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