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