Mercurial > sdl-ios-xcode
comparison src/video/SDL_video.c @ 5251:58265e606e4e
Window coordinates are in the global space and windows are not tied to a particular display.
Also added Ctrl-Enter keybinding to the test code to toggle fullscreen mode for testing.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Thu, 10 Feb 2011 14:44:25 -0800 |
parents | 762e40fb8e28 |
children | 7a963be087ef |
comparison
equal
deleted
inserted
replaced
5250:329d435f97f4 | 5251:58265e606e4e |
---|---|
653 sizeof(SDL_DisplayMode), cmpmodes); | 653 sizeof(SDL_DisplayMode), cmpmodes); |
654 | 654 |
655 return SDL_TRUE; | 655 return SDL_TRUE; |
656 } | 656 } |
657 | 657 |
658 SDL_VideoDisplay * | |
659 SDL_GetFirstDisplay(void) | |
660 { | |
661 return &_this->displays[0]; | |
662 } | |
663 | |
658 static int | 664 static int |
659 SDL_GetNumDisplayModesForDisplay(SDL_VideoDisplay * display) | 665 SDL_GetNumDisplayModesForDisplay(SDL_VideoDisplay * display) |
660 { | 666 { |
661 if (!display->num_display_modes && _this->GetDisplayModes) { | 667 if (!display->num_display_modes && _this->GetDisplayModes) { |
662 _this->GetDisplayModes(_this, display); | 668 _this->GetDisplayModes(_this, display); |
891 display->current_mode = display_mode; | 897 display->current_mode = display_mode; |
892 return 0; | 898 return 0; |
893 } | 899 } |
894 | 900 |
895 int | 901 int |
902 SDLCALL SDL_GetWindowDisplay(SDL_Window * window) | |
903 { | |
904 int displayIndex; | |
905 int i, dist; | |
906 int closest = -1; | |
907 int closest_dist = 0x7FFFFFFF; | |
908 SDL_Point center; | |
909 SDL_Point delta; | |
910 SDL_Rect rect; | |
911 | |
912 CHECK_WINDOW_MAGIC(window, -1); | |
913 | |
914 if (SDL_WINDOWPOS_ISUNDEFINED(window->x) || | |
915 SDL_WINDOWPOS_ISCENTERED(window->x)) { | |
916 displayIndex = (window->x & 0xFFFF); | |
917 if (displayIndex >= _this->num_displays) { | |
918 displayIndex = 0; | |
919 } | |
920 return displayIndex; | |
921 } | |
922 if (SDL_WINDOWPOS_ISUNDEFINED(window->y) || | |
923 SDL_WINDOWPOS_ISCENTERED(window->y)) { | |
924 displayIndex = (window->y & 0xFFFF); | |
925 if (displayIndex >= _this->num_displays) { | |
926 displayIndex = 0; | |
927 } | |
928 return displayIndex; | |
929 } | |
930 | |
931 /* Find the display containing the window */ | |
932 center.x = window->x + window->w / 2; | |
933 center.y = window->y + window->h / 2; | |
934 for (i = 0; i < _this->num_displays; ++i) { | |
935 SDL_VideoDisplay *display = &_this->displays[i]; | |
936 | |
937 SDL_GetDisplayBounds(i, &rect); | |
938 if (display->fullscreen_window == window || SDL_EnclosePoints(¢er, 1, &rect, NULL)) { | |
939 return i; | |
940 } | |
941 | |
942 delta.x = center.x - (rect.x + rect.w / 2); | |
943 delta.y = center.y - (rect.y + rect.h / 2); | |
944 dist = (delta.x*delta.x + delta.y*delta.y); | |
945 if (dist < closest_dist) { | |
946 closest = i; | |
947 closest_dist = dist; | |
948 } | |
949 } | |
950 if (closest < 0) { | |
951 SDL_SetError("Couldn't find any displays"); | |
952 } | |
953 return closest; | |
954 } | |
955 | |
956 SDL_VideoDisplay * | |
957 SDL_GetDisplayForWindow(SDL_Window *window) | |
958 { | |
959 return &_this->displays[SDL_GetWindowDisplay(window)]; | |
960 } | |
961 | |
962 int | |
896 SDL_SetWindowDisplayMode(SDL_Window * window, const SDL_DisplayMode * mode) | 963 SDL_SetWindowDisplayMode(SDL_Window * window, const SDL_DisplayMode * mode) |
897 { | 964 { |
898 CHECK_WINDOW_MAGIC(window, -1); | 965 CHECK_WINDOW_MAGIC(window, -1); |
899 | 966 |
900 if (mode) { | 967 if (mode) { |
918 } | 985 } |
919 if (!fullscreen_mode.h) { | 986 if (!fullscreen_mode.h) { |
920 fullscreen_mode.h = window->h; | 987 fullscreen_mode.h = window->h; |
921 } | 988 } |
922 | 989 |
923 if (!SDL_GetClosestDisplayModeForDisplay(window->display, | 990 if (!SDL_GetClosestDisplayModeForDisplay(SDL_GetDisplayForWindow(window), |
924 &fullscreen_mode, | 991 &fullscreen_mode, |
925 &fullscreen_mode)) { | 992 &fullscreen_mode)) { |
926 SDL_SetError("Couldn't find display mode match"); | 993 SDL_SetError("Couldn't find display mode match"); |
927 return -1; | 994 return -1; |
928 } | 995 } |
934 } | 1001 } |
935 | 1002 |
936 Uint32 | 1003 Uint32 |
937 SDL_GetWindowPixelFormat(SDL_Window * window) | 1004 SDL_GetWindowPixelFormat(SDL_Window * window) |
938 { | 1005 { |
939 SDL_VideoDisplay *display = window->display; | 1006 SDL_VideoDisplay *display; |
940 SDL_DisplayMode *displayMode = &display->current_mode; | 1007 SDL_DisplayMode *displayMode; |
941 return displayMode->format; | 1008 |
1009 CHECK_WINDOW_MAGIC(window, SDL_PIXELFORMAT_UNKNOWN); | |
1010 | |
1011 display = SDL_GetDisplayForWindow(window); | |
1012 return display->current_mode.format; | |
942 } | 1013 } |
943 | 1014 |
944 static void | 1015 static void |
945 SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool attempt) | 1016 SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool attempt) |
946 { | 1017 { |
947 SDL_VideoDisplay *display = window->display; | 1018 SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); |
948 | 1019 |
949 /* See if we're already processing a window */ | 1020 /* See if we're already processing a window */ |
950 if (display->updating_fullscreen) { | 1021 if (display->updating_fullscreen) { |
951 return; | 1022 return; |
952 } | 1023 } |
969 } | 1040 } |
970 } | 1041 } |
971 | 1042 |
972 if (FULLSCREEN_VISIBLE(window)) { | 1043 if (FULLSCREEN_VISIBLE(window)) { |
973 /* Hide any other fullscreen windows */ | 1044 /* Hide any other fullscreen windows */ |
974 SDL_Window *other; | 1045 if (display->fullscreen_window != window) { |
975 for (other = display->windows; other; other = other->next) { | 1046 SDL_MinimizeWindow(display->fullscreen_window); |
976 if (other != window && FULLSCREEN_VISIBLE(other)) { | |
977 SDL_MinimizeWindow(other); | |
978 } | |
979 } | 1047 } |
980 } | 1048 } |
981 | 1049 |
982 display->updating_fullscreen = SDL_FALSE; | 1050 display->updating_fullscreen = SDL_FALSE; |
983 | 1051 |
984 /* See if there are any fullscreen windows */ | 1052 /* See if there are any fullscreen windows */ |
985 for (window = display->windows; window; window = window->next) { | 1053 for (window = _this->windows; window; window = window->next) { |
986 if (FULLSCREEN_VISIBLE(window)) { | 1054 if (FULLSCREEN_VISIBLE(window) && |
1055 SDL_GetDisplayForWindow(window) == display) { | |
987 SDL_DisplayMode fullscreen_mode; | 1056 SDL_DisplayMode fullscreen_mode; |
988 if (SDL_GetWindowDisplayMode(window, &fullscreen_mode) == 0) { | 1057 if (SDL_GetWindowDisplayMode(window, &fullscreen_mode) == 0) { |
989 SDL_SetDisplayModeForDisplay(display, &fullscreen_mode); | 1058 SDL_SetDisplayModeForDisplay(display, &fullscreen_mode); |
990 display->fullscreen_window = window; | 1059 display->fullscreen_window = window; |
991 return; | 1060 return; |
1020 SDL_SetError("No OpenGL support in video driver"); | 1089 SDL_SetError("No OpenGL support in video driver"); |
1021 return NULL; | 1090 return NULL; |
1022 } | 1091 } |
1023 SDL_GL_LoadLibrary(NULL); | 1092 SDL_GL_LoadLibrary(NULL); |
1024 } | 1093 } |
1025 display = &_this->displays[0]; /* FIXME */ | |
1026 window = (SDL_Window *)SDL_calloc(1, sizeof(*window)); | 1094 window = (SDL_Window *)SDL_calloc(1, sizeof(*window)); |
1027 window->magic = &_this->window_magic; | 1095 window->magic = &_this->window_magic; |
1028 window->id = _this->next_object_id++; | 1096 window->id = _this->next_object_id++; |
1029 window->x = x; | 1097 window->x = x; |
1030 window->y = y; | 1098 window->y = y; |
1031 window->w = w; | 1099 window->w = w; |
1032 window->h = h; | 1100 window->h = h; |
1033 window->flags = (flags & allowed_flags); | 1101 window->flags = (flags & allowed_flags); |
1034 window->display = display; | 1102 window->next = _this->windows; |
1035 window->next = display->windows; | 1103 if (_this->windows) { |
1036 if (display->windows) { | 1104 _this->windows->prev = window; |
1037 display->windows->prev = window; | 1105 } |
1038 } | 1106 _this->windows = window; |
1039 display->windows = window; | |
1040 | 1107 |
1041 if (_this->CreateWindow && _this->CreateWindow(_this, window) < 0) { | 1108 if (_this->CreateWindow && _this->CreateWindow(_this, window) < 0) { |
1042 SDL_DestroyWindow(window); | 1109 SDL_DestroyWindow(window); |
1043 return NULL; | 1110 return NULL; |
1044 } | 1111 } |
1061 } | 1128 } |
1062 | 1129 |
1063 SDL_Window * | 1130 SDL_Window * |
1064 SDL_CreateWindowFrom(const void *data) | 1131 SDL_CreateWindowFrom(const void *data) |
1065 { | 1132 { |
1066 SDL_VideoDisplay *display; | |
1067 SDL_Window *window; | 1133 SDL_Window *window; |
1068 | 1134 |
1069 if (!_this) { | 1135 if (!_this) { |
1070 SDL_UninitializedVideo(); | 1136 SDL_UninitializedVideo(); |
1071 return NULL; | 1137 return NULL; |
1072 } | 1138 } |
1073 display = &_this->displays[0]; /* FIXME */ | |
1074 window = (SDL_Window *)SDL_calloc(1, sizeof(*window)); | 1139 window = (SDL_Window *)SDL_calloc(1, sizeof(*window)); |
1075 window->magic = &_this->window_magic; | 1140 window->magic = &_this->window_magic; |
1076 window->id = _this->next_object_id++; | 1141 window->id = _this->next_object_id++; |
1077 window->flags = SDL_WINDOW_FOREIGN; | 1142 window->flags = SDL_WINDOW_FOREIGN; |
1078 window->display = display; | 1143 window->next = _this->windows; |
1079 window->next = display->windows; | 1144 if (_this->windows) { |
1080 if (display->windows) { | 1145 _this->windows->prev = window; |
1081 display->windows->prev = window; | 1146 } |
1082 } | 1147 _this->windows = window; |
1083 display->windows = window; | |
1084 | 1148 |
1085 if (!_this->CreateWindowFrom || | 1149 if (!_this->CreateWindowFrom || |
1086 _this->CreateWindowFrom(_this, window, data) < 0) { | 1150 _this->CreateWindowFrom(_this, window, data) < 0) { |
1087 SDL_DestroyWindow(window); | 1151 SDL_DestroyWindow(window); |
1088 return NULL; | 1152 return NULL; |
1169 int i; | 1233 int i; |
1170 | 1234 |
1171 if (!_this) { | 1235 if (!_this) { |
1172 return NULL; | 1236 return NULL; |
1173 } | 1237 } |
1174 /* FIXME: Should we keep a separate hash table for these? */ | 1238 for (window = _this->windows; window; window = window->next) { |
1175 for (i = _this->num_displays; i--;) { | 1239 if (window->id == id) { |
1176 SDL_VideoDisplay *display = &_this->displays[i]; | 1240 return window; |
1177 for (window = display->windows; window; window = window->next) { | |
1178 if (window->id == id) { | |
1179 return window; | |
1180 } | |
1181 } | 1241 } |
1182 } | 1242 } |
1183 return NULL; | 1243 return NULL; |
1184 } | 1244 } |
1185 | 1245 |
1296 window->x = x; | 1356 window->x = x; |
1297 } | 1357 } |
1298 if (y != SDL_WINDOWPOS_UNDEFINED) { | 1358 if (y != SDL_WINDOWPOS_UNDEFINED) { |
1299 window->y = y; | 1359 window->y = y; |
1300 } | 1360 } |
1301 if (_this->SetWindowPosition) { | 1361 if (!(window->flags & SDL_WINDOW_FULLSCREEN)) { |
1302 _this->SetWindowPosition(_this, window); | 1362 if (_this->SetWindowPosition) { |
1303 } | 1363 _this->SetWindowPosition(_this, window); |
1304 SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MOVED, x, y); | 1364 } |
1365 SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MOVED, x, y); | |
1366 } | |
1305 } | 1367 } |
1306 | 1368 |
1307 void | 1369 void |
1308 SDL_GetWindowPosition(SDL_Window * window, int *x, int *y) | 1370 SDL_GetWindowPosition(SDL_Window * window, int *x, int *y) |
1309 { | 1371 { |
1310 if (_this && window && window->magic == &_this->window_magic) { | 1372 /* Clear the values */ |
1373 if (x) { | |
1374 *x = 0; | |
1375 } | |
1376 if (y) { | |
1377 *y = 0; | |
1378 } | |
1379 | |
1380 CHECK_WINDOW_MAGIC(window, ); | |
1381 | |
1382 /* Fullscreen windows are always at their display's origin */ | |
1383 if (window->flags & SDL_WINDOW_FULLSCREEN) { | |
1384 } else { | |
1311 if (x) { | 1385 if (x) { |
1312 *x = window->x; | 1386 *x = window->x; |
1313 } | 1387 } |
1314 if (y) { | 1388 if (y) { |
1315 *y = window->y; | 1389 *y = window->y; |
1316 } | 1390 } |
1317 } else { | |
1318 if (x) { | |
1319 *x = 0; | |
1320 } | |
1321 if (y) { | |
1322 *y = 0; | |
1323 } | |
1324 } | 1391 } |
1325 } | 1392 } |
1326 | 1393 |
1327 void | 1394 void |
1328 SDL_SetWindowSize(SDL_Window * window, int w, int h) | 1395 SDL_SetWindowSize(SDL_Window * window, int w, int h) |
1339 } | 1406 } |
1340 | 1407 |
1341 void | 1408 void |
1342 SDL_GetWindowSize(SDL_Window * window, int *w, int *h) | 1409 SDL_GetWindowSize(SDL_Window * window, int *w, int *h) |
1343 { | 1410 { |
1411 int dummy; | |
1412 | |
1413 if (!w) { | |
1414 w = &dummy; | |
1415 } | |
1416 if (!h) { | |
1417 h = &dummy; | |
1418 } | |
1419 | |
1420 *w = 0; | |
1421 *h = 0; | |
1422 | |
1423 CHECK_WINDOW_MAGIC(window, ); | |
1424 | |
1344 if (_this && window && window->magic == &_this->window_magic) { | 1425 if (_this && window && window->magic == &_this->window_magic) { |
1345 if (w) { | 1426 if (w) { |
1346 *w = window->w; | 1427 *w = window->w; |
1347 } | 1428 } |
1348 if (h) { | 1429 if (h) { |
1448 } | 1529 } |
1449 SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESTORED, 0, 0); | 1530 SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESTORED, 0, 0); |
1450 } | 1531 } |
1451 | 1532 |
1452 int | 1533 int |
1453 SDL_SetWindowFullscreen(SDL_Window * window, int fullscreen) | 1534 SDL_SetWindowFullscreen(SDL_Window * window, SDL_bool fullscreen) |
1454 { | 1535 { |
1455 CHECK_WINDOW_MAGIC(window, -1); | 1536 CHECK_WINDOW_MAGIC(window, -1); |
1456 | 1537 |
1457 if (fullscreen) { | 1538 if (fullscreen) { |
1458 fullscreen = SDL_WINDOW_FULLSCREEN; | 1539 fullscreen = SDL_WINDOW_FULLSCREEN; |
1608 } | 1689 } |
1609 | 1690 |
1610 void | 1691 void |
1611 SDL_OnWindowFocusGained(SDL_Window * window) | 1692 SDL_OnWindowFocusGained(SDL_Window * window) |
1612 { | 1693 { |
1613 SDL_VideoDisplay *display = window->display; | |
1614 | |
1615 if ((window->flags & (SDL_WINDOW_INPUT_GRABBED | SDL_WINDOW_FULLSCREEN)) | 1694 if ((window->flags & (SDL_WINDOW_INPUT_GRABBED | SDL_WINDOW_FULLSCREEN)) |
1616 && _this->SetWindowGrab) { | 1695 && _this->SetWindowGrab) { |
1617 _this->SetWindowGrab(_this, window); | 1696 _this->SetWindowGrab(_this, window); |
1618 } | 1697 } |
1619 } | 1698 } |
1620 | 1699 |
1621 void | 1700 void |
1622 SDL_OnWindowFocusLost(SDL_Window * window) | 1701 SDL_OnWindowFocusLost(SDL_Window * window) |
1623 { | 1702 { |
1624 SDL_VideoDisplay *display = window->display; | |
1625 | |
1626 /* If we're fullscreen on a single-head system and lose focus, minimize */ | 1703 /* If we're fullscreen on a single-head system and lose focus, minimize */ |
1627 if ((window->flags & SDL_WINDOW_FULLSCREEN) && | 1704 if ((window->flags & SDL_WINDOW_FULLSCREEN) && |
1628 _this->num_displays == 1) { | 1705 _this->num_displays == 1) { |
1629 SDL_MinimizeWindow(window); | 1706 SDL_MinimizeWindow(window); |
1630 } | 1707 } |
1636 } | 1713 } |
1637 | 1714 |
1638 SDL_Window * | 1715 SDL_Window * |
1639 SDL_GetFocusWindow(void) | 1716 SDL_GetFocusWindow(void) |
1640 { | 1717 { |
1641 SDL_VideoDisplay *display; | |
1642 SDL_Window *window; | 1718 SDL_Window *window; |
1643 | 1719 |
1644 if (!_this) { | 1720 if (!_this) { |
1645 return NULL; | 1721 return NULL; |
1646 } | 1722 } |
1647 display = &_this->displays[0]; /* FIXME */ | 1723 for (window = _this->windows; window; window = window->next) { |
1648 for (window = display->windows; window; window = window->next) { | |
1649 if (window->flags & SDL_WINDOW_INPUT_FOCUS) { | 1724 if (window->flags & SDL_WINDOW_INPUT_FOCUS) { |
1650 return window; | 1725 return window; |
1651 } | 1726 } |
1652 } | 1727 } |
1653 return NULL; | 1728 return NULL; |
1675 } | 1750 } |
1676 if (window->flags & SDL_WINDOW_OPENGL) { | 1751 if (window->flags & SDL_WINDOW_OPENGL) { |
1677 SDL_GL_UnloadLibrary(); | 1752 SDL_GL_UnloadLibrary(); |
1678 } | 1753 } |
1679 | 1754 |
1755 display = SDL_GetDisplayForWindow(window); | |
1756 if (display->fullscreen_window == window) { | |
1757 display->fullscreen_window = NULL; | |
1758 } | |
1759 | |
1680 /* Now invalidate magic */ | 1760 /* Now invalidate magic */ |
1681 window->magic = NULL; | 1761 window->magic = NULL; |
1682 | 1762 |
1683 /* Free memory associated with the window */ | 1763 /* Free memory associated with the window */ |
1684 if (window->title) { | 1764 if (window->title) { |
1691 SDL_free(data->name); | 1771 SDL_free(data->name); |
1692 SDL_free(data); | 1772 SDL_free(data); |
1693 } | 1773 } |
1694 | 1774 |
1695 /* Unlink the window from the list */ | 1775 /* Unlink the window from the list */ |
1696 display = window->display; | |
1697 if (window->next) { | 1776 if (window->next) { |
1698 window->next->prev = window->prev; | 1777 window->next->prev = window->prev; |
1699 } | 1778 } |
1700 if (window->prev) { | 1779 if (window->prev) { |
1701 window->prev->next = window->next; | 1780 window->prev->next = window->next; |
1702 } else { | 1781 } else { |
1703 display->windows = window->next; | 1782 _this->windows = window->next; |
1704 } | 1783 } |
1705 | 1784 |
1706 SDL_free(window); | 1785 SDL_free(window); |
1707 } | 1786 } |
1708 | 1787 |
1761 SDL_StopEventLoop(); | 1840 SDL_StopEventLoop(); |
1762 | 1841 |
1763 SDL_EnableScreenSaver(); | 1842 SDL_EnableScreenSaver(); |
1764 | 1843 |
1765 /* Clean up the system video */ | 1844 /* Clean up the system video */ |
1766 for (i = _this->num_displays; i--;) { | 1845 while (_this->windows) { |
1767 SDL_VideoDisplay *display = &_this->displays[i]; | 1846 SDL_DestroyWindow(_this->windows); |
1768 while (display->windows) { | |
1769 SDL_DestroyWindow(display->windows); | |
1770 } | |
1771 } | 1847 } |
1772 _this->VideoQuit(_this); | 1848 _this->VideoQuit(_this); |
1773 | 1849 |
1774 for (i = _this->num_displays; i--;) { | 1850 for (i = _this->num_displays; i--;) { |
1775 SDL_VideoDisplay *display = &_this->displays[i]; | 1851 SDL_VideoDisplay *display = &_this->displays[i]; |