Revert fix for T48901: Use of XIWarpPointer
[blender.git] / intern / ghost / intern / GHOST_SystemX11.h
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file ghost/intern/GHOST_SystemX11.h
29  *  \ingroup GHOST
30  * Declaration of GHOST_SystemX11 class.
31  */
32
33 #ifndef __GHOST_SYSTEMX11_H__
34 #define __GHOST_SYSTEMX11_H__
35
36 #include <X11/Xlib.h>
37 #include <X11/XKBlib.h> /* allow detectable autorepeate */
38
39 #include "GHOST_System.h"
40 #include "../GHOST_Types.h"
41
42 // For tablets
43 #ifdef WITH_X11_XINPUT
44 #  include <X11/extensions/XInput.h>
45
46 /* Disable xinput warp, currently not implemented by Xorg for multi-head display.
47  * (see comment in xserver "Xi/xiwarppointer.c" -> "FIXME: panoramix stuff is missing" ~ v1.13.4)
48  * If this is supported we can add back xinput for warping (fixing T48901).
49  * For now disable (see T50383). */
50 // #  define USE_X11_XINPUT_WARP
51 #endif
52
53 #if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
54 #  define GHOST_X11_RES_NAME  "Blender" /* res_name */
55 #  define GHOST_X11_RES_CLASS "Blender" /* res_class */
56 #endif
57
58 /* generic error handlers */
59 int GHOST_X11_ApplicationErrorHandler(Display *display, XErrorEvent *theEvent);
60 int GHOST_X11_ApplicationIOErrorHandler(Display *display);
61
62 #define GHOST_X11_ERROR_HANDLERS_OVERRIDE(var) \
63         struct { \
64                 XErrorHandler handler; \
65                 XIOErrorHandler handler_io; \
66         } var = { \
67                 XSetErrorHandler(GHOST_X11_ApplicationErrorHandler), \
68                 XSetIOErrorHandler(GHOST_X11_ApplicationIOErrorHandler), \
69         }
70
71 #define GHOST_X11_ERROR_HANDLERS_RESTORE(var) \
72         { \
73                 (void)XSetErrorHandler(var.handler); \
74                 (void)XSetIOErrorHandler(var.handler_io); \
75         } ((void)0)
76
77 class GHOST_WindowX11;
78
79 /**
80  * X11 Implementation of GHOST_System class.
81  * \see GHOST_System.
82  * \author      Laurence Bourn
83  * \date        October 26, 2001
84  */
85
86 class GHOST_SystemX11 : public GHOST_System {
87 public:
88
89         /**
90          * Constructor
91          * this class should only be instanciated by GHOST_ISystem.
92          */
93
94         GHOST_SystemX11(
95             );
96
97         /**
98          * Destructor.
99          */
100         ~GHOST_SystemX11();
101
102
103         GHOST_TSuccess
104         init(
105             );
106
107         /**
108          * Informs if the system provides native dialogs (eg. confirm quit)
109          */
110         virtual bool supportsNativeDialogs(void);
111
112         /**
113          * \section Interface Inherited from GHOST_ISystem
114          */
115
116         /**
117          * Returns the system time.
118          * Returns the number of milliseconds since the start of the system process.
119          * \return The number of milliseconds.
120          */
121         GHOST_TUns64
122         getMilliSeconds(
123             ) const;
124
125
126         /**
127          * Returns the number of displays on this system.
128          * \return The number of displays.
129          */
130         GHOST_TUns8
131         getNumDisplays(
132             ) const;
133
134         /**
135          * Returns the dimensions of the main display on this system.
136          * \return The dimension of the main display.
137          */
138         void
139         getMainDisplayDimensions(
140             GHOST_TUns32& width,
141             GHOST_TUns32& height
142             ) const;
143
144         /**
145          * Returns the dimensions of all displays on this system.
146          * \return The dimension of the main display.
147          */
148         void
149         getAllDisplayDimensions(
150             GHOST_TUns32& width,
151             GHOST_TUns32& height
152             ) const;
153
154         /**
155          * Create a new window.
156          * The new window is added to the list of windows managed.
157          * Never explicitly delete the window, use disposeWindow() instead.
158          * \param   title   The name of the window (displayed in the title bar of the window if the OS supports it).
159          * \param   left        The coordinate of the left edge of the window.
160          * \param   top     The coordinate of the top edge of the window.
161          * \param   width       The width the window.
162          * \param   height      The height the window.
163          * \param   state       The state of the window when opened.
164          * \param   type        The type of drawing context installed in this window.
165          * \param   stereoVisual    Create a stereo visual for quad buffered stereo.
166          * \param   exclusive   Use to show the window ontop and ignore others
167          *                      (used fullscreen).
168          * \param       parentWindow    Parent (embedder) window
169          * \return      The new window (or 0 if creation failed).
170          */
171         GHOST_IWindow *
172         createWindow(
173             const STR_String& title,
174             GHOST_TInt32 left,
175             GHOST_TInt32 top,
176             GHOST_TUns32 width,
177             GHOST_TUns32 height,
178             GHOST_TWindowState state,
179             GHOST_TDrawingContextType type,
180             GHOST_GLSettings glSettings,
181             const bool exclusive = false,
182             const GHOST_TEmbedderWindowID parentWindow = 0
183             );
184
185         /**
186          * Retrieves events from the system and stores them in the queue.
187          * \param waitForEvent Flag to wait for an event (or return immediately).
188          * \return Indication of the presence of events.
189          */
190         bool
191         processEvents(
192             bool waitForEvent
193             );
194
195         GHOST_TSuccess
196         getCursorPosition(
197             GHOST_TInt32& x,
198             GHOST_TInt32& y
199             ) const;
200
201         GHOST_TSuccess
202         setCursorPosition(
203             GHOST_TInt32 x,
204             GHOST_TInt32 y
205             );
206
207         /**
208          * Returns the state of all modifier keys.
209          * \param keys  The state of all modifier keys (true == pressed).
210          * \return              Indication of success.
211          */
212         GHOST_TSuccess
213         getModifierKeys(
214             GHOST_ModifierKeys& keys
215             ) const;
216
217         /**
218          * Returns the state of the mouse buttons (ouside the message queue).
219          * \param buttons       The state of the buttons.
220          * \return                      Indication of success.
221          */
222         GHOST_TSuccess
223         getButtons(
224             GHOST_Buttons& buttons
225             ) const;
226
227         /**
228          * Flag a window as dirty. This will
229          * generate a GHOST window update event on a call to processEvents()
230          */
231
232         void
233         addDirtyWindow(
234             GHOST_WindowX11 *bad_wind
235             );
236
237
238         /**
239          * return a pointer to the X11 display structure
240          */
241
242         Display *
243         getXDisplay(
244                 ) {
245                 return m_display;
246         }
247
248 #if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
249         XIM
250         getX11_XIM()
251         {
252                 return m_xim;
253         }
254 #endif
255
256         /* Helped function for get data from the clipboard. */
257         void getClipboard_xcout(const XEvent *evt, Atom sel, Atom target,
258                                 unsigned char **txt, unsigned long *len,
259                                 unsigned int *context) const;
260
261         /**
262          * Returns unsigned char from CUT_BUFFER0
263          * \param selection             Get selection, X11 only feature
264          * \return                              Returns the Clipboard indicated by Flag
265          */
266         GHOST_TUns8 *getClipboard(bool selection) const;
267
268         /**
269          * Puts buffer to system clipboard
270          * \param buffer        The buffer to copy to the clipboard
271          * \param selection     Set the selection into the clipboard, X11 only feature
272          */
273         void putClipboard(GHOST_TInt8 *buffer, bool selection) const;
274
275 #ifdef WITH_XDND
276         /**
277          * Creates a drag'n'drop event and pushes it immediately onto the event queue.
278          * Called by GHOST_DropTargetX11 class.
279          * \param eventType The type of drag'n'drop event
280          * \param draggedObjectType The type object concerned (currently array of file names, string, ?bitmap)
281          * \param mouseX x mouse coordinate (in window coordinates)
282          * \param mouseY y mouse coordinate
283          * \param window The window on which the event occurred
284          * \return Indication whether the event was handled.
285          */
286         static GHOST_TSuccess pushDragDropEvent(GHOST_TEventType eventType, GHOST_TDragnDropTypes draggedObjectType, GHOST_IWindow *window, int mouseX, int mouseY, void *data);
287 #endif
288
289         /**
290          * \see GHOST_ISystem
291          */
292         int toggleConsole(int /*action*/) {
293                 return 0;
294         }
295
296 #ifdef WITH_X11_XINPUT
297         typedef struct GHOST_TabletX11 {
298                 GHOST_TTabletMode mode;
299                 XDevice *Device;
300                 XID ID;
301
302                 int MotionEvent;
303                 int ProxInEvent;
304                 int ProxOutEvent;
305                 int PressEvent;
306
307                 int PressureLevels;
308                 int XtiltLevels, YtiltLevels;
309         } GHOST_TabletX11;
310
311         std::vector<GHOST_TabletX11> &GetXTablets()
312         {
313                 return m_xtablets;
314         }
315 #endif // WITH_X11_XINPUT
316
317         struct {
318                 /**
319                  * Atom used for ICCCM, WM-spec and Motif.
320                  * We only need get this atom at the start, it's relative
321                  * to the display not the window and are public for every
322                  * window that need it.
323                  */
324                 Atom WM_STATE;
325                 Atom WM_CHANGE_STATE;
326                 Atom _NET_WM_STATE;
327                 Atom _NET_WM_STATE_MAXIMIZED_HORZ;
328                 Atom _NET_WM_STATE_MAXIMIZED_VERT;
329                 Atom _NET_WM_STATE_FULLSCREEN;
330                 Atom _MOTIF_WM_HINTS;
331                 Atom WM_TAKE_FOCUS;
332                 Atom WM_PROTOCOLS;
333                 Atom WM_DELETE_WINDOW;
334
335                 /* Atoms for Selection, copy & paste. */
336                 Atom TARGETS;
337                 Atom STRING;
338                 Atom COMPOUND_TEXT;
339                 Atom TEXT;
340                 Atom CLIPBOARD;
341                 Atom PRIMARY;
342                 Atom XCLIP_OUT;
343                 Atom INCR;
344                 Atom UTF8_STRING;
345 #ifdef WITH_X11_XINPUT
346                 Atom TABLET;
347 #endif
348         } m_atom;
349
350 #ifdef WITH_X11_XINPUT
351         XExtensionVersion m_xinput_version;
352 #endif
353
354 private:
355
356         Display *m_display;
357
358         /* Use for scancode lookups. */
359         XkbDescRec *m_xkb_descr;
360
361 #if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
362         XIM m_xim;
363 #endif
364
365 #ifdef WITH_X11_XINPUT
366         /* Tablet devices */
367         std::vector<GHOST_TabletX11> m_xtablets;
368 #endif
369
370         /// The vector of windows that need to be updated.
371         std::vector<GHOST_WindowX11 *> m_dirty_windows;
372
373         /// Start time at initialization.
374         GHOST_TUns64 m_start_time;
375
376         /// A vector of keyboard key masks
377         char m_keyboard_vector[32];
378
379         /* to prevent multiple warp, we store the time of the last warp event
380          * and stop accumulating all events generated before that */
381         Time m_last_warp;
382
383         /* detect autorepeat glitch */
384         unsigned int m_last_release_keycode;
385         Time m_last_release_time;
386
387         /**
388          * Return the ghost window associated with the
389          * X11 window xwind
390          */
391
392 #if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
393         bool openX11_IM();
394 #endif
395
396 #ifdef WITH_X11_XINPUT
397         void clearXInputDevices();
398         void refreshXInputDevices();
399 #endif
400
401         GHOST_WindowX11 *
402         findGhostWindow(
403             Window xwind
404             ) const;
405
406         void
407         processEvent(
408             XEvent *xe
409             );
410
411         Time
412         lastEventTime(
413             Time default_time
414             );
415
416         bool
417         generateWindowExposeEvents(
418             );
419 };
420
421 #endif