wl_monitor.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. //========================================================================
  2. // GLFW 3.4 Wayland - www.glfw.org
  3. //------------------------------------------------------------------------
  4. // Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
  5. //
  6. // This software is provided 'as-is', without any express or implied
  7. // warranty. In no event will the authors be held liable for any damages
  8. // arising from the use of this software.
  9. //
  10. // Permission is granted to anyone to use this software for any purpose,
  11. // including commercial applications, and to alter it and redistribute it
  12. // freely, subject to the following restrictions:
  13. //
  14. // 1. The origin of this software must not be misrepresented; you must not
  15. // claim that you wrote the original software. If you use this software
  16. // in a product, an acknowledgment in the product documentation would
  17. // be appreciated but is not required.
  18. //
  19. // 2. Altered source versions must be plainly marked as such, and must not
  20. // be misrepresented as being the original software.
  21. //
  22. // 3. This notice may not be removed or altered from any source
  23. // distribution.
  24. //
  25. //========================================================================
  26. // It is fine to use C99 in this file because it will not be built with VS
  27. //========================================================================
  28. #include "internal.h"
  29. #include <stdio.h>
  30. #include <stdlib.h>
  31. #include <string.h>
  32. #include <math.h>
  33. static void outputHandleGeometry(void* data,
  34. struct wl_output* output UNUSED,
  35. int32_t x,
  36. int32_t y,
  37. int32_t physicalWidth,
  38. int32_t physicalHeight,
  39. int32_t subpixel UNUSED,
  40. const char* make,
  41. const char* model,
  42. int32_t transform UNUSED)
  43. {
  44. struct _GLFWmonitor *monitor = data;
  45. char name[1024];
  46. monitor->wl.x = x;
  47. monitor->wl.y = y;
  48. monitor->widthMM = physicalWidth;
  49. monitor->heightMM = physicalHeight;
  50. snprintf(name, sizeof(name), "%s %s", make, model);
  51. monitor->name = _glfw_strdup(name);
  52. }
  53. static void outputHandleMode(void* data,
  54. struct wl_output* output UNUSED,
  55. uint32_t flags,
  56. int32_t width,
  57. int32_t height,
  58. int32_t refresh)
  59. {
  60. struct _GLFWmonitor *monitor = data;
  61. GLFWvidmode mode;
  62. mode.width = width;
  63. mode.height = height;
  64. mode.redBits = 8;
  65. mode.greenBits = 8;
  66. mode.blueBits = 8;
  67. mode.refreshRate = (int) round(refresh / 1000.0);
  68. monitor->modeCount++;
  69. monitor->modes =
  70. realloc(monitor->modes, monitor->modeCount * sizeof(GLFWvidmode));
  71. monitor->modes[monitor->modeCount - 1] = mode;
  72. if (flags & WL_OUTPUT_MODE_CURRENT)
  73. monitor->wl.currentMode = monitor->modeCount - 1;
  74. }
  75. static void outputHandleDone(void* data, struct wl_output* output UNUSED)
  76. {
  77. struct _GLFWmonitor *monitor = data;
  78. for (int i = 0; i < _glfw.monitorCount; i++) {
  79. if (_glfw.monitors[i] == monitor) return;
  80. }
  81. _glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST);
  82. }
  83. static void outputHandleScale(void* data,
  84. struct wl_output* output UNUSED,
  85. int32_t factor)
  86. {
  87. struct _GLFWmonitor *monitor = data;
  88. if (factor > 0 && factor < 24)
  89. monitor->wl.scale = factor;
  90. }
  91. static void outputHandleName(void* data,
  92. struct wl_output* output UNUSED,
  93. const char* name) {
  94. struct _GLFWmonitor *monitor = data;
  95. if (name) strncpy(monitor->wl.friendly_name, name, sizeof(monitor->wl.friendly_name)-1);
  96. }
  97. static void outputHandleDescription(void* data,
  98. struct wl_output* output UNUSED,
  99. const char* description) {
  100. struct _GLFWmonitor *monitor = data;
  101. if (description) strncpy(monitor->wl.description, description, sizeof(monitor->wl.description)-1);
  102. }
  103. static const struct wl_output_listener outputListener = {
  104. outputHandleGeometry,
  105. outputHandleMode,
  106. outputHandleDone,
  107. outputHandleScale,
  108. outputHandleName,
  109. outputHandleDescription,
  110. };
  111. //////////////////////////////////////////////////////////////////////////
  112. ////// GLFW internal API //////
  113. //////////////////////////////////////////////////////////////////////////
  114. void _glfwAddOutputWayland(uint32_t name, uint32_t version)
  115. {
  116. _GLFWmonitor *monitor;
  117. struct wl_output *output;
  118. if (version < 2)
  119. {
  120. _glfwInputError(GLFW_PLATFORM_ERROR,
  121. "Wayland: Unsupported output interface version");
  122. return;
  123. }
  124. // The actual name of this output will be set in the geometry handler.
  125. monitor = _glfwAllocMonitor(NULL, 0, 0);
  126. output = wl_registry_bind(_glfw.wl.registry,
  127. name,
  128. &wl_output_interface,
  129. MIN(version, (unsigned)WL_OUTPUT_NAME_SINCE_VERSION));
  130. if (!output)
  131. {
  132. _glfwFreeMonitor(monitor);
  133. return;
  134. }
  135. monitor->wl.scale = 1;
  136. monitor->wl.output = output;
  137. monitor->wl.name = name;
  138. wl_output_add_listener(output, &outputListener, monitor);
  139. }
  140. //////////////////////////////////////////////////////////////////////////
  141. ////// GLFW platform API //////
  142. //////////////////////////////////////////////////////////////////////////
  143. void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor)
  144. {
  145. if (monitor->wl.output)
  146. wl_output_destroy(monitor->wl.output);
  147. }
  148. void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
  149. {
  150. if (xpos)
  151. *xpos = monitor->wl.x;
  152. if (ypos)
  153. *ypos = monitor->wl.y;
  154. }
  155. void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
  156. float* xscale, float* yscale)
  157. {
  158. if (xscale)
  159. *xscale = (float) monitor->wl.scale;
  160. if (yscale)
  161. *yscale = (float) monitor->wl.scale;
  162. }
  163. void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor,
  164. int* xpos, int* ypos,
  165. int* width, int* height)
  166. {
  167. if (xpos)
  168. *xpos = monitor->wl.x;
  169. if (ypos)
  170. *ypos = monitor->wl.y;
  171. if (width)
  172. *width = monitor->modes[monitor->wl.currentMode].width;
  173. if (height)
  174. *height = monitor->modes[monitor->wl.currentMode].height;
  175. }
  176. GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found)
  177. {
  178. *found = monitor->modeCount;
  179. return monitor->modes;
  180. }
  181. bool _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
  182. {
  183. if (monitor->modeCount > monitor->wl.currentMode) {
  184. *mode = monitor->modes[monitor->wl.currentMode];
  185. return true;
  186. }
  187. return false;
  188. }
  189. bool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor UNUSED, GLFWgammaramp* ramp UNUSED)
  190. {
  191. _glfwInputError(GLFW_FEATURE_UNAVAILABLE,
  192. "Wayland: Gamma ramp access is not available");
  193. return false;
  194. }
  195. void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor UNUSED,
  196. const GLFWgammaramp* ramp UNUSED)
  197. {
  198. _glfwInputError(GLFW_FEATURE_UNAVAILABLE,
  199. "Wayland: Gamma ramp access is not available");
  200. }
  201. //////////////////////////////////////////////////////////////////////////
  202. ////// GLFW native API //////
  203. //////////////////////////////////////////////////////////////////////////
  204. GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* handle)
  205. {
  206. _GLFWmonitor* monitor = (_GLFWmonitor*) handle;
  207. _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
  208. return monitor->wl.output;
  209. }