wl_monitor.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. //========================================================================
  2. // GLFW 3.4 Wayland - www.glfw.org
  3. //------------------------------------------------------------------------
  4. // Copyright (c) 2014 Jonas Ådahl <[email protected]>
  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 <errno.h>
  33. #include <math.h>
  34. static void outputHandleGeometry(void* data,
  35. struct wl_output* output,
  36. int32_t x,
  37. int32_t y,
  38. int32_t physicalWidth,
  39. int32_t physicalHeight,
  40. int32_t subpixel,
  41. const char* make,
  42. const char* model,
  43. int32_t transform)
  44. {
  45. struct _GLFWmonitor *monitor = data;
  46. char name[1024];
  47. monitor->wl.x = x;
  48. monitor->wl.y = y;
  49. monitor->widthMM = physicalWidth;
  50. monitor->heightMM = physicalHeight;
  51. snprintf(name, sizeof(name), "%s %s", make, model);
  52. monitor->name = _glfw_strdup(name);
  53. }
  54. static void outputHandleMode(void* data,
  55. struct wl_output* output,
  56. uint32_t flags,
  57. int32_t width,
  58. int32_t height,
  59. int32_t refresh)
  60. {
  61. struct _GLFWmonitor *monitor = data;
  62. GLFWvidmode mode;
  63. mode.width = width;
  64. mode.height = height;
  65. mode.redBits = 8;
  66. mode.greenBits = 8;
  67. mode.blueBits = 8;
  68. mode.refreshRate = (int) round(refresh / 1000.0);
  69. monitor->modeCount++;
  70. monitor->modes =
  71. realloc(monitor->modes, monitor->modeCount * sizeof(GLFWvidmode));
  72. monitor->modes[monitor->modeCount - 1] = mode;
  73. if (flags & WL_OUTPUT_MODE_CURRENT)
  74. monitor->wl.currentMode = monitor->modeCount - 1;
  75. }
  76. static void outputHandleDone(void* data, struct wl_output* output)
  77. {
  78. struct _GLFWmonitor *monitor = data;
  79. _glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST);
  80. }
  81. static void outputHandleScale(void* data,
  82. struct wl_output* output,
  83. int32_t factor)
  84. {
  85. struct _GLFWmonitor *monitor = data;
  86. monitor->wl.scale = factor;
  87. }
  88. static const struct wl_output_listener outputListener = {
  89. outputHandleGeometry,
  90. outputHandleMode,
  91. outputHandleDone,
  92. outputHandleScale,
  93. };
  94. //////////////////////////////////////////////////////////////////////////
  95. ////// GLFW internal API //////
  96. //////////////////////////////////////////////////////////////////////////
  97. void _glfwAddOutputWayland(uint32_t name, uint32_t version)
  98. {
  99. _GLFWmonitor *monitor;
  100. struct wl_output *output;
  101. if (version < 2)
  102. {
  103. _glfwInputError(GLFW_PLATFORM_ERROR,
  104. "Wayland: Unsupported output interface version");
  105. return;
  106. }
  107. // The actual name of this output will be set in the geometry handler.
  108. monitor = _glfwAllocMonitor(NULL, 0, 0);
  109. output = wl_registry_bind(_glfw.wl.registry,
  110. name,
  111. &wl_output_interface,
  112. 2);
  113. if (!output)
  114. {
  115. _glfwFreeMonitor(monitor);
  116. return;
  117. }
  118. monitor->wl.scale = 1;
  119. monitor->wl.output = output;
  120. monitor->wl.name = name;
  121. wl_output_add_listener(output, &outputListener, monitor);
  122. }
  123. //////////////////////////////////////////////////////////////////////////
  124. ////// GLFW platform API //////
  125. //////////////////////////////////////////////////////////////////////////
  126. void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor)
  127. {
  128. if (monitor->wl.output)
  129. wl_output_destroy(monitor->wl.output);
  130. }
  131. void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
  132. {
  133. if (xpos)
  134. *xpos = monitor->wl.x;
  135. if (ypos)
  136. *ypos = monitor->wl.y;
  137. }
  138. void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
  139. float* xscale, float* yscale)
  140. {
  141. if (xscale)
  142. *xscale = (float) monitor->wl.scale;
  143. if (yscale)
  144. *yscale = (float) monitor->wl.scale;
  145. }
  146. void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor,
  147. int* xpos, int* ypos,
  148. int* width, int* height)
  149. {
  150. if (xpos)
  151. *xpos = monitor->wl.x;
  152. if (ypos)
  153. *ypos = monitor->wl.y;
  154. if (width)
  155. *width = monitor->modes[monitor->wl.currentMode].width;
  156. if (height)
  157. *height = monitor->modes[monitor->wl.currentMode].height;
  158. }
  159. GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found)
  160. {
  161. *found = monitor->modeCount;
  162. return monitor->modes;
  163. }
  164. void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
  165. {
  166. *mode = monitor->modes[monitor->wl.currentMode];
  167. }
  168. GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
  169. {
  170. _glfwInputError(GLFW_PLATFORM_ERROR,
  171. "Wayland: Gamma ramp access is not available");
  172. return GLFW_FALSE;
  173. }
  174. void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor,
  175. const GLFWgammaramp* ramp)
  176. {
  177. _glfwInputError(GLFW_PLATFORM_ERROR,
  178. "Wayland: Gamma ramp access is not available");
  179. }
  180. //////////////////////////////////////////////////////////////////////////
  181. ////// GLFW native API //////
  182. //////////////////////////////////////////////////////////////////////////
  183. GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* handle)
  184. {
  185. _GLFWmonitor* monitor = (_GLFWmonitor*) handle;
  186. _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
  187. return monitor->wl.output;
  188. }