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