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(&center, 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];