GLVis  v4.2
Accurate and flexible finite element visualization
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
sdl_x11.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
2 // at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3 // LICENSE and NOTICE for details. LLNL-CODE-443271.
4 //
5 // This file is part of the GLVis visualization tool and library. For more
6 // information and source code availability see https://glvis.org.
7 //
8 // GLVis is free software; you can redistribute it and/or modify it under the
9 // terms of the BSD-3 license. We welcome feedback and contributions, see file
10 // CONTRIBUTING.md for details.
11 
12 #include "sdl_x11.hpp"
13 
14 #ifdef SDL_VIDEO_DRIVER_X11
15 
16 #include <vector>
17 #include <array>
18 #include <iostream>
19 
20 #ifndef __EMSCRIPTEN__
21 #include <SDL2/SDL_syswm.h>
22 #else
23 #include <SDL_syswm.h>
24 #endif
25 
26 #ifdef SDL_VIDEO_DRIVER_X11_XINPUT2
27 #include <X11/extensions/XInput2.h>
28 #endif // SDL_VIDEO_DRIVER_X11_XINPUT2
29 
30 using namespace std;
31 
32 void SdlX11Platform::RegisterWindow(SDL_Window* window)
33 {
34  SDL_SysWMinfo sysinfo;
35  SDL_VERSION(&sysinfo.version);
36  if (!SDL_GetWindowWMInfo(window, &sysinfo))
37  {
38  cerr << "Error: unable to get window manager information for the "
39  << "current window." << endl;
40  return;
41  }
42  if (sysinfo.subsystem != SDL_SYSWM_X11)
43  {
44  cerr << "Error: created SDL window is not an X11 window." << endl;
45  return;
46  }
47  Display *disp = sysinfo.info.x11.display;
48  Window wnd = sysinfo.info.x11.window;
49 
50  display_fds.emplace(window, ConnectionNumber(disp));
51 
52 #ifdef SDL_VIDEO_DRIVER_X11_XINPUT2
53  // Disable XInput extension events since they are generated even outside
54  // the GLVis window.
55  Window root_win = DefaultRootWindow(disp);
56  unsigned char mask[4] = {0,0,0,0};
57  XIEventMask event_mask;
58  event_mask.deviceid = XIAllMasterDevices;
59  event_mask.mask_len = sizeof(mask);
60  event_mask.mask = mask;
61 #ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2
62  const char Xi_lib[] = SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2;
63 #else
64  const char Xi_lib[] = "libXi.so";
65 #endif
66  typedef int (*XISelectEvents_ptr)(Display *, Window, XIEventMask *, int);
67  XISelectEvents_ptr XISelectEvents_ = NULL;
68  void *lib = SDL_LoadObject(Xi_lib);
69  if (lib != NULL)
70  {
71  XISelectEvents_ =
72  (XISelectEvents_ptr)SDL_LoadFunction(lib, "XISelectEvents");
73  }
74  if (XISelectEvents_ == NULL)
75  {
76  cerr << "Error accessing XISelectEvents!" << endl;
77  exit(EXIT_FAILURE);
78  }
79  if (XISelectEvents_(disp, root_win, &event_mask, 1) != Success)
80  {
81  cerr << "Failed to disable XInput on the default root window!" << endl;
82  }
83  if (XISelectEvents_(disp, wnd, &event_mask, 1) != Success)
84  {
85  cerr << "Failed to disable XInput on the current window!" << endl;
86  }
87 #ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2
88  SDL_UnloadObject(lib);
89 #endif
90 #endif // SDL_VIDEO_DRIVER_X11_XINPUT2
91 }
92 
93 void SdlX11Platform::UnregisterWindow(SDL_Window* window)
94 {
95  display_fds.erase(window);
96 }
97 
99 {
100  vector<pollfd> pfd;
101  pfd.emplace_back( pollfd{ event_pfd[0], POLLIN, 0 } );
102 
103  for (auto wnd : display_fds)
104  {
105  // add file descriptors for the window event queue
106  pfd.emplace_back( pollfd{ wnd.second, POLLIN, 0 } );
107  }
108 
109  int nstr;
110  do
111  {
112  // We timeout the poll call after 500ms, just in case a pending SDL_QUIT
113  // needs to be pumped into the SDL event queue
114  nstr = poll(pfd.data(), pfd.size(), 500);
115  }
116  while (nstr == -1 && errno == EINTR);
117 
118  if (nstr == -1) { perror("poll()"); }
119 
120  int n = 0;
121  // Read out the pending GLVisCommand-sent events, if any
122  do
123  {
124  array<char, 16> buf;
125  n = read(event_pfd[0], buf.data(), buf.size());
126  }
127  while (n > 0);
128 }
129 
130 #endif // SDL_VIDEO_DRIVER_X11
thread_local SdlWindow * wnd
Definition: aux_vis.cpp:50
void WaitEvent()
Definition: sdl_x11.cpp:98
void RegisterWindow(SDL_Window *window)
Definition: sdl_x11.cpp:32
void UnregisterWindow(SDL_Window *window)
Definition: sdl_x11.cpp:93