testwm2.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. /*
  2. Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
  3. This software is provided 'as-is', without any express or implied
  4. warranty. In no event will the authors be held liable for any damages
  5. arising from the use of this software.
  6. Permission is granted to anyone to use this software for any purpose,
  7. including commercial applications, and to alter it and redistribute it
  8. freely.
  9. */
  10. #include <stdlib.h>
  11. #ifdef __EMSCRIPTEN__
  12. #include <emscripten/emscripten.h>
  13. #endif
  14. #include <SDL3/SDL_test_common.h>
  15. #include <SDL3/SDL_test_font.h>
  16. static SDLTest_CommonState *state;
  17. int done;
  18. static const char *cursorNames[] = {
  19. "arrow",
  20. "ibeam",
  21. "wait",
  22. "crosshair",
  23. "waitarrow",
  24. "sizeNWSE",
  25. "sizeNESW",
  26. "sizeWE",
  27. "sizeNS",
  28. "sizeALL",
  29. "NO",
  30. "hand",
  31. };
  32. int system_cursor = -1;
  33. SDL_Cursor *cursor = NULL;
  34. SDL_bool relative_mode = SDL_FALSE;
  35. int highlighted_mode = -1;
  36. /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
  37. static void
  38. quit(int rc)
  39. {
  40. SDLTest_CommonQuit(state);
  41. exit(rc);
  42. }
  43. /* Draws the modes menu, and stores the mode index under the mouse in highlighted_mode */
  44. static void
  45. draw_modes_menu(SDL_Window *window, SDL_Renderer *renderer, SDL_Rect viewport)
  46. {
  47. SDL_DisplayMode mode;
  48. char text[1024];
  49. const int lineHeight = 10;
  50. const int display_index = SDL_GetWindowDisplayIndex(window);
  51. const int num_modes = SDL_GetNumDisplayModes(display_index);
  52. int i;
  53. int column_chars = 0;
  54. int text_length;
  55. int x, y;
  56. int table_top;
  57. SDL_Point mouse_pos = { -1, -1 };
  58. /* Get mouse position */
  59. if (SDL_GetMouseFocus() == window) {
  60. int window_x, window_y;
  61. float logical_x, logical_y;
  62. SDL_GetMouseState(&window_x, &window_y);
  63. SDL_RenderWindowToLogical(renderer, window_x, window_y, &logical_x, &logical_y);
  64. mouse_pos.x = (int)logical_x;
  65. mouse_pos.y = (int)logical_y;
  66. }
  67. x = 0;
  68. y = viewport.y;
  69. y += lineHeight;
  70. SDL_snprintf(text, sizeof(text), "Click on a mode to set it with SDL_SetWindowDisplayMode");
  71. SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
  72. SDLTest_DrawString(renderer, x, y, text);
  73. y += lineHeight;
  74. SDL_snprintf(text, sizeof(text), "Press Ctrl+Enter to toggle SDL_WINDOW_FULLSCREEN");
  75. SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
  76. SDLTest_DrawString(renderer, x, y, text);
  77. y += lineHeight;
  78. table_top = y;
  79. /* Clear the cached mode under the mouse */
  80. if (window == SDL_GetMouseFocus()) {
  81. highlighted_mode = -1;
  82. }
  83. for (i = 0; i < num_modes; ++i) {
  84. SDL_Rect cell_rect;
  85. if (0 != SDL_GetDisplayMode(display_index, i, &mode)) {
  86. return;
  87. }
  88. SDL_snprintf(text, sizeof(text), "%d: %dx%d@%dHz",
  89. i, mode.w, mode.h, mode.refresh_rate);
  90. /* Update column width */
  91. text_length = (int)SDL_strlen(text);
  92. column_chars = SDL_max(column_chars, text_length);
  93. /* Check if under mouse */
  94. cell_rect.x = x;
  95. cell_rect.y = y;
  96. cell_rect.w = text_length * FONT_CHARACTER_SIZE;
  97. cell_rect.h = lineHeight;
  98. if (SDL_PointInRect(&mouse_pos, &cell_rect)) {
  99. SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
  100. /* Update cached mode under the mouse */
  101. if (window == SDL_GetMouseFocus()) {
  102. highlighted_mode = i;
  103. }
  104. } else {
  105. SDL_SetRenderDrawColor(renderer, 170, 170, 170, 255);
  106. }
  107. SDLTest_DrawString(renderer, x, y, text);
  108. y += lineHeight;
  109. if (y + lineHeight > (viewport.y + viewport.h)) {
  110. /* Advance to next column */
  111. x += (column_chars + 1) * FONT_CHARACTER_SIZE;
  112. y = table_top;
  113. column_chars = 0;
  114. }
  115. }
  116. }
  117. void
  118. loop()
  119. {
  120. int i;
  121. SDL_Event event;
  122. /* Check for events */
  123. while (SDL_PollEvent(&event)) {
  124. SDLTest_CommonEvent(state, &event, &done);
  125. if (event.type == SDL_WINDOWEVENT) {
  126. if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
  127. SDL_Window *window = SDL_GetWindowFromID(event.window.windowID);
  128. if (window) {
  129. SDL_Log("Window %" SDL_PRIu32 " resized to %" SDL_PRIs32 "x%" SDL_PRIs32 "\n",
  130. event.window.windowID,
  131. event.window.data1,
  132. event.window.data2);
  133. }
  134. }
  135. if (event.window.event == SDL_WINDOWEVENT_MOVED) {
  136. SDL_Window *window = SDL_GetWindowFromID(event.window.windowID);
  137. if (window) {
  138. SDL_Log("Window %" SDL_PRIu32 " moved to %" SDL_PRIs32 ",%" SDL_PRIs32 " (display %s)\n",
  139. event.window.windowID,
  140. event.window.data1,
  141. event.window.data2,
  142. SDL_GetDisplayName(SDL_GetWindowDisplayIndex(window)));
  143. }
  144. }
  145. if (event.window.event == SDL_WINDOWEVENT_FOCUS_LOST) {
  146. relative_mode = SDL_GetRelativeMouseMode();
  147. if (relative_mode) {
  148. SDL_SetRelativeMouseMode(SDL_FALSE);
  149. }
  150. }
  151. if (event.window.event == SDL_WINDOWEVENT_FOCUS_GAINED) {
  152. if (relative_mode) {
  153. SDL_SetRelativeMouseMode(SDL_TRUE);
  154. }
  155. }
  156. }
  157. if (event.type == SDL_KEYUP) {
  158. SDL_bool updateCursor = SDL_FALSE;
  159. if (event.key.keysym.sym == SDLK_LEFT) {
  160. --system_cursor;
  161. if (system_cursor < 0) {
  162. system_cursor = SDL_NUM_SYSTEM_CURSORS - 1;
  163. }
  164. updateCursor = SDL_TRUE;
  165. } else if (event.key.keysym.sym == SDLK_RIGHT) {
  166. ++system_cursor;
  167. if (system_cursor >= SDL_NUM_SYSTEM_CURSORS) {
  168. system_cursor = 0;
  169. }
  170. updateCursor = SDL_TRUE;
  171. }
  172. if (updateCursor) {
  173. SDL_Log("Changing cursor to \"%s\"", cursorNames[system_cursor]);
  174. SDL_FreeCursor(cursor);
  175. cursor = SDL_CreateSystemCursor((SDL_SystemCursor)system_cursor);
  176. SDL_SetCursor(cursor);
  177. }
  178. }
  179. if (event.type == SDL_MOUSEBUTTONUP) {
  180. SDL_Window* window = SDL_GetMouseFocus();
  181. if (highlighted_mode != -1 && window != NULL) {
  182. const int display_index = SDL_GetWindowDisplayIndex(window);
  183. SDL_DisplayMode mode;
  184. if (0 != SDL_GetDisplayMode(display_index, highlighted_mode, &mode)) {
  185. SDL_Log("Couldn't get display mode");
  186. } else {
  187. SDL_SetWindowDisplayMode(window, &mode);
  188. }
  189. }
  190. }
  191. }
  192. for (i = 0; i < state->num_windows; ++i) {
  193. SDL_Window* window = state->windows[i];
  194. SDL_Renderer *renderer = state->renderers[i];
  195. if (window != NULL && renderer != NULL) {
  196. int y = 0;
  197. SDL_Rect viewport, menurect;
  198. SDL_RenderGetViewport(renderer, &viewport);
  199. SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
  200. SDL_RenderClear(renderer);
  201. SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
  202. SDLTest_CommonDrawWindowInfo(renderer, state->windows[i], &y);
  203. menurect.x = 0;
  204. menurect.y = y;
  205. menurect.w = viewport.w;
  206. menurect.h = viewport.h - y;
  207. draw_modes_menu(window, renderer, menurect);
  208. SDL_RenderPresent(renderer);
  209. }
  210. }
  211. #ifdef __EMSCRIPTEN__
  212. if (done) {
  213. emscripten_cancel_main_loop();
  214. }
  215. #endif
  216. }
  217. int
  218. main(int argc, char *argv[])
  219. {
  220. int i;
  221. /* Enable standard application logging */
  222. SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
  223. SDL_assert(SDL_arraysize(cursorNames) == SDL_NUM_SYSTEM_CURSORS);
  224. /* Initialize test framework */
  225. state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO);
  226. if (state == NULL) {
  227. return 1;
  228. }
  229. if (!SDLTest_CommonDefaultArgs(state, argc, argv) || !SDLTest_CommonInit(state)) {
  230. SDLTest_CommonQuit(state);
  231. return 1;
  232. }
  233. SDL_EventState(SDL_DROPFILE, SDL_ENABLE);
  234. SDL_EventState(SDL_DROPTEXT, SDL_ENABLE);
  235. for (i = 0; i < state->num_windows; ++i) {
  236. SDL_Renderer *renderer = state->renderers[i];
  237. SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF);
  238. SDL_RenderClear(renderer);
  239. }
  240. /* Main render loop */
  241. done = 0;
  242. #ifdef __EMSCRIPTEN__
  243. emscripten_set_main_loop(loop, 0, 1);
  244. #else
  245. while (!done) {
  246. loop();
  247. }
  248. #endif
  249. SDL_FreeCursor(cursor);
  250. quit(0);
  251. /* keep the compiler happy ... */
  252. return 0;
  253. }
  254. /* vi: set ts=4 sw=4 expandtab: */