1 //======================================================================== 2 // GLFW 3.3 X11 - www.glfw.org 3 //------------------------------------------------------------------------ 4 // Copyright (c) 2002-2006 Marcus Geelnard 5 // Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org> 6 // 7 // This software is provided 'as-is', without any express or implied 8 // warranty. In no event will the authors be held liable for any damages 9 // arising from the use of this software. 10 // 11 // Permission is granted to anyone to use this software for any purpose, 12 // including commercial applications, and to alter it and redistribute it 13 // freely, subject to the following restrictions: 14 // 15 // 1. The origin of this software must not be misrepresented; you must not 16 // claim that you wrote the original software. If you use this software 17 // in a product, an acknowledgment in the product documentation would 18 // be appreciated but is not required. 19 // 20 // 2. Altered source versions must be plainly marked as such, and must not 21 // be misrepresented as being the original software. 22 // 23 // 3. This notice may not be removed or altered from any source 24 // distribution. 25 // 26 //======================================================================== 27 28 #include <unistd.h> 29 #include <signal.h> 30 #include <stdint.h> 31 #include <dlfcn.h> 32 33 #include <X11/Xlib.h> 34 #include <X11/keysym.h> 35 #include <X11/Xatom.h> 36 #include <X11/Xcursor/Xcursor.h> 37 38 // The XRandR extension provides mode setting and gamma control 39 #include <X11/extensions/Xrandr.h> 40 41 // The Xkb extension provides improved keyboard support 42 #include <X11/XKBlib.h> 43 44 // The Xinerama extension provides legacy monitor indices 45 #include <X11/extensions/Xinerama.h> 46 47 // The XInput extension provides raw mouse motion input 48 #include <X11/extensions/XInput2.h> 49 50 typedef XRRCrtcGamma* (* PFN_XRRAllocGamma)(int); 51 typedef void (* PFN_XRRFreeCrtcInfo)(XRRCrtcInfo*); 52 typedef void (* PFN_XRRFreeGamma)(XRRCrtcGamma*); 53 typedef void (* PFN_XRRFreeOutputInfo)(XRROutputInfo*); 54 typedef void (* PFN_XRRFreeScreenResources)(XRRScreenResources*); 55 typedef XRRCrtcGamma* (* PFN_XRRGetCrtcGamma)(Display*,RRCrtc); 56 typedef int (* PFN_XRRGetCrtcGammaSize)(Display*,RRCrtc); 57 typedef XRRCrtcInfo* (* PFN_XRRGetCrtcInfo) (Display*,XRRScreenResources*,RRCrtc); 58 typedef XRROutputInfo* (* PFN_XRRGetOutputInfo)(Display*,XRRScreenResources*,RROutput); 59 typedef RROutput (* PFN_XRRGetOutputPrimary)(Display*,Window); 60 typedef XRRScreenResources* (* PFN_XRRGetScreenResourcesCurrent)(Display*,Window); 61 typedef Bool (* PFN_XRRQueryExtension)(Display*,int*,int*); 62 typedef Status (* PFN_XRRQueryVersion)(Display*,int*,int*); 63 typedef void (* PFN_XRRSelectInput)(Display*,Window,int); 64 typedef Status (* PFN_XRRSetCrtcConfig)(Display*,XRRScreenResources*,RRCrtc,Time,int,int,RRMode,Rotation,RROutput*,int); 65 typedef void (* PFN_XRRSetCrtcGamma)(Display*,RRCrtc,XRRCrtcGamma*); 66 typedef int (* PFN_XRRUpdateConfiguration)(XEvent*); 67 #define XRRAllocGamma _glfw.x11.randr.AllocGamma 68 #define XRRFreeCrtcInfo _glfw.x11.randr.FreeCrtcInfo 69 #define XRRFreeGamma _glfw.x11.randr.FreeGamma 70 #define XRRFreeOutputInfo _glfw.x11.randr.FreeOutputInfo 71 #define XRRFreeScreenResources _glfw.x11.randr.FreeScreenResources 72 #define XRRGetCrtcGamma _glfw.x11.randr.GetCrtcGamma 73 #define XRRGetCrtcGammaSize _glfw.x11.randr.GetCrtcGammaSize 74 #define XRRGetCrtcInfo _glfw.x11.randr.GetCrtcInfo 75 #define XRRGetOutputInfo _glfw.x11.randr.GetOutputInfo 76 #define XRRGetOutputPrimary _glfw.x11.randr.GetOutputPrimary 77 #define XRRGetScreenResourcesCurrent _glfw.x11.randr.GetScreenResourcesCurrent 78 #define XRRQueryExtension _glfw.x11.randr.QueryExtension 79 #define XRRQueryVersion _glfw.x11.randr.QueryVersion 80 #define XRRSelectInput _glfw.x11.randr.SelectInput 81 #define XRRSetCrtcConfig _glfw.x11.randr.SetCrtcConfig 82 #define XRRSetCrtcGamma _glfw.x11.randr.SetCrtcGamma 83 #define XRRUpdateConfiguration _glfw.x11.randr.UpdateConfiguration 84 85 typedef XcursorImage* (* PFN_XcursorImageCreate)(int,int); 86 typedef void (* PFN_XcursorImageDestroy)(XcursorImage*); 87 typedef Cursor (* PFN_XcursorImageLoadCursor)(Display*,const XcursorImage*); 88 #define XcursorImageCreate _glfw.x11.xcursor.ImageCreate 89 #define XcursorImageDestroy _glfw.x11.xcursor.ImageDestroy 90 #define XcursorImageLoadCursor _glfw.x11.xcursor.ImageLoadCursor 91 92 typedef Bool (* PFN_XineramaIsActive)(Display*); 93 typedef Bool (* PFN_XineramaQueryExtension)(Display*,int*,int*); 94 typedef XineramaScreenInfo* (* PFN_XineramaQueryScreens)(Display*,int*); 95 #define XineramaIsActive _glfw.x11.xinerama.IsActive 96 #define XineramaQueryExtension _glfw.x11.xinerama.QueryExtension 97 #define XineramaQueryScreens _glfw.x11.xinerama.QueryScreens 98 99 typedef XID xcb_window_t; 100 typedef XID xcb_visualid_t; 101 typedef struct xcb_connection_t xcb_connection_t; 102 typedef xcb_connection_t* (* PFN_XGetXCBConnection)(Display*); 103 #define XGetXCBConnection _glfw.x11.x11xcb.GetXCBConnection 104 105 typedef Bool (* PFN_XF86VidModeQueryExtension)(Display*,int*,int*); 106 typedef Bool (* PFN_XF86VidModeGetGammaRamp)(Display*,int,int,unsigned short*,unsigned short*,unsigned short*); 107 typedef Bool (* PFN_XF86VidModeSetGammaRamp)(Display*,int,int,unsigned short*,unsigned short*,unsigned short*); 108 typedef Bool (* PFN_XF86VidModeGetGammaRampSize)(Display*,int,int*); 109 #define XF86VidModeQueryExtension _glfw.x11.vidmode.QueryExtension 110 #define XF86VidModeGetGammaRamp _glfw.x11.vidmode.GetGammaRamp 111 #define XF86VidModeSetGammaRamp _glfw.x11.vidmode.SetGammaRamp 112 #define XF86VidModeGetGammaRampSize _glfw.x11.vidmode.GetGammaRampSize 113 114 typedef Status (* PFN_XIQueryVersion)(Display*,int*,int*); 115 typedef int (* PFN_XISelectEvents)(Display*,Window,XIEventMask*,int); 116 #define XIQueryVersion _glfw.x11.xi.QueryVersion 117 #define XISelectEvents _glfw.x11.xi.SelectEvents 118 119 typedef Bool (* PFN_XRenderQueryExtension)(Display*,int*,int*); 120 typedef Status (* PFN_XRenderQueryVersion)(Display*dpy,int*,int*); 121 typedef XRenderPictFormat* (* PFN_XRenderFindVisualFormat)(Display*,Visual const*); 122 #define XRenderQueryExtension _glfw.x11.xrender.QueryExtension 123 #define XRenderQueryVersion _glfw.x11.xrender.QueryVersion 124 #define XRenderFindVisualFormat _glfw.x11.xrender.FindVisualFormat 125 126 typedef VkFlags VkXlibSurfaceCreateFlagsKHR; 127 typedef VkFlags VkXcbSurfaceCreateFlagsKHR; 128 129 typedef struct VkXlibSurfaceCreateInfoKHR 130 { 131 VkStructureType sType; 132 const void* pNext; 133 VkXlibSurfaceCreateFlagsKHR flags; 134 Display* dpy; 135 Window window; 136 } VkXlibSurfaceCreateInfoKHR; 137 138 typedef struct VkXcbSurfaceCreateInfoKHR 139 { 140 VkStructureType sType; 141 const void* pNext; 142 VkXcbSurfaceCreateFlagsKHR flags; 143 xcb_connection_t* connection; 144 xcb_window_t window; 145 } VkXcbSurfaceCreateInfoKHR; 146 147 typedef VkResult (APIENTRY *PFN_vkCreateXlibSurfaceKHR)(VkInstance,const VkXlibSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*); 148 typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)(VkPhysicalDevice,uint32_t,Display*,VisualID); 149 typedef VkResult (APIENTRY *PFN_vkCreateXcbSurfaceKHR)(VkInstance,const VkXcbSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*); 150 typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)(VkPhysicalDevice,uint32_t,xcb_connection_t*,xcb_visualid_t); 151 152 #include "posix_thread.h" 153 #include "posix_time.h" 154 #include "xkb_unicode.h" 155 #include "glx_context.h" 156 #include "egl_context.h" 157 #include "osmesa_context.h" 158 #if defined(__linux__) 159 #include "linux_joystick.h" 160 #else 161 #include "null_joystick.h" 162 #endif 163 164 #define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL) 165 #define _glfw_dlclose(handle) dlclose(handle) 166 #define _glfw_dlsym(handle, name) dlsym(handle, name) 167 168 #define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->x11.handle) 169 #define _GLFW_EGL_NATIVE_DISPLAY ((EGLNativeDisplayType) _glfw.x11.display) 170 171 #define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowX11 x11 172 #define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryX11 x11 173 #define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorX11 x11 174 #define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorX11 x11 175 176 177 // X11-specific per-window data 178 // 179 typedef struct _GLFWwindowX11 180 { 181 Colormap colormap; 182 Window handle; 183 XIC ic; 184 185 GLFWbool overrideRedirect; 186 GLFWbool iconified; 187 GLFWbool maximized; 188 189 // Whether the visual supports framebuffer transparency 190 GLFWbool transparent; 191 192 // Cached position and size used to filter out duplicate events 193 int width, height; 194 int xpos, ypos; 195 196 // The last received cursor position, regardless of source 197 int lastCursorPosX, lastCursorPosY; 198 // The last position the cursor was warped to by GLFW 199 int warpCursorPosX, warpCursorPosY; 200 201 // The time of the last KeyPress event 202 Time lastKeyTime; 203 204 } _GLFWwindowX11; 205 206 // X11-specific global data 207 // 208 typedef struct _GLFWlibraryX11 209 { 210 Display* display; 211 int screen; 212 Window root; 213 214 // System content scale 215 float contentScaleX, contentScaleY; 216 // Helper window for IPC 217 Window helperWindowHandle; 218 // Invisible cursor for hidden cursor mode 219 Cursor hiddenCursorHandle; 220 // Context for mapping window XIDs to _GLFWwindow pointers 221 XContext context; 222 // XIM input method 223 XIM im; 224 // Most recent error code received by X error handler 225 int errorCode; 226 // Primary selection string (while the primary selection is owned) 227 char* primarySelectionString; 228 // Clipboard string (while the selection is owned) 229 char* clipboardString; 230 // Key name string 231 char keyName[5]; 232 // X11 keycode to GLFW key LUT 233 short int keycodes[256]; 234 // GLFW key to X11 keycode LUT 235 short int scancodes[GLFW_KEY_LAST + 1]; 236 // Where to place the cursor when re-enabled 237 double restoreCursorPosX, restoreCursorPosY; 238 // The window whose disabled cursor mode is active 239 _GLFWwindow* disabledCursorWindow; 240 241 // Window manager atoms 242 Atom WM_PROTOCOLS; 243 Atom WM_STATE; 244 Atom WM_DELETE_WINDOW; 245 Atom NET_WM_NAME; 246 Atom NET_WM_ICON_NAME; 247 Atom NET_WM_ICON; 248 Atom NET_WM_PID; 249 Atom NET_WM_PING; 250 Atom NET_WM_WINDOW_TYPE; 251 Atom NET_WM_WINDOW_TYPE_NORMAL; 252 Atom NET_WM_STATE; 253 Atom NET_WM_STATE_ABOVE; 254 Atom NET_WM_STATE_FULLSCREEN; 255 Atom NET_WM_STATE_MAXIMIZED_VERT; 256 Atom NET_WM_STATE_MAXIMIZED_HORZ; 257 Atom NET_WM_STATE_DEMANDS_ATTENTION; 258 Atom NET_WM_BYPASS_COMPOSITOR; 259 Atom NET_WM_FULLSCREEN_MONITORS; 260 Atom NET_WM_WINDOW_OPACITY; 261 Atom NET_WM_CM_Sx; 262 Atom NET_WORKAREA; 263 Atom NET_CURRENT_DESKTOP; 264 Atom NET_ACTIVE_WINDOW; 265 Atom NET_FRAME_EXTENTS; 266 Atom NET_REQUEST_FRAME_EXTENTS; 267 Atom MOTIF_WM_HINTS; 268 269 // Xdnd (drag and drop) atoms 270 Atom XdndAware; 271 Atom XdndEnter; 272 Atom XdndPosition; 273 Atom XdndStatus; 274 Atom XdndActionCopy; 275 Atom XdndDrop; 276 Atom XdndFinished; 277 Atom XdndSelection; 278 Atom XdndTypeList; 279 Atom text_uri_list; 280 281 // Selection (clipboard) atoms 282 Atom TARGETS; 283 Atom MULTIPLE; 284 Atom INCR; 285 Atom CLIPBOARD; 286 Atom PRIMARY; 287 Atom CLIPBOARD_MANAGER; 288 Atom SAVE_TARGETS; 289 Atom NULL_; 290 Atom UTF8_STRING; 291 Atom COMPOUND_STRING; 292 Atom ATOM_PAIR; 293 Atom GLFW_SELECTION; 294 295 struct { 296 GLFWbool available; 297 void* handle; 298 int eventBase; 299 int errorBase; 300 int major; 301 int minor; 302 GLFWbool gammaBroken; 303 GLFWbool monitorBroken; 304 PFN_XRRAllocGamma AllocGamma; 305 PFN_XRRFreeCrtcInfo FreeCrtcInfo; 306 PFN_XRRFreeGamma FreeGamma; 307 PFN_XRRFreeOutputInfo FreeOutputInfo; 308 PFN_XRRFreeScreenResources FreeScreenResources; 309 PFN_XRRGetCrtcGamma GetCrtcGamma; 310 PFN_XRRGetCrtcGammaSize GetCrtcGammaSize; 311 PFN_XRRGetCrtcInfo GetCrtcInfo; 312 PFN_XRRGetOutputInfo GetOutputInfo; 313 PFN_XRRGetOutputPrimary GetOutputPrimary; 314 PFN_XRRGetScreenResourcesCurrent GetScreenResourcesCurrent; 315 PFN_XRRQueryExtension QueryExtension; 316 PFN_XRRQueryVersion QueryVersion; 317 PFN_XRRSelectInput SelectInput; 318 PFN_XRRSetCrtcConfig SetCrtcConfig; 319 PFN_XRRSetCrtcGamma SetCrtcGamma; 320 PFN_XRRUpdateConfiguration UpdateConfiguration; 321 } randr; 322 323 struct { 324 GLFWbool available; 325 GLFWbool detectable; 326 int majorOpcode; 327 int eventBase; 328 int errorBase; 329 int major; 330 int minor; 331 } xkb; 332 333 struct { 334 int count; 335 int timeout; 336 int interval; 337 int blanking; 338 int exposure; 339 } saver; 340 341 struct { 342 int version; 343 Window source; 344 Atom format; 345 } xdnd; 346 347 struct { 348 void* handle; 349 PFN_XcursorImageCreate ImageCreate; 350 PFN_XcursorImageDestroy ImageDestroy; 351 PFN_XcursorImageLoadCursor ImageLoadCursor; 352 } xcursor; 353 354 struct { 355 GLFWbool available; 356 void* handle; 357 int major; 358 int minor; 359 PFN_XineramaIsActive IsActive; 360 PFN_XineramaQueryExtension QueryExtension; 361 PFN_XineramaQueryScreens QueryScreens; 362 } xinerama; 363 364 struct { 365 void* handle; 366 PFN_XGetXCBConnection GetXCBConnection; 367 } x11xcb; 368 369 struct { 370 GLFWbool available; 371 void* handle; 372 int eventBase; 373 int errorBase; 374 PFN_XF86VidModeQueryExtension QueryExtension; 375 PFN_XF86VidModeGetGammaRamp GetGammaRamp; 376 PFN_XF86VidModeSetGammaRamp SetGammaRamp; 377 PFN_XF86VidModeGetGammaRampSize GetGammaRampSize; 378 } vidmode; 379 380 struct { 381 GLFWbool available; 382 void* handle; 383 int majorOpcode; 384 int eventBase; 385 int errorBase; 386 int major; 387 int minor; 388 PFN_XIQueryVersion QueryVersion; 389 PFN_XISelectEvents SelectEvents; 390 } xi; 391 392 struct { 393 GLFWbool available; 394 void* handle; 395 int major; 396 int minor; 397 int eventBase; 398 int errorBase; 399 PFN_XRenderQueryExtension QueryExtension; 400 PFN_XRenderQueryVersion QueryVersion; 401 PFN_XRenderFindVisualFormat FindVisualFormat; 402 } xrender; 403 404 } _GLFWlibraryX11; 405 406 // X11-specific per-monitor data 407 // 408 typedef struct _GLFWmonitorX11 409 { 410 RROutput output; 411 RRCrtc crtc; 412 RRMode oldMode; 413 414 // Index of corresponding Xinerama screen, 415 // for EWMH full screen window placement 416 int index; 417 418 } _GLFWmonitorX11; 419 420 // X11-specific per-cursor data 421 // 422 typedef struct _GLFWcursorX11 423 { 424 Cursor handle; 425 426 } _GLFWcursorX11; 427 428 429 void _glfwPollMonitorsX11(void); 430 void _glfwSetVideoModeX11(_GLFWmonitor* monitor, const GLFWvidmode* desired); 431 void _glfwRestoreVideoModeX11(_GLFWmonitor* monitor); 432 433 Cursor _glfwCreateCursorX11(const GLFWimage* image, int xhot, int yhot); 434 435 unsigned long _glfwGetWindowPropertyX11(Window window, 436 Atom property, 437 Atom type, 438 unsigned char** value); 439 GLFWbool _glfwIsVisualTransparentX11(Visual* visual); 440 441 void _glfwGrabErrorHandlerX11(void); 442 void _glfwReleaseErrorHandlerX11(void); 443 void _glfwInputErrorX11(int error, const char* message); 444 445 void _glfwPushSelectionToManagerX11(void); 446 447