~ubuntu-branches/ubuntu/trusty/blender/trusty

« back to all changes in this revision

Viewing changes to intern/ghost/intern/GHOST_SystemX11.cpp

  • Committer: Package Import Robot
  • Author(s): Jeremy Bicha
  • Date: 2013-03-06 12:08:47 UTC
  • mfrom: (1.5.1) (14.1.8 experimental)
  • Revision ID: package-import@ubuntu.com-20130306120847-frjfaryb2zrotwcg
Tags: 2.66a-1ubuntu1
* Resynchronize with Debian (LP: #1076930, #1089256, #1052743, #999024,
  #1122888, #1147084)
* debian/control:
  - Lower build-depends on libavcodec-dev since we're not
    doing the libav9 transition in Ubuntu yet

Show diffs side-by-side

added added

removed removed

Lines of Context:
32
32
 *  \ingroup GHOST
33
33
 */
34
34
 
35
 
 
36
35
#include "GHOST_SystemX11.h"
37
36
#include "GHOST_WindowX11.h"
38
37
#include "GHOST_WindowManager.h"
44
43
#include "GHOST_DisplayManagerX11.h"
45
44
#include "GHOST_EventDragnDrop.h"
46
45
#ifdef WITH_INPUT_NDOF
47
 
#include "GHOST_NDOFManagerX11.h"
 
46
#  include "GHOST_NDOFManagerX11.h"
48
47
#endif
49
48
 
50
49
#ifdef WITH_XDND
51
 
#include "GHOST_DropTargetX11.h"
 
50
#  include "GHOST_DropTargetX11.h"
52
51
#endif
53
52
 
54
53
#include "GHOST_Debug.h"
61
60
#include <X11/XF86keysym.h>
62
61
#endif
63
62
 
64
 
// For timing
65
 
 
 
63
/* For timing */
66
64
#include <sys/time.h>
67
65
#include <unistd.h>
68
66
 
69
67
#include <iostream>
70
68
#include <vector>
71
 
#include <stdio.h> // for fprintf only
72
 
#include <cstdlib> // for exit
73
 
 
74
 
static GHOST_TKey
75
 
convertXKey(KeySym key);
76
 
 
77
 
//these are for copy and select copy
78
 
static char *txt_cut_buffer= NULL;
79
 
static char *txt_select_buffer= NULL;
 
69
#include <stdio.h> /* for fprintf only */
 
70
#include <cstdlib> /* for exit */
 
71
 
 
72
/* for debugging - so we can breakpoint X11 errors */
 
73
// #define USE_X11_ERROR_HANDLERS
 
74
 
 
75
/* see [#34039] Fix Alt key glitch on Unity desktop */
 
76
#define USE_UNITY_WORKAROUND
 
77
 
 
78
static GHOST_TKey convertXKey(KeySym key);
 
79
 
 
80
/* these are for copy and select copy */
 
81
static char *txt_cut_buffer = NULL;
 
82
static char *txt_select_buffer = NULL;
80
83
 
81
84
using namespace std;
82
85
 
83
86
GHOST_SystemX11::
84
87
GHOST_SystemX11(
85
 
) : 
 
88
    ) :
86
89
        GHOST_System(),
87
90
        m_start_time(0)
88
91
{
90
93
        
91
94
        if (!m_display) {
92
95
                std::cerr << "Unable to open a display" << std::endl;
93
 
                abort(); //was return before, but this would just mean it will crash later
 
96
                abort(); /* was return before, but this would just mean it will crash later */
94
97
        }
95
98
 
96
 
        /* Open a connection to the X input manager */
 
99
#ifdef USE_X11_ERROR_HANDLERS
 
100
        (void) XSetErrorHandler(GHOST_X11_ApplicationErrorHandler);
 
101
        (void) XSetIOErrorHandler(GHOST_X11_ApplicationIOErrorHandler);
 
102
#endif
 
103
 
97
104
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
98
 
        m_xim = XOpenIM(m_display, NULL, (char *)GHOST_X11_RES_NAME, (char *)GHOST_X11_RES_CLASS);
99
 
#endif
100
 
 
101
 
        m_delete_window_atom 
102
 
          = XInternAtom(m_display, "WM_DELETE_WINDOW", True);
103
 
 
104
 
        m_wm_protocols= XInternAtom(m_display, "WM_PROTOCOLS", False);
105
 
        m_wm_take_focus= XInternAtom(m_display, "WM_TAKE_FOCUS", False);
106
 
        m_wm_state= XInternAtom(m_display, "WM_STATE", False);
107
 
        m_wm_change_state= XInternAtom(m_display, "WM_CHANGE_STATE", False);
108
 
        m_net_state= XInternAtom(m_display, "_NET_WM_STATE", False);
109
 
        m_net_max_horz= XInternAtom(m_display,
110
 
                                        "_NET_WM_STATE_MAXIMIZED_HORZ", False);
111
 
        m_net_max_vert= XInternAtom(m_display,
112
 
                                        "_NET_WM_STATE_MAXIMIZED_VERT", False);
113
 
        m_net_fullscreen= XInternAtom(m_display,
114
 
                                        "_NET_WM_STATE_FULLSCREEN", False);
115
 
        m_motif= XInternAtom(m_display, "_MOTIF_WM_HINTS", False);
116
 
        m_targets= XInternAtom(m_display, "TARGETS", False);
117
 
        m_string= XInternAtom(m_display, "STRING", False);
118
 
        m_compound_text= XInternAtom(m_display, "COMPOUND_TEXT", False);
119
 
        m_text= XInternAtom(m_display, "TEXT", False);
120
 
        m_clipboard= XInternAtom(m_display, "CLIPBOARD", False);
121
 
        m_primary= XInternAtom(m_display, "PRIMARY", False);
122
 
        m_xclip_out= XInternAtom(m_display, "XCLIP_OUT", False);
123
 
        m_incr= XInternAtom(m_display, "INCR", False);
124
 
        m_utf8_string= XInternAtom(m_display, "UTF8_STRING", False);
 
105
        /* note -- don't open connection to XIM server here, because the locale
 
106
         * has to be set before opening the connection but setlocale() has not
 
107
         * been called yet.  the connection will be opened after entering
 
108
         * the event loop. */
 
109
        m_xim = NULL;
 
110
#endif
 
111
 
 
112
#define GHOST_INTERN_ATOM_IF_EXISTS(atom) { m_atom.atom = XInternAtom(m_display, #atom , True);  } (void)0
 
113
#define GHOST_INTERN_ATOM(atom)           { m_atom.atom = XInternAtom(m_display, #atom , False); } (void)0
 
114
 
 
115
        GHOST_INTERN_ATOM_IF_EXISTS(WM_DELETE_WINDOW);
 
116
        GHOST_INTERN_ATOM(WM_PROTOCOLS);
 
117
        GHOST_INTERN_ATOM(WM_TAKE_FOCUS);
 
118
        GHOST_INTERN_ATOM(WM_STATE);
 
119
        GHOST_INTERN_ATOM(WM_CHANGE_STATE);
 
120
        GHOST_INTERN_ATOM(_NET_WM_STATE);
 
121
        GHOST_INTERN_ATOM(_NET_WM_STATE_MAXIMIZED_HORZ);
 
122
        GHOST_INTERN_ATOM(_NET_WM_STATE_MAXIMIZED_VERT);
 
123
 
 
124
        GHOST_INTERN_ATOM(_NET_WM_STATE_FULLSCREEN);
 
125
        GHOST_INTERN_ATOM(_MOTIF_WM_HINTS);
 
126
        GHOST_INTERN_ATOM(TARGETS);
 
127
        GHOST_INTERN_ATOM(STRING);
 
128
        GHOST_INTERN_ATOM(COMPOUND_TEXT);
 
129
        GHOST_INTERN_ATOM(TEXT);
 
130
        GHOST_INTERN_ATOM(CLIPBOARD);
 
131
        GHOST_INTERN_ATOM(PRIMARY);
 
132
        GHOST_INTERN_ATOM(XCLIP_OUT);
 
133
        GHOST_INTERN_ATOM(INCR);
 
134
        GHOST_INTERN_ATOM(UTF8_STRING);
 
135
#ifdef WITH_X11_XINPUT
 
136
        m_atom.TABLET = XInternAtom(m_display, XI_TABLET, False);
 
137
#endif
 
138
 
 
139
#undef GHOST_INTERN_ATOM_IF_EXISTS
 
140
#undef GHOST_INTERN_ATOM
 
141
 
125
142
        m_last_warp = 0;
126
143
 
127
 
 
128
 
        // compute the initial time
 
144
        /* compute the initial time */
129
145
        timeval tv;
130
 
        if (gettimeofday(&tv,NULL) == -1) {
131
 
                GHOST_ASSERT(false,"Could not instantiate timer!");
 
146
        if (gettimeofday(&tv, NULL) == -1) {
 
147
                GHOST_ASSERT(false, "Could not instantiate timer!");
132
148
        }
133
149
        
134
 
        // Taking care not to overflow the tv.tv_sec*1000
135
 
        m_start_time = GHOST_TUns64(tv.tv_sec)*1000 + tv.tv_usec/1000;
 
150
        /* Taking care not to overflow the tv.tv_sec * 1000 */
 
151
        m_start_time = GHOST_TUns64(tv.tv_sec) * 1000 + tv.tv_usec / 1000;
136
152
        
137
153
        
138
154
        /* use detectable autorepeate, mac and windows also do this */
145
161
                XkbSetDetectableAutoRepeat(m_display, true, NULL);
146
162
        }
147
163
        
 
164
#ifdef WITH_X11_XINPUT
 
165
        /* initialize incase X11 fails to load */
 
166
        memset(&m_xtablet, 0, sizeof(m_xtablet));
 
167
 
 
168
        initXInputDevices();
 
169
#endif
148
170
}
149
171
 
150
172
GHOST_SystemX11::
151
173
~GHOST_SystemX11()
152
174
{
153
175
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
154
 
        XCloseIM(m_xim);
 
176
        if (m_xim) {
 
177
                XCloseIM(m_xim);
 
178
        }
155
179
#endif
156
180
 
 
181
#ifdef WITH_X11_XINPUT
 
182
        /* close tablet devices */
 
183
        if (m_xtablet.StylusDevice)
 
184
                XCloseDevice(m_display, m_xtablet.StylusDevice);
 
185
        
 
186
        if (m_xtablet.EraserDevice)
 
187
                XCloseDevice(m_display, m_xtablet.EraserDevice);
 
188
#endif /* WITH_X11_XINPUT */
 
189
 
157
190
        XCloseDisplay(m_display);
158
191
}
159
192
 
160
193
 
161
 
        GHOST_TSuccess 
 
194
GHOST_TSuccess
162
195
GHOST_SystemX11::
163
 
init(
164
 
){
 
196
init()
 
197
{
165
198
        GHOST_TSuccess success = GHOST_System::init();
166
199
 
167
200
        if (success) {
178
211
        return GHOST_kFailure;
179
212
}
180
213
 
181
 
        GHOST_TUns64
 
214
GHOST_TUns64
182
215
GHOST_SystemX11::
183
 
getMilliSeconds(
184
 
) const {
 
216
getMilliSeconds() const
 
217
{
185
218
        timeval tv;
186
 
        if (gettimeofday(&tv,NULL) == -1) {
187
 
                GHOST_ASSERT(false,"Could not compute time!");
 
219
        if (gettimeofday(&tv, NULL) == -1) {
 
220
                GHOST_ASSERT(false, "Could not compute time!");
188
221
        }
189
222
 
190
 
        // Taking care not to overflow the tv.tv_sec*1000
191
 
        return  GHOST_TUns64(tv.tv_sec)*1000 + tv.tv_usec/1000 - m_start_time;
 
223
        /* Taking care not to overflow the tv.tv_sec * 1000 */
 
224
        return GHOST_TUns64(tv.tv_sec) * 1000 + tv.tv_usec / 1000 - m_start_time;
192
225
}
193
226
        
194
 
        GHOST_TUns8 
 
227
GHOST_TUns8
195
228
GHOST_SystemX11::
196
 
getNumDisplays(
197
 
) const {
 
229
getNumDisplays() const
 
230
{
198
231
        return GHOST_TUns8(1);
199
232
}
200
233
 
201
 
        /**
202
 
         * Returns the dimensions of the main display on this system.
203
 
         * @return The dimension of the main display.
204
 
         */
205
 
        void 
 
234
/**
 
235
 * Returns the dimensions of the main display on this system.
 
236
 * \return The dimension of the main display.
 
237
 */
 
238
void
206
239
GHOST_SystemX11::
207
240
getMainDisplayDimensions(
208
 
        GHOST_TUns32& width,
209
 
        GHOST_TUns32& height
210
 
) const {       
 
241
                GHOST_TUns32& width,
 
242
                GHOST_TUns32& height) const
 
243
{
 
244
        if (m_display) {
 
245
                /* note, for this to work as documented,
 
246
                 * we would need to use Xinerama check r54370 for code that did thia,
 
247
                 * we've since removed since its not worth the extra dep - campbell */
 
248
                getAllDisplayDimensions(width, height);
 
249
        }
 
250
}
 
251
 
 
252
 
 
253
/**
 
254
 * Returns the dimensions of the main display on this system.
 
255
 * \return The dimension of the main display.
 
256
 */
 
257
void
 
258
GHOST_SystemX11::
 
259
getAllDisplayDimensions(
 
260
                GHOST_TUns32& width,
 
261
                GHOST_TUns32& height) const
 
262
{
211
263
        if (m_display) {
212
264
                width  = DisplayWidth(m_display, DefaultScreen(m_display));
213
265
                height = DisplayHeight(m_display, DefaultScreen(m_display));
214
266
        }
215
267
}
216
268
 
217
 
        /**
218
 
         * Create a new window.
219
 
         * The new window is added to the list of windows managed.
220
 
         * Never explicitly delete the window, use disposeWindow() instead.
221
 
         * @param       title   The name of the window (displayed in the title bar of the window if the OS supports it).
222
 
         * @param       left    The coordinate of the left edge of the window.
223
 
         * @param       top             The coordinate of the top edge of the window.
224
 
         * @param       width   The width the window.
225
 
         * @param       height  The height the window.
226
 
         * @param       state   The state of the window when opened.
227
 
         * @param       type    The type of drawing context installed in this window.
228
 
         * @param       stereoVisual    Stereo visual for quad buffered stereo.
229
 
         * @param       numOfAASamples  Number of samples used for AA (zero if no AA)
230
 
         * @param       parentWindow    Parent (embedder) window
231
 
         * @return      The new window (or 0 if creation failed).
232
 
         */
233
 
        GHOST_IWindow* 
 
269
/**
 
270
 * Create a new window.
 
271
 * The new window is added to the list of windows managed.
 
272
 * Never explicitly delete the window, use disposeWindow() instead.
 
273
 * \param       title   The name of the window (displayed in the title bar of the window if the OS supports it).
 
274
 * \param       left    The coordinate of the left edge of the window.
 
275
 * \param       top             The coordinate of the top edge of the window.
 
276
 * \param       width   The width the window.
 
277
 * \param       height  The height the window.
 
278
 * \param       state   The state of the window when opened.
 
279
 * \param       type    The type of drawing context installed in this window.
 
280
 * \param       stereoVisual    Stereo visual for quad buffered stereo.
 
281
 * \param       numOfAASamples  Number of samples used for AA (zero if no AA)
 
282
 * \param       parentWindow    Parent (embedder) window
 
283
 * \return      The new window (or 0 if creation failed).
 
284
 */
 
285
GHOST_IWindow *
234
286
GHOST_SystemX11::
235
287
createWindow(
236
 
        const STR_String& title,
237
 
        GHOST_TInt32 left,
238
 
        GHOST_TInt32 top,
239
 
        GHOST_TUns32 width,
240
 
        GHOST_TUns32 height,
241
 
        GHOST_TWindowState state,
242
 
        GHOST_TDrawingContextType type,
243
 
        bool stereoVisual,
244
 
        const GHOST_TUns16 numOfAASamples,
245
 
        const GHOST_TEmbedderWindowID parentWindow
246
 
){
247
 
        GHOST_WindowX11 * window = 0;
 
288
                const STR_String& title,
 
289
                GHOST_TInt32 left,
 
290
                GHOST_TInt32 top,
 
291
                GHOST_TUns32 width,
 
292
                GHOST_TUns32 height,
 
293
                GHOST_TWindowState state,
 
294
                GHOST_TDrawingContextType type,
 
295
                bool stereoVisual,
 
296
                const GHOST_TUns16 numOfAASamples,
 
297
                const GHOST_TEmbedderWindowID parentWindow)
 
298
{
 
299
        GHOST_WindowX11 *window = 0;
248
300
        
249
301
        if (!m_display) return 0;
250
302
        
251
303
 
252
304
        
253
305
 
254
 
        window = new GHOST_WindowX11 (
255
 
                this,m_display,title, left, top, width, height, state, parentWindow, type, stereoVisual
256
 
        );
 
306
        window = new GHOST_WindowX11(this, m_display, title,
 
307
                                     left, top, width, height,
 
308
                                     state, parentWindow, type, stereoVisual, numOfAASamples);
257
309
 
258
310
        if (window) {
259
 
                // Both are now handle in GHOST_WindowX11.cpp
260
 
                // Focus and Delete atoms.
 
311
                /* Both are now handle in GHOST_WindowX11.cpp
 
312
                 * Focus and Delete atoms. */
261
313
 
262
314
                if (window->getValid()) {
263
 
                        // Store the pointer to the window 
 
315
                        /* Store the pointer to the window */
264
316
                        m_windowManager->addWindow(window);
265
317
                        m_windowManager->setActiveWindow(window);
266
 
                        pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window) );
 
318
                        pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window) );
267
319
                }
268
320
                else {
269
321
                        delete window;
273
325
        return window;
274
326
}
275
327
 
276
 
        GHOST_WindowX11 * 
 
328
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
 
329
static void destroyIMCallback(XIM xim, XPointer ptr, XPointer data)
 
330
{
 
331
        GHOST_PRINT("XIM server died\n");
 
332
 
 
333
        if (ptr)
 
334
                *(XIM *)ptr = NULL;
 
335
}
 
336
 
 
337
bool GHOST_SystemX11::openX11_IM()
 
338
{
 
339
        if (!m_display)
 
340
                return false;
 
341
 
 
342
        /* set locale modifiers such as "@im=ibus" specified by XMODIFIERS */
 
343
        XSetLocaleModifiers("");
 
344
 
 
345
        m_xim = XOpenIM(m_display, NULL, (char *)GHOST_X11_RES_NAME, (char *)GHOST_X11_RES_CLASS);
 
346
        if (!m_xim)
 
347
                return false;
 
348
 
 
349
        XIMCallback destroy;
 
350
        destroy.callback = (XIMProc)destroyIMCallback;
 
351
        destroy.client_data = (XPointer)&m_xim;
 
352
        XSetIMValues(m_xim, XNDestroyCallback, &destroy, NULL);
 
353
        return true;
 
354
}
 
355
#endif
 
356
 
 
357
GHOST_WindowX11 *
277
358
GHOST_SystemX11::
278
359
findGhostWindow(
279
 
        Window xwind
280
 
) const {
 
360
                Window xwind) const
 
361
{
281
362
        
282
363
        if (xwind == 0) return NULL;
283
364
 
284
 
        // It is not entirely safe to do this as the backptr may point
285
 
        // to a window that has recently been removed. 
286
 
        // We should always check the window manager's list of windows 
287
 
        // and only process events on these windows.
 
365
        /* It is not entirely safe to do this as the backptr may point
 
366
         * to a window that has recently been removed.
 
367
         * We should always check the window manager's list of windows
 
368
         * and only process events on these windows. */
288
369
 
289
370
        vector<GHOST_IWindow *> & win_vec = m_windowManager->getWindows();
290
371
 
292
373
        vector<GHOST_IWindow *>::const_iterator win_end = win_vec.end();
293
374
        
294
375
        for (; win_it != win_end; ++win_it) {
295
 
                GHOST_WindowX11 * window = static_cast<GHOST_WindowX11 *>(*win_it);
 
376
                GHOST_WindowX11 *window = static_cast<GHOST_WindowX11 *>(*win_it);
296
377
                if (window->getXWindow() == xwind) {
297
378
                        return window;
298
379
                }
315
396
        else {
316
397
                timeval tv;
317
398
 
318
 
                tv.tv_sec = maxSleep/1000;
319
 
                tv.tv_usec = (maxSleep - tv.tv_sec*1000)*1000;
 
399
                tv.tv_sec = maxSleep / 1000;
 
400
                tv.tv_usec = (maxSleep - tv.tv_sec * 1000) * 1000;
320
401
        
321
402
                select(fd + 1, &fds, NULL, NULL, &tv);
322
403
        }
325
406
/* This function borrowed from Qt's X11 support
326
407
 * qclipboard_x11.cpp
327
408
 *  */
328
 
struct init_timestamp_data
329
 
{
330
 
    Time timestamp;
 
409
struct init_timestamp_data {
 
410
        Time timestamp;
331
411
};
332
412
 
333
 
static Bool init_timestamp_scanner(Display*, XEvent *event, XPointer arg)
 
413
static Bool init_timestamp_scanner(Display *, XEvent *event, XPointer arg)
334
414
{
335
415
        init_timestamp_data *data =
336
 
        reinterpret_cast<init_timestamp_data*>(arg);
337
 
    switch(event->type)
338
 
    {
339
 
    case ButtonPress:
340
 
    case ButtonRelease:
341
 
        data->timestamp = event->xbutton.time;
342
 
        break;
343
 
    case MotionNotify:
344
 
        data->timestamp = event->xmotion.time;
345
 
        break;
346
 
    case KeyPress:
347
 
    case KeyRelease:
348
 
        data->timestamp = event->xkey.time;
349
 
        break;
350
 
    case PropertyNotify:
351
 
        data->timestamp = event->xproperty.time;
352
 
        break;
353
 
    case EnterNotify:
354
 
    case LeaveNotify:
355
 
        data->timestamp = event->xcrossing.time;
356
 
        break;
357
 
    case SelectionClear:
358
 
        data->timestamp = event->xselectionclear.time;
359
 
        break;
360
 
    default:
361
 
        break;
362
 
    }
 
416
            reinterpret_cast<init_timestamp_data *>(arg);
 
417
        switch (event->type)
 
418
        {
 
419
                case ButtonPress:
 
420
                case ButtonRelease:
 
421
                        data->timestamp = event->xbutton.time;
 
422
                        break;
 
423
                case MotionNotify:
 
424
                        data->timestamp = event->xmotion.time;
 
425
                        break;
 
426
                case KeyPress:
 
427
                case KeyRelease:
 
428
                        data->timestamp = event->xkey.time;
 
429
                        break;
 
430
                case PropertyNotify:
 
431
                        data->timestamp = event->xproperty.time;
 
432
                        break;
 
433
                case EnterNotify:
 
434
                case LeaveNotify:
 
435
                        data->timestamp = event->xcrossing.time;
 
436
                        break;
 
437
                case SelectionClear:
 
438
                        data->timestamp = event->xselectionclear.time;
 
439
                        break;
 
440
                default:
 
441
                        break;
 
442
        }
363
443
 
364
 
    return false;
 
444
        return false;
365
445
}
366
446
 
367
447
Time
368
448
GHOST_SystemX11::
369
449
lastEventTime(Time default_time) {
370
 
    init_timestamp_data data;
371
 
    data.timestamp = default_time;
372
 
    XEvent ev;
373
 
    XCheckIfEvent(m_display, &ev, &init_timestamp_scanner, (XPointer)&data);
 
450
        init_timestamp_data data;
 
451
        data.timestamp = default_time;
 
452
        XEvent ev;
 
453
        XCheckIfEvent(m_display, &ev, &init_timestamp_scanner, (XPointer) & data);
374
454
 
375
 
    return data.timestamp;
 
455
        return data.timestamp;
376
456
}
377
457
 
378
 
        bool 
 
458
bool
379
459
GHOST_SystemX11::
380
460
processEvents(
381
 
        bool waitForEvent
382
 
){
383
 
        // Get all the current events -- translate them into 
384
 
        // ghost events and call base class pushEvent() method.
 
461
                bool waitForEvent)
 
462
{
 
463
        /* Get all the current events -- translate them into
 
464
         * ghost events and call base class pushEvent() method. */
385
465
        
386
466
        bool anyProcessed = false;
387
467
        
388
468
        do {
389
 
                GHOST_TimerManager* timerMgr = getTimerManager();
 
469
                GHOST_TimerManager *timerMgr = getTimerManager();
390
470
                
391
471
                if (waitForEvent && m_dirty_windows.empty() && !XPending(m_display)) {
392
472
                        GHOST_TUns64 next = timerMgr->nextFireTime();
393
473
                        
394
 
                        if (next==GHOST_kFireTimeNever) {
 
474
                        if (next == GHOST_kFireTimeNever) {
395
475
                                SleepTillEvent(m_display, -1);
396
 
                        } else {
 
476
                        }
 
477
                        else {
397
478
                                GHOST_TInt64 maxSleep = next - getMilliSeconds();
398
479
 
399
 
                                if(maxSleep >= 0)
 
480
                                if (maxSleep >= 0)
400
481
                                        SleepTillEvent(m_display, next - getMilliSeconds());
401
482
                        }
402
483
                }
408
489
                while (XPending(m_display)) {
409
490
                        XEvent xevent;
410
491
                        XNextEvent(m_display, &xevent);
 
492
 
 
493
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
 
494
                        /* open connection to XIM server and create input context (XIC)
 
495
                         * when receiving the first FocusIn or KeyPress event after startup,
 
496
                         * or recover XIM and XIC when the XIM server has been restarted */
 
497
                        if (xevent.type == FocusIn || xevent.type == KeyPress) {
 
498
                                if (!m_xim && openX11_IM()) {
 
499
                                        GHOST_PRINT("Connected to XIM server\n");
 
500
                                }
 
501
 
 
502
                                if (m_xim) {
 
503
                                        GHOST_WindowX11 * window = findGhostWindow(xevent.xany.window);
 
504
                                        if (window && !window->getX11_XIC() && window->createX11_XIC()) {
 
505
                                                GHOST_PRINT("XIM input context created\n");
 
506
                                                if (xevent.type == KeyPress)
 
507
                                                        /* we can assume the window has input focus
 
508
                                                         * here, because key events are received only
 
509
                                                         * when the window is focused. */
 
510
                                                        XSetICFocus(window->getX11_XIC());
 
511
                                        }
 
512
                                }
 
513
                        }
 
514
 
 
515
                        /* dispatch event to XIM server */
 
516
                        if ((XFilterEvent(&xevent, (Window)NULL) == True) && (xevent.type != KeyRelease)) {
 
517
                                /* do nothing now, the event is consumed by XIM.
 
518
                                 * however, KeyRelease event should be processed
 
519
                                 * here, otherwise modifiers remain activated.   */
 
520
                                continue;
 
521
                        }
 
522
#endif
 
523
 
411
524
                        processEvent(&xevent);
412
525
                        anyProcessed = true;
 
526
 
 
527
 
 
528
#ifdef USE_UNITY_WORKAROUND
 
529
                        /* note: processEvent() can't include this code because
 
530
                         * KeymapNotify event have no valid window information. */
 
531
 
 
532
                        /* the X server generates KeymapNotify event immediately after
 
533
                         * every EnterNotify and FocusIn event.  we handle this event
 
534
                         * to correct modifier states. */
 
535
                        if (xevent.type == FocusIn) {
 
536
                                /* use previous event's window, because KeymapNotify event
 
537
                                 * has no window information. */
 
538
                                GHOST_WindowX11 *window = findGhostWindow(xevent.xany.window);
 
539
                                if (window && XPending(m_display) >= 2) {
 
540
                                        XNextEvent(m_display, &xevent);
 
541
 
 
542
                                        if (xevent.type == KeymapNotify) {
 
543
                                                XEvent xev_next;
 
544
 
 
545
                                                /* check if KeyPress or KeyRelease event was generated
 
546
                                                 * in order to confirm the window is active. */
 
547
                                                XPeekEvent(m_display, &xev_next);
 
548
 
 
549
                                                if (xev_next.type == KeyPress || xev_next.type == KeyRelease) {
 
550
                                                        /* XK_Hyper_L/R currently unused */
 
551
                                                        const static KeySym modifiers[8] = {XK_Shift_L, XK_Shift_R,
 
552
                                                                                            XK_Control_L, XK_Control_R,
 
553
                                                                                            XK_Alt_L, XK_Alt_R,
 
554
                                                                                            XK_Super_L, XK_Super_R};
 
555
 
 
556
                                                        for (int i = 0; i < (sizeof(modifiers) / sizeof(*modifiers)); i++) {
 
557
                                                                KeyCode kc = XKeysymToKeycode(m_display, modifiers[i]);
 
558
                                                                if (((xevent.xkeymap.key_vector[kc >> 3] >> (kc & 7)) & 1) != 0) {
 
559
                                                                        pushEvent(new GHOST_EventKey(
 
560
                                                                                      getMilliSeconds(),
 
561
                                                                                      GHOST_kEventKeyDown,
 
562
                                                                                      window,
 
563
                                                                                      convertXKey(modifiers[i]),
 
564
                                                                                      '\0',
 
565
                                                                                      NULL));
 
566
                                                                }
 
567
                                                        }
 
568
                                                }
 
569
                                        }
 
570
                                }
 
571
                        }
 
572
#endif  /* USE_UNITY_WORKAROUND */
 
573
 
413
574
                }
414
575
                
415
576
                if (generateWindowExposeEvents()) {
417
578
                }
418
579
 
419
580
#ifdef WITH_INPUT_NDOF
420
 
                if (dynamic_cast<GHOST_NDOFManagerX11*>(m_ndofManager)->processEvents()) {
 
581
                if (dynamic_cast<GHOST_NDOFManagerX11 *>(m_ndofManager)->processEvents()) {
421
582
                        anyProcessed = true;
422
583
                }
423
584
#endif
430
591
 
431
592
#ifdef WITH_X11_XINPUT
432
593
/* set currently using tablet mode (stylus or eraser) depending on device ID */
433
 
static void setTabletMode(GHOST_WindowX11 * window, XID deviceid)
434
 
{
435
 
        if(deviceid == window->GetXTablet().StylusID)
436
 
                window->GetXTablet().CommonData.Active= GHOST_kTabletModeStylus;
437
 
        else if(deviceid == window->GetXTablet().EraserID)
438
 
                window->GetXTablet().CommonData.Active= GHOST_kTabletModeEraser;
439
 
}
440
 
#endif /* WITH_X11_XINPUT */
441
 
 
442
 
        void
 
594
static void setTabletMode(GHOST_SystemX11 *system, GHOST_WindowX11 *window, XID deviceid)
 
595
{
 
596
        if (deviceid == system->GetXTablet().StylusID)
 
597
                window->GetTabletData()->Active = GHOST_kTabletModeStylus;
 
598
        else if (deviceid == system->GetXTablet().EraserID)
 
599
                window->GetTabletData()->Active = GHOST_kTabletModeEraser;
 
600
}
 
601
#endif /* WITH_X11_XINPUT */
 
602
 
 
603
#ifdef WITH_X11_XINPUT
 
604
static bool checkTabletProximity(Display *display, XDevice *device)
 
605
{
 
606
        /* we could have true/false/not-found return value, but for now false is OK */
 
607
 
 
608
        /* see: state.c from xinput, to get more data out of the device */
 
609
        XDeviceState *state;
 
610
 
 
611
        if (device == NULL) {
 
612
                return false;
 
613
        }
 
614
 
 
615
        state = XQueryDeviceState(display, device);
 
616
 
 
617
        if (state) {
 
618
                XInputClass *cls = state->data;
 
619
                // printf("%d class%s :\n", state->num_classes,
 
620
                //       (state->num_classes > 1) ? "es" : "");
 
621
                for (int loop = 0; loop < state->num_classes; loop++) {
 
622
                        switch (cls->c_class) {
 
623
                                case ValuatorClass:
 
624
                                        XValuatorState *val_state = (XValuatorState *)cls;
 
625
                                        // printf("ValuatorClass Mode=%s Proximity=%s\n",
 
626
                                        //        val_state->mode & 1 ? "Absolute" : "Relative",
 
627
                                        //        val_state->mode & 2 ? "Out" : "In");
 
628
 
 
629
                                        if ((val_state->mode & 2) == 0) {
 
630
                                                XFreeDeviceState(state);
 
631
                                                return true;
 
632
                                        }
 
633
                                        break;
 
634
                        }
 
635
                        cls = (XInputClass *) ((char *)cls + cls->length);
 
636
                }
 
637
                XFreeDeviceState(state);
 
638
        }
 
639
        return false;
 
640
}
 
641
#endif /* WITH_X11_XINPUT */
 
642
 
 
643
void
443
644
GHOST_SystemX11::processEvent(XEvent *xe)
444
645
{
445
 
        GHOST_WindowX11 * window = findGhostWindow(xe->xany.window);    
446
 
        GHOST_Event * g_event = NULL;
 
646
        GHOST_WindowX11 *window = findGhostWindow(xe->xany.window);
 
647
        GHOST_Event *g_event = NULL;
447
648
 
448
649
        if (!window) {
449
650
                return;
450
651
        }
451
 
        
 
652
 
 
653
#ifdef WITH_X11_XINPUT
 
654
        /* Proximity-Out Events are not reliable, if the tablet is active - check on each event
 
655
         * this adds a little overhead but only while the tablet is in use.
 
656
         * in the futire we could have a ghost call window->CheckTabletProximity()
 
657
         * but for now enough parts of the code are checking 'Active'
 
658
         * - campbell */
 
659
        if (window->GetTabletData()->Active != GHOST_kTabletModeNone) {
 
660
                if (checkTabletProximity(xe->xany.display, m_xtablet.StylusDevice) == false &&
 
661
                    checkTabletProximity(xe->xany.display, m_xtablet.EraserDevice) == false)
 
662
                {
 
663
                        // printf("proximity disable\n");
 
664
                        window->GetTabletData()->Active = GHOST_kTabletModeNone;
 
665
                }
 
666
        }
 
667
#endif /* WITH_X11_XINPUT */
 
668
 
452
669
        switch (xe->type) {
453
670
                case Expose:
454
671
                {
455
672
                        XExposeEvent & xee = xe->xexpose;
456
673
 
457
674
                        if (xee.count == 0) {
458
 
                                // Only generate a single expose event
459
 
                                // per read of the event queue.
 
675
                                /* Only generate a single expose event
 
676
                                 * per read of the event queue. */
460
677
 
461
678
                                g_event = new
462
 
                                GHOST_Event(
463
 
                                        getMilliSeconds(),
464
 
                                        GHOST_kEventWindowUpdate,
465
 
                                        window
466
 
                                );
 
679
                                          GHOST_Event(
 
680
                                    getMilliSeconds(),
 
681
                                    GHOST_kEventWindowUpdate,
 
682
                                    window
 
683
                                    );
467
684
                        }
468
685
                        break;
469
686
                }
471
688
                case MotionNotify:
472
689
                {
473
690
                        XMotionEvent &xme = xe->xmotion;
474
 
                        
475
 
                        if(window->getCursorGrabMode() != GHOST_kGrabDisable && window->getCursorGrabMode() != GHOST_kGrabNormal)
476
 
                        {
477
 
                                GHOST_TInt32 x_new= xme.x_root;
478
 
                                GHOST_TInt32 y_new= xme.y_root;
 
691
 
 
692
#ifdef WITH_X11_XINPUT
 
693
                        bool is_tablet = window->GetTabletData()->Active != GHOST_kTabletModeNone;
 
694
#else
 
695
                        bool is_tablet = false;
 
696
#endif
 
697
 
 
698
                        if (is_tablet == false && window->getCursorGrabModeIsWarp()) {
 
699
                                GHOST_TInt32 x_new = xme.x_root;
 
700
                                GHOST_TInt32 y_new = xme.y_root;
479
701
                                GHOST_TInt32 x_accum, y_accum;
480
702
                                GHOST_Rect bounds;
481
703
 
482
704
                                /* fallback to window bounds */
483
 
                                if(window->getCursorGrabBounds(bounds)==GHOST_kFailure)
 
705
                                if (window->getCursorGrabBounds(bounds) == GHOST_kFailure)
484
706
                                        window->getClientBounds(bounds);
485
707
 
486
708
                                /* could also clamp to screen bounds
488
710
                                bounds.wrapPoint(x_new, y_new, 8); /* offset of one incase blender is at screen bounds */
489
711
                                window->getCursorGrabAccum(x_accum, y_accum);
490
712
 
491
 
                                if(x_new != xme.x_root || y_new != xme.y_root) {
 
713
                                if (x_new != xme.x_root || y_new != xme.y_root) {
492
714
                                        if (xme.time > m_last_warp) {
493
715
                                                /* when wrapping we don't need to add an event because the
494
716
                                                 * setCursorPosition call will cause a new event after */
495
717
                                                setCursorPosition(x_new, y_new); /* wrap */
496
718
                                                window->setCursorGrabAccum(x_accum + (xme.x_root - x_new), y_accum + (xme.y_root - y_new));
497
719
                                                m_last_warp = lastEventTime(xme.time);
498
 
                                        } else {
 
720
                                        }
 
721
                                        else {
499
722
                                                setCursorPosition(x_new, y_new); /* wrap but don't accumulate */
500
723
                                        }
501
724
                                }
502
725
                                else {
503
726
                                        g_event = new
504
 
                                        GHOST_EventCursor(
505
 
                                                getMilliSeconds(),
506
 
                                                GHOST_kEventCursorMove,
507
 
                                                window,
508
 
                                                xme.x_root + x_accum,
509
 
                                                xme.y_root + y_accum
510
 
                                        );
 
727
                                                  GHOST_EventCursor(
 
728
                                            getMilliSeconds(),
 
729
                                            GHOST_kEventCursorMove,
 
730
                                            window,
 
731
                                            xme.x_root + x_accum,
 
732
                                            xme.y_root + y_accum
 
733
                                            );
511
734
                                }
512
735
                        }
513
736
                        else {
514
737
                                g_event = new
515
 
                                GHOST_EventCursor(
516
 
                                        getMilliSeconds(),
517
 
                                        GHOST_kEventCursorMove,
518
 
                                        window,
519
 
                                        xme.x_root,
520
 
                                        xme.y_root
521
 
                                );
 
738
                                          GHOST_EventCursor(
 
739
                                    getMilliSeconds(),
 
740
                                    GHOST_kEventCursorMove,
 
741
                                    window,
 
742
                                    xme.x_root,
 
743
                                    xme.y_root
 
744
                                    );
522
745
                        }
523
746
                        break;
524
747
                }
527
750
                case KeyRelease:
528
751
                {
529
752
                        XKeyEvent *xke = &(xe->xkey);
530
 
                        KeySym key_sym = XLookupKeysym(xke,0);
 
753
                        KeySym key_sym = XLookupKeysym(xke, 0);
531
754
                        char ascii;
532
 
                        char utf8_buf[6]; /* 6 is enough for a utf8 char */
 
755
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
 
756
                        /* utf8_array[] is initial buffer used for Xutf8LookupString().
 
757
                         * if the length of the utf8 string exceeds this array, allocate
 
758
                         * another memory area and call Xutf8LookupString() again.
 
759
                         * the last 5 bytes are used to avoid segfault that might happen
 
760
                         * at the end of this buffer when the constructor of GHOST_EventKey
 
761
                         * reads 6 bytes regardless of the effective data length. */
 
762
                        char utf8_array[16 * 6 + 5]; /* 16 utf8 characters */
 
763
                        char *utf8_buf = utf8_array;
 
764
                        int len = 1; /* at least one null character will be stored */
 
765
#else
 
766
                        char *utf8_buf = NULL;
 
767
#endif
533
768
                        
534
769
                        GHOST_TKey gkey = convertXKey(key_sym);
535
770
                        GHOST_TEventType type = (xke->type == KeyPress) ? 
536
 
                                GHOST_kEventKeyDown : GHOST_kEventKeyUp;
 
771
                                                GHOST_kEventKeyDown : GHOST_kEventKeyUp;
537
772
                        
538
773
                        if (!XLookupString(xke, &ascii, 1, NULL, NULL)) {
539
774
                                ascii = '\0';
541
776
                        
542
777
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
543
778
                        /* getting unicode on key-up events gives XLookupNone status */
544
 
                        if (xke->type == KeyPress) {
 
779
                        XIC xic = window->getX11_XIC();
 
780
                        if (xic && xke->type == KeyPress) {
545
781
                                Status status;
546
 
                                int len;
547
782
 
548
783
                                /* use utf8 because its not locale depentant, from xorg docs */
549
 
                                if (!(len= Xutf8LookupString(window->getX11_XIC(), xke, utf8_buf, sizeof(utf8_buf), &key_sym, &status))) {
550
 
                                        utf8_buf[0]= '\0';
 
784
                                if (!(len = Xutf8LookupString(xic, xke, utf8_buf, sizeof(utf8_array) - 5, &key_sym, &status))) {
 
785
                                        utf8_buf[0] = '\0';
 
786
                                }
 
787
 
 
788
                                if (status == XBufferOverflow) {
 
789
                                        utf8_buf = (char *) malloc(len + 5);
 
790
                                        len = Xutf8LookupString(xic, xke, utf8_buf, len, &key_sym, &status);
551
791
                                }
552
792
 
553
793
                                if ((status == XLookupChars || status == XLookupBoth)) {
555
795
                                                /* do nothing for now, this is valid utf8 */
556
796
                                        }
557
797
                                        else {
558
 
                                                utf8_buf[0]= '\0';
 
798
                                                utf8_buf[0] = '\0';
559
799
                                        }
560
800
                                }
561
801
                                else if (status == XLookupKeySym) {
562
802
                                        /* this key doesn't have a text representation, it is a command
563
 
                                           key of some sort */;
 
803
                                         * key of some sort */;
564
804
                                }
565
805
                                else {
566
806
                                        printf("Bad keycode lookup. Keysym 0x%x Status: %s\n",
567
 
                                                          (unsigned int) key_sym,
568
 
                                                          (status == XBufferOverflow ? "BufferOverflow" :
569
 
                                                           status == XLookupNone ? "XLookupNone" :
570
 
                                                           status == XLookupKeySym ? "XLookupKeySym" :
571
 
                                                           "Unknown status"));
 
807
                                               (unsigned int) key_sym,
 
808
                                               (status == XLookupNone ? "XLookupNone" :
 
809
                                                status == XLookupKeySym ? "XLookupKeySym" :
 
810
                                                "Unknown status"));
572
811
 
573
 
                                        printf("'%.*s' %p %p\n", len, utf8_buf, window->getX11_XIC(), m_xim);
 
812
                                        printf("'%.*s' %p %p\n", len, utf8_buf, xic, m_xim);
574
813
                                }
575
814
                        }
576
815
                        else {
577
 
                                utf8_buf[0]= '\0';
 
816
                                utf8_buf[0] = '\0';
578
817
                        }
579
 
#else
580
 
                        utf8_buf[0]= '\0';
581
818
#endif
582
819
 
583
820
                        g_event = new
584
 
                        GHOST_EventKey(
585
 
                                getMilliSeconds(),
586
 
                                type,
587
 
                                window,
588
 
                                gkey,
589
 
                                ascii,
 
821
                                  GHOST_EventKey(
 
822
                            getMilliSeconds(),
 
823
                            type,
 
824
                            window,
 
825
                            gkey,
 
826
                            ascii,
590
827
                            utf8_buf
591
 
                        );
 
828
                            );
 
829
 
 
830
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
 
831
                        /* when using IM for some languages such as Japanese,
 
832
                         * one event inserts multiple utf8 characters */
 
833
                        if (xic && xke->type == KeyPress) {
 
834
                                unsigned char c;
 
835
                                int i = 0;
 
836
                                while (1) {
 
837
                                        /* search character boundary */
 
838
                                        if ((unsigned char)utf8_buf[i++] > 0x7f) {
 
839
                                                for (; i < len; ++i) {
 
840
                                                        c = utf8_buf[i];
 
841
                                                        if (c < 0x80 || c > 0xbf) break;
 
842
                                                }
 
843
                                        }
 
844
 
 
845
                                        if (i >= len) break;
 
846
 
 
847
                                        /* enqueue previous character */
 
848
                                        pushEvent(g_event);
 
849
 
 
850
                                        g_event = new
 
851
                                                  GHOST_EventKey(
 
852
                                            getMilliSeconds(),
 
853
                                            type,
 
854
                                            window,
 
855
                                            gkey,
 
856
                                            '\0',
 
857
                                            &utf8_buf[i]
 
858
                                            );
 
859
                                }
 
860
                        }
 
861
 
 
862
                        if (utf8_buf != utf8_array)
 
863
                                free(utf8_buf);
 
864
#endif
592
865
                        
593
 
                break;
 
866
                        break;
594
867
                }
595
868
 
596
869
                case ButtonPress:
599
872
                        XButtonEvent & xbe = xe->xbutton;
600
873
                        GHOST_TButtonMask gbmask = GHOST_kButtonMaskLeft;
601
874
                        GHOST_TEventType type = (xbe.type == ButtonPress) ? 
602
 
                                GHOST_kEventButtonDown : GHOST_kEventButtonUp;
 
875
                                                GHOST_kEventButtonDown : GHOST_kEventButtonUp;
603
876
 
604
877
                        /* process wheel mouse events and break, only pass on press events */
605
 
                        if(xbe.button == Button4) {
606
 
                                if(xbe.type == ButtonPress)
 
878
                        if (xbe.button == Button4) {
 
879
                                if (xbe.type == ButtonPress)
607
880
                                        g_event = new GHOST_EventWheel(getMilliSeconds(), window, 1);
608
881
                                break;
609
882
                        }
610
 
                        else if(xbe.button == Button5) {
611
 
                                if(xbe.type == ButtonPress)
 
883
                        else if (xbe.button == Button5) {
 
884
                                if (xbe.type == ButtonPress)
612
885
                                        g_event = new GHOST_EventWheel(getMilliSeconds(), window, -1);
613
886
                                break;
614
887
                        }
615
888
                        
616
889
                        /* process rest of normal mouse buttons */
617
 
                        if(xbe.button == Button1)
 
890
                        if (xbe.button == Button1)
618
891
                                gbmask = GHOST_kButtonMaskLeft;
619
 
                        else if(xbe.button == Button2)
 
892
                        else if (xbe.button == Button2)
620
893
                                gbmask = GHOST_kButtonMaskMiddle;
621
 
                        else if(xbe.button == Button3)
 
894
                        else if (xbe.button == Button3)
622
895
                                gbmask = GHOST_kButtonMaskRight;
623
896
                        /* It seems events 6 and 7 are for horizontal scrolling.
624
 
                        * you can re-order button mapping like this... (swaps 6,7 with 8,9)
625
 
                        *   xmodmap -e "pointer = 1 2 3 4 5 8 9 6 7" 
626
 
                        */
627
 
                        else if(xbe.button == 8)
 
897
                         * you can re-order button mapping like this... (swaps 6,7 with 8,9)
 
898
                         *   xmodmap -e "pointer = 1 2 3 4 5 8 9 6 7"
 
899
                         */
 
900
                        else if (xbe.button == 8)
628
901
                                gbmask = GHOST_kButtonMaskButton4;
629
 
                        else if(xbe.button == 9)
 
902
                        else if (xbe.button == 9)
630
903
                                gbmask = GHOST_kButtonMaskButton5;
631
904
                        else
632
905
                                break;
633
906
 
634
907
                        g_event = new
635
 
                        GHOST_EventButton(
636
 
                                getMilliSeconds(),
637
 
                                type,
638
 
                                window,
639
 
                                gbmask
640
 
                        );
 
908
                                  GHOST_EventButton(
 
909
                            getMilliSeconds(),
 
910
                            type,
 
911
                            window,
 
912
                            gbmask
 
913
                            );
641
914
                        break;
642
915
                }
643
916
                        
644
 
                        // change of size, border, layer etc.
 
917
                /* change of size, border, layer etc. */
645
918
                case ConfigureNotify:
646
919
                {
647
920
                        /* XConfigureEvent & xce = xe->xconfigure; */
648
921
 
649
922
                        g_event = new 
650
 
                        GHOST_Event(
651
 
                                getMilliSeconds(),
652
 
                                GHOST_kEventWindowSize,
653
 
                                window
654
 
                        );                      
 
923
                                  GHOST_Event(
 
924
                            getMilliSeconds(),
 
925
                            GHOST_kEventWindowSize,
 
926
                            window
 
927
                            );
655
928
                        break;
656
929
                }
657
930
 
660
933
                {
661
934
                        XFocusChangeEvent &xfe = xe->xfocus;
662
935
 
663
 
                        // TODO: make sure this is the correct place for activate/deactivate
 
936
                        /* TODO: make sure this is the correct place for activate/deactivate */
664
937
                        // printf("X: focus %s for window %d\n", xfe.type == FocusIn ? "in" : "out", (int) xfe.window);
665
938
                
666
 
                        // May have to look at the type of event and filter some
667
 
                        // out.
668
 
                                                                        
 
939
                        /* May have to look at the type of event and filter some out. */
 
940
 
669
941
                        GHOST_TEventType gtype = (xfe.type == FocusIn) ? 
670
 
                                GHOST_kEventWindowActivate : GHOST_kEventWindowDeactivate;
 
942
                                                 GHOST_kEventWindowActivate : GHOST_kEventWindowDeactivate;
 
943
 
 
944
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
 
945
                        XIC xic = window->getX11_XIC();
 
946
                        if (xic) {
 
947
                                if (xe->type == FocusIn)
 
948
                                        XSetICFocus(xic);
 
949
                                else
 
950
                                        XUnsetICFocus(xic);
 
951
                        }
 
952
#endif
671
953
 
672
954
                        g_event = new 
673
 
                        GHOST_Event(    
674
 
                                getMilliSeconds(),
675
 
                                gtype,
676
 
                                window
677
 
                        );
 
955
                                  GHOST_Event(
 
956
                            getMilliSeconds(),
 
957
                            gtype,
 
958
                            window
 
959
                            );
678
960
                        break;
679
961
 
680
962
                }
682
964
                {
683
965
                        XClientMessageEvent & xcme = xe->xclient;
684
966
 
685
 
                        if (((Atom)xcme.data.l[0]) == m_delete_window_atom) {
 
967
                        if (((Atom)xcme.data.l[0]) == m_atom.WM_DELETE_WINDOW) {
686
968
                                g_event = new 
687
 
                                GHOST_Event(    
688
 
                                        getMilliSeconds(),
689
 
                                        GHOST_kEventWindowClose,
690
 
                                        window
691
 
                                );
 
969
                                          GHOST_Event(
 
970
                                    getMilliSeconds(),
 
971
                                    GHOST_kEventWindowClose,
 
972
                                    window
 
973
                                    );
692
974
                        }
693
 
                        else if (((Atom)xcme.data.l[0]) == m_wm_take_focus) {
 
975
                        else if (((Atom)xcme.data.l[0]) == m_atom.WM_TAKE_FOCUS) {
694
976
                                XWindowAttributes attr;
695
977
                                Window fwin;
696
978
                                int revert_to;
713
995
                                                }
714
996
                                        }
715
997
                                }
716
 
                        } else {
 
998
                        }
 
999
                        else {
717
1000
#ifdef WITH_XDND
718
1001
                                /* try to handle drag event (if there's no such events, GHOST_HandleClientMessage will return zero) */
719
1002
                                if (window->getDropTarget()->GHOST_HandleClientMessage(xe) == false) {
728
1011
                }
729
1012
                
730
1013
                case DestroyNotify:
731
 
                        ::exit(-1);     
732
 
                // We're not interested in the following things.(yet...)
733
 
                case NoExpose : 
734
 
                case GraphicsExpose :
 
1014
                        ::exit(-1);
 
1015
                /* We're not interested in the following things.(yet...) */
 
1016
                case NoExpose:
 
1017
                case GraphicsExpose:
735
1018
                        break;
736
1019
                
737
1020
                case EnterNotify:
738
1021
                case LeaveNotify:
739
1022
                {
740
1023
                        /* XCrossingEvents pointer leave enter window.
741
 
                           also do cursor move here, MotionNotify only
742
 
                           happens when motion starts & ends inside window.
743
 
                           we only do moves when the crossing mode is 'normal'
744
 
                           (really crossing between windows) since some windowmanagers
745
 
                           also send grab/ungrab crossings for mousewheel events.
746
 
                        */
 
1024
                         * also do cursor move here, MotionNotify only
 
1025
                         * happens when motion starts & ends inside window.
 
1026
                         * we only do moves when the crossing mode is 'normal'
 
1027
                         * (really crossing between windows) since some windowmanagers
 
1028
                         * also send grab/ungrab crossings for mousewheel events.
 
1029
                         */
747
1030
                        XCrossingEvent &xce = xe->xcrossing;
748
 
                        if( xce.mode == NotifyNormal ) {
 
1031
                        if (xce.mode == NotifyNormal) {
749
1032
                                g_event = new 
750
 
                                GHOST_EventCursor(
751
 
                                        getMilliSeconds(),
752
 
                                        GHOST_kEventCursorMove,
753
 
                                        window,
754
 
                                        xce.x_root,
755
 
                                        xce.y_root
756
 
                                );
 
1033
                                          GHOST_EventCursor(
 
1034
                                    getMilliSeconds(),
 
1035
                                    GHOST_kEventCursorMove,
 
1036
                                    window,
 
1037
                                    xce.x_root,
 
1038
                                    xce.y_root
 
1039
                                    );
757
1040
                        }
758
1041
 
759
1042
                        // printf("X: %s window %d\n", xce.type == EnterNotify ? "entering" : "leaving", (int) xce.window);
780
1063
                                 * Now we are sure that the window is
781
1064
                                 * mapped, so only need change the state.
782
1065
                                 */
783
 
                                window->setState (window->m_post_state);
 
1066
                                window->setState(window->m_post_state);
784
1067
                                window->m_post_init = False;
785
1068
                        }
786
1069
                        break;
814
1097
                        nxe.xselection.target = xse->target;
815
1098
                        nxe.xselection.time = xse->time;
816
1099
                        
817
 
                        /*Check to see if the requestor is asking for String*/
818
 
                        if(xse->target == utf8_string || xse->target == string || xse->target == compound_text || xse->target == c_string) {
 
1100
                        /* Check to see if the requestor is asking for String */
 
1101
                        if (xse->target == utf8_string ||
 
1102
                            xse->target == string ||
 
1103
                            xse->target == compound_text ||
 
1104
                            xse->target == c_string)
 
1105
                        {
819
1106
                                if (xse->selection == XInternAtom(m_display, "PRIMARY", False)) {
820
1107
                                        XChangeProperty(m_display, xse->requestor, xse->property, xse->target, 8, PropModeReplace,
821
 
                                                        (unsigned char*)txt_select_buffer, strlen(txt_select_buffer));
822
 
                                } else if (xse->selection == XInternAtom(m_display, "CLIPBOARD", False)) {
 
1108
                                                        (unsigned char *)txt_select_buffer, strlen(txt_select_buffer));
 
1109
                                }
 
1110
                                else if (xse->selection == XInternAtom(m_display, "CLIPBOARD", False)) {
823
1111
                                        XChangeProperty(m_display, xse->requestor, xse->property, xse->target, 8, PropModeReplace,
824
 
                                                        (unsigned char*)txt_cut_buffer, strlen(txt_cut_buffer));
 
1112
                                                        (unsigned char *)txt_cut_buffer, strlen(txt_cut_buffer));
825
1113
                                }
826
 
                        } else if (xse->target == target) {
 
1114
                        }
 
1115
                        else if (xse->target == target) {
827
1116
                                Atom alist[5];
828
1117
                                alist[0] = target;
829
1118
                                alist[1] = utf8_string;
831
1120
                                alist[3] = compound_text;
832
1121
                                alist[4] = c_string;
833
1122
                                XChangeProperty(m_display, xse->requestor, xse->property, xse->target, 32, PropModeReplace,
834
 
                                                (unsigned char*)alist, 5);
 
1123
                                                (unsigned char *)alist, 5);
835
1124
                                XFlush(m_display);
836
 
                        } else  {
837
 
                                //Change property to None because we do not support anything but STRING
 
1125
                        }
 
1126
                        else {
 
1127
                                /* Change property to None because we do not support anything but STRING */
838
1128
                                nxe.xselection.property = None;
839
1129
                        }
840
1130
                        
841
 
                        //Send the event to the client 0 0 == False, SelectionNotify
 
1131
                        /* Send the event to the client 0 0 == False, SelectionNotify */
842
1132
                        XSendEvent(m_display, xse->requestor, 0, 0, &nxe);
843
1133
                        XFlush(m_display);
844
1134
                        break;
846
1136
                
847
1137
                default: {
848
1138
#ifdef WITH_X11_XINPUT
849
 
                        if(xe->type == window->GetXTablet().MotionEvent) 
850
 
                        {
851
 
                                XDeviceMotionEvent* data = (XDeviceMotionEvent*)xe;
 
1139
                        if (xe->type == m_xtablet.MotionEvent) {
 
1140
                                XDeviceMotionEvent *data = (XDeviceMotionEvent *)xe;
852
1141
 
853
1142
                                /* stroke might begin without leading ProxyIn event,
854
1143
                                 * this happens when window is opened when stylus is already hovering
855
1144
                                 * around tablet surface */
856
 
                                setTabletMode(window, data->deviceid);
857
 
 
858
 
                                window->GetXTablet().CommonData.Pressure= 
859
 
                                        data->axis_data[2]/((float)window->GetXTablet().PressureLevels);
860
 
                        
861
 
                        /* the (short) cast and the &0xffff is bizarre and unexplained anywhere,
862
 
                         * but I got garbage data without it. Found it in the xidump.c source --matt */
863
 
                                window->GetXTablet().CommonData.Xtilt= 
864
 
                                        (short)(data->axis_data[3]&0xffff)/((float)window->GetXTablet().XtiltLevels);
865
 
                                window->GetXTablet().CommonData.Ytilt= 
866
 
                                        (short)(data->axis_data[4]&0xffff)/((float)window->GetXTablet().YtiltLevels);
867
 
                        }
868
 
                        else if(xe->type == window->GetXTablet().ProxInEvent) 
869
 
                        {
870
 
                                XProximityNotifyEvent* data = (XProximityNotifyEvent*)xe;
871
 
 
872
 
                                setTabletMode(window, data->deviceid);
873
 
                        }
874
 
                        else if(xe->type == window->GetXTablet().ProxOutEvent)
875
 
                                window->GetXTablet().CommonData.Active= GHOST_kTabletModeNone;
 
1145
                                setTabletMode(this, window, data->deviceid);
 
1146
 
 
1147
                                window->GetTabletData()->Pressure =
 
1148
                                        data->axis_data[2] / ((float)m_xtablet.PressureLevels);
 
1149
 
 
1150
                                /* the (short) cast and the &0xffff is bizarre and unexplained anywhere,
 
1151
                                 * but I got garbage data without it. Found it in the xidump.c source --matt */
 
1152
                                window->GetTabletData()->Xtilt =
 
1153
                                        (short)(data->axis_data[3] & 0xffff) / ((float)m_xtablet.XtiltLevels);
 
1154
                                window->GetTabletData()->Ytilt =
 
1155
                                        (short)(data->axis_data[4] & 0xffff) / ((float)m_xtablet.YtiltLevels);
 
1156
                        }
 
1157
                        else if (xe->type == m_xtablet.ProxInEvent) {
 
1158
                                XProximityNotifyEvent *data = (XProximityNotifyEvent *)xe;
 
1159
 
 
1160
                                setTabletMode(this, window, data->deviceid);
 
1161
                        }
 
1162
                        else if (xe->type == m_xtablet.ProxOutEvent) {
 
1163
                                window->GetTabletData()->Active = GHOST_kTabletModeNone;
 
1164
                        }
876
1165
#endif // WITH_X11_XINPUT
877
1166
                        break;
878
1167
                }
883
1172
        }
884
1173
}
885
1174
 
886
 
        GHOST_TSuccess 
 
1175
GHOST_TSuccess
887
1176
GHOST_SystemX11::
888
1177
getModifierKeys(
889
 
        GHOST_ModifierKeys& keys
890
 
) const {
891
 
 
892
 
        // analyse the masks retuned from XQueryPointer.
893
 
 
894
 
        memset((void *)m_keyboard_vector,0,sizeof(m_keyboard_vector));
895
 
 
896
 
        XQueryKeymap(m_display,(char *)m_keyboard_vector);
897
 
 
898
 
        // now translate key symobols into keycodes and
899
 
        // test with vector.
900
 
 
901
 
        const static KeyCode shift_l = XKeysymToKeycode(m_display,XK_Shift_L);
902
 
        const static KeyCode shift_r = XKeysymToKeycode(m_display,XK_Shift_R);
903
 
        const static KeyCode control_l = XKeysymToKeycode(m_display,XK_Control_L);
904
 
        const static KeyCode control_r = XKeysymToKeycode(m_display,XK_Control_R);
905
 
        const static KeyCode alt_l = XKeysymToKeycode(m_display,XK_Alt_L);
906
 
        const static KeyCode alt_r = XKeysymToKeycode(m_display,XK_Alt_R);
907
 
        const static KeyCode super_l = XKeysymToKeycode(m_display,XK_Super_L);
908
 
        const static KeyCode super_r = XKeysymToKeycode(m_display,XK_Super_R);
909
 
 
910
 
        // shift
 
1178
                GHOST_ModifierKeys& keys) const
 
1179
{
 
1180
 
 
1181
        /* analyse the masks retuned from XQueryPointer. */
 
1182
 
 
1183
        memset((void *)m_keyboard_vector, 0, sizeof(m_keyboard_vector));
 
1184
 
 
1185
        XQueryKeymap(m_display, (char *)m_keyboard_vector);
 
1186
 
 
1187
        /* now translate key symobols into keycodes and
 
1188
         * test with vector. */
 
1189
 
 
1190
        const static KeyCode shift_l = XKeysymToKeycode(m_display, XK_Shift_L);
 
1191
        const static KeyCode shift_r = XKeysymToKeycode(m_display, XK_Shift_R);
 
1192
        const static KeyCode control_l = XKeysymToKeycode(m_display, XK_Control_L);
 
1193
        const static KeyCode control_r = XKeysymToKeycode(m_display, XK_Control_R);
 
1194
        const static KeyCode alt_l = XKeysymToKeycode(m_display, XK_Alt_L);
 
1195
        const static KeyCode alt_r = XKeysymToKeycode(m_display, XK_Alt_R);
 
1196
        const static KeyCode super_l = XKeysymToKeycode(m_display, XK_Super_L);
 
1197
        const static KeyCode super_r = XKeysymToKeycode(m_display, XK_Super_R);
 
1198
 
 
1199
        /* shift */
911
1200
        keys.set(GHOST_kModifierKeyLeftShift, ((m_keyboard_vector[shift_l >> 3] >> (shift_l & 7)) & 1) != 0);
912
1201
        keys.set(GHOST_kModifierKeyRightShift, ((m_keyboard_vector[shift_r >> 3] >> (shift_r & 7)) & 1) != 0);
913
 
        // control
 
1202
        /* control */
914
1203
        keys.set(GHOST_kModifierKeyLeftControl, ((m_keyboard_vector[control_l >> 3] >> (control_l & 7)) & 1) != 0);
915
1204
        keys.set(GHOST_kModifierKeyRightControl, ((m_keyboard_vector[control_r >> 3] >> (control_r & 7)) & 1) != 0);
916
 
        // alt
 
1205
        /* alt */
917
1206
        keys.set(GHOST_kModifierKeyLeftAlt, ((m_keyboard_vector[alt_l >> 3] >> (alt_l & 7)) & 1) != 0);
918
1207
        keys.set(GHOST_kModifierKeyRightAlt, ((m_keyboard_vector[alt_r >> 3] >> (alt_r & 7)) & 1) != 0);
919
 
        // super (windows) - only one GHOST-kModifierKeyOS, so mapping to either
 
1208
        /* super (windows) - only one GHOST-kModifierKeyOS, so mapping to either */
920
1209
        keys.set(GHOST_kModifierKeyOS, ( ((m_keyboard_vector[super_l >> 3] >> (super_l & 7)) & 1) ||
921
1210
                                         ((m_keyboard_vector[super_r >> 3] >> (super_r & 7)) & 1) ) != 0);
922
1211
 
923
1212
        return GHOST_kSuccess;
924
1213
}
925
1214
 
926
 
        GHOST_TSuccess 
 
1215
GHOST_TSuccess
927
1216
GHOST_SystemX11::
928
1217
getButtons(
929
 
        GHOST_Buttons& buttons
930
 
) const {
931
 
 
 
1218
                GHOST_Buttons& buttons) const
 
1219
{
932
1220
        Window root_return, child_return;
933
 
        int rx,ry,wx,wy;
 
1221
        int rx, ry, wx, wy;
934
1222
        unsigned int mask_return;
935
1223
 
936
1224
        if (XQueryPointer(m_display,
937
 
                          RootWindow(m_display,DefaultScreen(m_display)),
 
1225
                          RootWindow(m_display, DefaultScreen(m_display)),
938
1226
                          &root_return,
939
1227
                          &child_return,
940
 
                          &rx,&ry,
941
 
                          &wx,&wy,
 
1228
                          &rx, &ry,
 
1229
                          &wx, &wy,
942
1230
                          &mask_return) == True)
943
1231
        {
944
1232
                buttons.set(GHOST_kButtonMaskLeft,   (mask_return & Button1Mask) != 0);
953
1241
}
954
1242
 
955
1243
 
956
 
        GHOST_TSuccess 
 
1244
GHOST_TSuccess
957
1245
GHOST_SystemX11::
958
1246
getCursorPosition(
959
 
        GHOST_TInt32& x,
960
 
        GHOST_TInt32& y
961
 
) const {
 
1247
                GHOST_TInt32& x,
 
1248
                GHOST_TInt32& y) const
 
1249
{
962
1250
 
963
1251
        Window root_return, child_return;
964
 
        int rx,ry,wx,wy;
 
1252
        int rx, ry, wx, wy;
965
1253
        unsigned int mask_return;
966
1254
 
967
1255
        if (XQueryPointer(
968
 
                m_display,
969
 
                RootWindow(m_display,DefaultScreen(m_display)),
970
 
                &root_return,
971
 
                &child_return,
972
 
                &rx,&ry,
973
 
                &wx,&wy,
974
 
                &mask_return
975
 
        ) == False) {
 
1256
                m_display,
 
1257
                RootWindow(m_display, DefaultScreen(m_display)),
 
1258
                &root_return,
 
1259
                &child_return,
 
1260
                &rx, &ry,
 
1261
                &wx, &wy,
 
1262
                &mask_return
 
1263
                ) == False) {
976
1264
                return GHOST_kFailure;
977
 
        } else {
 
1265
        }
 
1266
        else {
978
1267
                x = rx;
979
1268
                y = ry;
980
1269
        }       
982
1271
}
983
1272
 
984
1273
 
985
 
        GHOST_TSuccess 
 
1274
GHOST_TSuccess
986
1275
GHOST_SystemX11::
987
1276
setCursorPosition(
988
 
        GHOST_TInt32 x,
989
 
        GHOST_TInt32 y
990
 
) {
991
 
 
992
 
        // This is a brute force move in screen coordinates
993
 
        // XWarpPointer does relative moves so first determine the
994
 
        // current pointer position.
995
 
 
996
 
        int cx,cy;
997
 
        if (getCursorPosition(cx,cy) == GHOST_kFailure) {
 
1277
                GHOST_TInt32 x,
 
1278
                GHOST_TInt32 y
 
1279
        ) {
 
1280
 
 
1281
        /* This is a brute force move in screen coordinates
 
1282
         * XWarpPointer does relative moves so first determine the
 
1283
         * current pointer position. */
 
1284
 
 
1285
        int cx, cy;
 
1286
        if (getCursorPosition(cx, cy) == GHOST_kFailure) {
998
1287
                return GHOST_kFailure;
999
1288
        }
1000
1289
 
1001
 
        int relx = x-cx;
1002
 
        int rely = y-cy;
 
1290
        int relx = x - cx;
 
1291
        int rely = y - cy;
1003
1292
 
1004
 
        XWarpPointer(m_display,None,None,0,0,0,0,relx,rely);
 
1293
        XWarpPointer(m_display, None, None, 0, 0, 0, 0, relx, rely);
1005
1294
        XSync(m_display, 0); /* Sync to process all requests */
1006
1295
        
1007
1296
        return GHOST_kSuccess;
1008
1297
}
1009
1298
 
1010
1299
 
1011
 
        void
 
1300
void
1012
1301
GHOST_SystemX11::
1013
1302
addDirtyWindow(
1014
 
        GHOST_WindowX11 * bad_wind
1015
 
){
1016
 
 
 
1303
                GHOST_WindowX11 *bad_wind)
 
1304
{
1017
1305
        GHOST_ASSERT((bad_wind != NULL), "addDirtyWindow() NULL ptr trapped (window)");
1018
1306
        
1019
1307
        m_dirty_windows.push_back(bad_wind);
1020
1308
}
1021
1309
 
1022
1310
 
1023
 
        bool
 
1311
bool
1024
1312
GHOST_SystemX11::
1025
 
generateWindowExposeEvents(
1026
 
){
1027
 
 
 
1313
generateWindowExposeEvents()
 
1314
{
1028
1315
        vector<GHOST_WindowX11 *>::iterator w_start = m_dirty_windows.begin();
1029
1316
        vector<GHOST_WindowX11 *>::const_iterator w_end = m_dirty_windows.end();
1030
1317
        bool anyProcessed = false;
1031
1318
        
1032
 
        for (;w_start != w_end; ++w_start) {
1033
 
                GHOST_Event * g_event = new 
1034
 
                        GHOST_Event(
1035
 
                                getMilliSeconds(),
1036
 
                                GHOST_kEventWindowUpdate,
1037
 
                                *w_start
1038
 
                        );                      
 
1319
        for (; w_start != w_end; ++w_start) {
 
1320
                GHOST_Event *g_event = new
 
1321
                                       GHOST_Event(
 
1322
                    getMilliSeconds(),
 
1323
                    GHOST_kEventWindowUpdate,
 
1324
                    *w_start
 
1325
                    );
1039
1326
 
1040
 
                (*w_start)->validate(); 
 
1327
                (*w_start)->validate();
1041
1328
                
1042
1329
                if (g_event) {
1043
1330
                        pushEvent(g_event);
1049
1336
        return anyProcessed;
1050
1337
}
1051
1338
 
1052
 
#define GXMAP(k,x,y) case x: k = y; break; 
 
1339
#define GXMAP(k, x, y) case x: k = y; break
1053
1340
 
1054
1341
static GHOST_TKey
1055
1342
convertXKey(KeySym key)
1057
1344
        GHOST_TKey type;
1058
1345
 
1059
1346
        if ((key >= XK_A) && (key <= XK_Z)) {
1060
 
                type = GHOST_TKey( key - XK_A + int(GHOST_kKeyA));
1061
 
        } else if ((key >= XK_a) && (key <= XK_z)) {
 
1347
                type = GHOST_TKey(key - XK_A + int(GHOST_kKeyA));
 
1348
        }
 
1349
        else if ((key >= XK_a) && (key <= XK_z)) {
1062
1350
                type = GHOST_TKey(key - XK_a + int(GHOST_kKeyA));
1063
 
        } else if ((key >= XK_0) && (key <= XK_9)) {
 
1351
        }
 
1352
        else if ((key >= XK_0) && (key <= XK_9)) {
1064
1353
                type = GHOST_TKey(key - XK_0 + int(GHOST_kKey0));
1065
 
        } else if ((key >= XK_F1) && (key <= XK_F24)) {
 
1354
        }
 
1355
        else if ((key >= XK_F1) && (key <= XK_F24)) {
1066
1356
                type = GHOST_TKey(key - XK_F1 + int(GHOST_kKeyF1));
1067
1357
#if defined(__sun) || defined(__sun__) 
1068
1358
                /* This is a bit of a hack, but it looks like sun
1069
 
                   Used F11 and friends for its special keys Stop,again etc..
1070
 
                   So this little patch enables F11 and F12 to work as expected
1071
 
                   following link has documentation on it: 
1072
 
                   http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4734408
1073
 
                   also from /usr/include/X11/Sunkeysym.h 
1074
 
#define SunXK_F36               0x1005FF10      // Labeled F11
1075
 
#define SunXK_F37               0x1005FF11      // Labeled F12 
1076
 
 
1077
 
                                mein@cs.umn.edu
 
1359
                 * Used F11 and friends for its special keys Stop,again etc..
 
1360
                 * So this little patch enables F11 and F12 to work as expected
 
1361
                 * following link has documentation on it:
 
1362
                 * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4734408
 
1363
                 * also from /usr/include/X11/Sunkeysym.h
 
1364
                 * #define SunXK_F36               0x1005FF10      // Labeled F11
 
1365
                 * #define SunXK_F37               0x1005FF11      // Labeled F12
 
1366
                 *
 
1367
                 *      mein@cs.umn.edu
1078
1368
                 */
1079
1369
                
1080
 
        } else if (key == 268828432) {
 
1370
        }
 
1371
        else if (key == 268828432) {
1081
1372
                type = GHOST_kKeyF11;
1082
 
        } else if (key == 268828433) {
 
1373
        }
 
1374
        else if (key == 268828433) {
1083
1375
                type = GHOST_kKeyF12;
1084
1376
#endif
1085
 
        } else {
1086
 
                switch(key) {
1087
 
                        GXMAP(type,XK_BackSpace,        GHOST_kKeyBackSpace);
1088
 
                        GXMAP(type,XK_Tab,              GHOST_kKeyTab);
1089
 
                        GXMAP(type,XK_Return,           GHOST_kKeyEnter);
1090
 
                        GXMAP(type,XK_Escape,           GHOST_kKeyEsc);
1091
 
                        GXMAP(type,XK_space,            GHOST_kKeySpace);
1092
 
                        
1093
 
                        GXMAP(type,XK_Linefeed,         GHOST_kKeyLinefeed);
1094
 
                        GXMAP(type,XK_semicolon,        GHOST_kKeySemicolon);
1095
 
                        GXMAP(type,XK_period,           GHOST_kKeyPeriod);
1096
 
                        GXMAP(type,XK_comma,            GHOST_kKeyComma);
1097
 
                        GXMAP(type,XK_quoteright,       GHOST_kKeyQuote);
1098
 
                        GXMAP(type,XK_quoteleft,        GHOST_kKeyAccentGrave);
1099
 
                        GXMAP(type,XK_minus,            GHOST_kKeyMinus);
1100
 
                        GXMAP(type,XK_slash,            GHOST_kKeySlash);
1101
 
                        GXMAP(type,XK_backslash,        GHOST_kKeyBackslash);
1102
 
                        GXMAP(type,XK_equal,            GHOST_kKeyEqual);
1103
 
                        GXMAP(type,XK_bracketleft,      GHOST_kKeyLeftBracket);
1104
 
                        GXMAP(type,XK_bracketright,     GHOST_kKeyRightBracket);
1105
 
                        GXMAP(type,XK_Pause,            GHOST_kKeyPause);
1106
 
                        
1107
 
                        GXMAP(type,XK_Shift_L,          GHOST_kKeyLeftShift);
1108
 
                        GXMAP(type,XK_Shift_R,          GHOST_kKeyRightShift);
1109
 
                        GXMAP(type,XK_Control_L,        GHOST_kKeyLeftControl);
1110
 
                        GXMAP(type,XK_Control_R,        GHOST_kKeyRightControl);
1111
 
                        GXMAP(type,XK_Alt_L,            GHOST_kKeyLeftAlt);
1112
 
                        GXMAP(type,XK_Alt_R,            GHOST_kKeyRightAlt);
1113
 
                        GXMAP(type,XK_Super_L,          GHOST_kKeyOS);
1114
 
                        GXMAP(type,XK_Super_R,          GHOST_kKeyOS);
1115
 
 
1116
 
                        GXMAP(type,XK_Insert,           GHOST_kKeyInsert);
1117
 
                        GXMAP(type,XK_Delete,           GHOST_kKeyDelete);
1118
 
                        GXMAP(type,XK_Home,                     GHOST_kKeyHome);
1119
 
                        GXMAP(type,XK_End,                      GHOST_kKeyEnd);
1120
 
                        GXMAP(type,XK_Page_Up,          GHOST_kKeyUpPage);
1121
 
                        GXMAP(type,XK_Page_Down,        GHOST_kKeyDownPage);
1122
 
 
1123
 
                        GXMAP(type,XK_Left,                     GHOST_kKeyLeftArrow);
1124
 
                        GXMAP(type,XK_Right,            GHOST_kKeyRightArrow);
1125
 
                        GXMAP(type,XK_Up,                       GHOST_kKeyUpArrow);
1126
 
                        GXMAP(type,XK_Down,                     GHOST_kKeyDownArrow);
1127
 
 
1128
 
                        GXMAP(type,XK_Caps_Lock,        GHOST_kKeyCapsLock);
1129
 
                        GXMAP(type,XK_Scroll_Lock,      GHOST_kKeyScrollLock);
1130
 
                        GXMAP(type,XK_Num_Lock,         GHOST_kKeyNumLock);
1131
 
                        
1132
 
                                /* keypad events */
1133
 
                                
1134
 
                        GXMAP(type,XK_KP_0,                     GHOST_kKeyNumpad0);
1135
 
                        GXMAP(type,XK_KP_1,                     GHOST_kKeyNumpad1);
1136
 
                        GXMAP(type,XK_KP_2,                     GHOST_kKeyNumpad2);
1137
 
                        GXMAP(type,XK_KP_3,                     GHOST_kKeyNumpad3);
1138
 
                        GXMAP(type,XK_KP_4,                     GHOST_kKeyNumpad4);
1139
 
                        GXMAP(type,XK_KP_5,                     GHOST_kKeyNumpad5);
1140
 
                        GXMAP(type,XK_KP_6,                     GHOST_kKeyNumpad6);
1141
 
                        GXMAP(type,XK_KP_7,                     GHOST_kKeyNumpad7);
1142
 
                        GXMAP(type,XK_KP_8,                     GHOST_kKeyNumpad8);
1143
 
                        GXMAP(type,XK_KP_9,                     GHOST_kKeyNumpad9);
1144
 
                        GXMAP(type,XK_KP_Decimal,       GHOST_kKeyNumpadPeriod);
1145
 
 
1146
 
                        GXMAP(type,XK_KP_Insert,        GHOST_kKeyNumpad0);
1147
 
                        GXMAP(type,XK_KP_End,           GHOST_kKeyNumpad1);
1148
 
                        GXMAP(type,XK_KP_Down,          GHOST_kKeyNumpad2);
1149
 
                        GXMAP(type,XK_KP_Page_Down,     GHOST_kKeyNumpad3);
1150
 
                        GXMAP(type,XK_KP_Left,          GHOST_kKeyNumpad4);
1151
 
                        GXMAP(type,XK_KP_Begin,         GHOST_kKeyNumpad5);
1152
 
                        GXMAP(type,XK_KP_Right,         GHOST_kKeyNumpad6);
1153
 
                        GXMAP(type,XK_KP_Home,          GHOST_kKeyNumpad7);
1154
 
                        GXMAP(type,XK_KP_Up,            GHOST_kKeyNumpad8);
1155
 
                        GXMAP(type,XK_KP_Page_Up,       GHOST_kKeyNumpad9);
1156
 
                        GXMAP(type,XK_KP_Delete,        GHOST_kKeyNumpadPeriod);
1157
 
 
1158
 
                        GXMAP(type,XK_KP_Enter,         GHOST_kKeyNumpadEnter);
1159
 
                        GXMAP(type,XK_KP_Add,           GHOST_kKeyNumpadPlus);
1160
 
                        GXMAP(type,XK_KP_Subtract,      GHOST_kKeyNumpadMinus);
1161
 
                        GXMAP(type,XK_KP_Multiply,      GHOST_kKeyNumpadAsterisk);
1162
 
                        GXMAP(type,XK_KP_Divide,        GHOST_kKeyNumpadSlash);
 
1377
        }
 
1378
        else {
 
1379
                switch (key) {
 
1380
                        GXMAP(type, XK_BackSpace,    GHOST_kKeyBackSpace);
 
1381
                        GXMAP(type, XK_Tab,          GHOST_kKeyTab);
 
1382
                        GXMAP(type, XK_Return,       GHOST_kKeyEnter);
 
1383
                        GXMAP(type, XK_Escape,       GHOST_kKeyEsc);
 
1384
                        GXMAP(type, XK_space,        GHOST_kKeySpace);
 
1385
 
 
1386
                        GXMAP(type, XK_Linefeed,     GHOST_kKeyLinefeed);
 
1387
                        GXMAP(type, XK_semicolon,    GHOST_kKeySemicolon);
 
1388
                        GXMAP(type, XK_period,       GHOST_kKeyPeriod);
 
1389
                        GXMAP(type, XK_comma,        GHOST_kKeyComma);
 
1390
                        GXMAP(type, XK_quoteright,   GHOST_kKeyQuote);
 
1391
                        GXMAP(type, XK_quoteleft,    GHOST_kKeyAccentGrave);
 
1392
                        GXMAP(type, XK_minus,        GHOST_kKeyMinus);
 
1393
                        GXMAP(type, XK_slash,        GHOST_kKeySlash);
 
1394
                        GXMAP(type, XK_backslash,    GHOST_kKeyBackslash);
 
1395
                        GXMAP(type, XK_equal,        GHOST_kKeyEqual);
 
1396
                        GXMAP(type, XK_bracketleft,  GHOST_kKeyLeftBracket);
 
1397
                        GXMAP(type, XK_bracketright, GHOST_kKeyRightBracket);
 
1398
                        GXMAP(type, XK_Pause,        GHOST_kKeyPause);
 
1399
 
 
1400
                        GXMAP(type, XK_Shift_L,      GHOST_kKeyLeftShift);
 
1401
                        GXMAP(type, XK_Shift_R,      GHOST_kKeyRightShift);
 
1402
                        GXMAP(type, XK_Control_L,    GHOST_kKeyLeftControl);
 
1403
                        GXMAP(type, XK_Control_R,    GHOST_kKeyRightControl);
 
1404
                        GXMAP(type, XK_Alt_L,        GHOST_kKeyLeftAlt);
 
1405
                        GXMAP(type, XK_Alt_R,        GHOST_kKeyRightAlt);
 
1406
                        GXMAP(type, XK_Super_L,      GHOST_kKeyOS);
 
1407
                        GXMAP(type, XK_Super_R,      GHOST_kKeyOS);
 
1408
 
 
1409
                        GXMAP(type, XK_Insert,       GHOST_kKeyInsert);
 
1410
                        GXMAP(type, XK_Delete,       GHOST_kKeyDelete);
 
1411
                        GXMAP(type, XK_Home,         GHOST_kKeyHome);
 
1412
                        GXMAP(type, XK_End,          GHOST_kKeyEnd);
 
1413
                        GXMAP(type, XK_Page_Up,      GHOST_kKeyUpPage);
 
1414
                        GXMAP(type, XK_Page_Down,    GHOST_kKeyDownPage);
 
1415
 
 
1416
                        GXMAP(type, XK_Left,         GHOST_kKeyLeftArrow);
 
1417
                        GXMAP(type, XK_Right,        GHOST_kKeyRightArrow);
 
1418
                        GXMAP(type, XK_Up,           GHOST_kKeyUpArrow);
 
1419
                        GXMAP(type, XK_Down,         GHOST_kKeyDownArrow);
 
1420
 
 
1421
                        GXMAP(type, XK_Caps_Lock,    GHOST_kKeyCapsLock);
 
1422
                        GXMAP(type, XK_Scroll_Lock,  GHOST_kKeyScrollLock);
 
1423
                        GXMAP(type, XK_Num_Lock,     GHOST_kKeyNumLock);
 
1424
 
 
1425
                        /* keypad events */
 
1426
 
 
1427
                        GXMAP(type, XK_KP_0,         GHOST_kKeyNumpad0);
 
1428
                        GXMAP(type, XK_KP_1,         GHOST_kKeyNumpad1);
 
1429
                        GXMAP(type, XK_KP_2,         GHOST_kKeyNumpad2);
 
1430
                        GXMAP(type, XK_KP_3,         GHOST_kKeyNumpad3);
 
1431
                        GXMAP(type, XK_KP_4,         GHOST_kKeyNumpad4);
 
1432
                        GXMAP(type, XK_KP_5,         GHOST_kKeyNumpad5);
 
1433
                        GXMAP(type, XK_KP_6,         GHOST_kKeyNumpad6);
 
1434
                        GXMAP(type, XK_KP_7,         GHOST_kKeyNumpad7);
 
1435
                        GXMAP(type, XK_KP_8,         GHOST_kKeyNumpad8);
 
1436
                        GXMAP(type, XK_KP_9,         GHOST_kKeyNumpad9);
 
1437
                        GXMAP(type, XK_KP_Decimal,   GHOST_kKeyNumpadPeriod);
 
1438
 
 
1439
                        GXMAP(type, XK_KP_Insert,    GHOST_kKeyNumpad0);
 
1440
                        GXMAP(type, XK_KP_End,       GHOST_kKeyNumpad1);
 
1441
                        GXMAP(type, XK_KP_Down,      GHOST_kKeyNumpad2);
 
1442
                        GXMAP(type, XK_KP_Page_Down, GHOST_kKeyNumpad3);
 
1443
                        GXMAP(type, XK_KP_Left,      GHOST_kKeyNumpad4);
 
1444
                        GXMAP(type, XK_KP_Begin,     GHOST_kKeyNumpad5);
 
1445
                        GXMAP(type, XK_KP_Right,     GHOST_kKeyNumpad6);
 
1446
                        GXMAP(type, XK_KP_Home,      GHOST_kKeyNumpad7);
 
1447
                        GXMAP(type, XK_KP_Up,        GHOST_kKeyNumpad8);
 
1448
                        GXMAP(type, XK_KP_Page_Up,   GHOST_kKeyNumpad9);
 
1449
                        GXMAP(type, XK_KP_Delete,    GHOST_kKeyNumpadPeriod);
 
1450
 
 
1451
                        GXMAP(type, XK_KP_Enter,     GHOST_kKeyNumpadEnter);
 
1452
                        GXMAP(type, XK_KP_Add,       GHOST_kKeyNumpadPlus);
 
1453
                        GXMAP(type, XK_KP_Subtract,  GHOST_kKeyNumpadMinus);
 
1454
                        GXMAP(type, XK_KP_Multiply,  GHOST_kKeyNumpadAsterisk);
 
1455
                        GXMAP(type, XK_KP_Divide,    GHOST_kKeyNumpadSlash);
1163
1456
 
1164
1457
                        /* Media keys in some keyboards and laptops with XFree86/Xorg */
1165
1458
#ifdef WITH_XF86KEYSYM
1166
 
                        GXMAP(type,XF86XK_AudioPlay,    GHOST_kKeyMediaPlay);
1167
 
                        GXMAP(type,XF86XK_AudioStop,    GHOST_kKeyMediaStop);
1168
 
                        GXMAP(type,XF86XK_AudioPrev,    GHOST_kKeyMediaFirst);
1169
 
                        GXMAP(type,XF86XK_AudioRewind,  GHOST_kKeyMediaFirst);
1170
 
                        GXMAP(type,XF86XK_AudioNext,    GHOST_kKeyMediaLast);
 
1459
                        GXMAP(type, XF86XK_AudioPlay,    GHOST_kKeyMediaPlay);
 
1460
                        GXMAP(type, XF86XK_AudioStop,    GHOST_kKeyMediaStop);
 
1461
                        GXMAP(type, XF86XK_AudioPrev,    GHOST_kKeyMediaFirst);
 
1462
                        GXMAP(type, XF86XK_AudioRewind,  GHOST_kKeyMediaFirst);
 
1463
                        GXMAP(type, XF86XK_AudioNext,    GHOST_kKeyMediaLast);
1171
1464
#ifdef XF86XK_AudioForward /* Debian lenny's XF86keysym.h has no XF86XK_AudioForward define */
1172
 
                        GXMAP(type,XF86XK_AudioForward, GHOST_kKeyMediaLast);
 
1465
                        GXMAP(type, XF86XK_AudioForward, GHOST_kKeyMediaLast);
1173
1466
#endif
1174
1467
#endif
1175
1468
 
1176
 
                                /* some extra sun cruft (NICE KEYBOARD!) */
 
1469
                        /* some extra sun cruft (NICE KEYBOARD!) */
1177
1470
#ifdef __sun__
1178
 
                        GXMAP(type,0xffde,                      GHOST_kKeyNumpad1);
1179
 
                        GXMAP(type,0xffe0,                      GHOST_kKeyNumpad3);
1180
 
                        GXMAP(type,0xffdc,                      GHOST_kKeyNumpad5);
1181
 
                        GXMAP(type,0xffd8,                      GHOST_kKeyNumpad7);
1182
 
                        GXMAP(type,0xffda,                      GHOST_kKeyNumpad9);
 
1471
                        GXMAP(type, 0xffde,          GHOST_kKeyNumpad1);
 
1472
                        GXMAP(type, 0xffe0,          GHOST_kKeyNumpad3);
 
1473
                        GXMAP(type, 0xffdc,          GHOST_kKeyNumpad5);
 
1474
                        GXMAP(type, 0xffd8,          GHOST_kKeyNumpad7);
 
1475
                        GXMAP(type, 0xffda,          GHOST_kKeyNumpad9);
1183
1476
 
1184
 
                        GXMAP(type,0xffd6,                      GHOST_kKeyNumpadSlash);
1185
 
                        GXMAP(type,0xffd7,                      GHOST_kKeyNumpadAsterisk);
 
1477
                        GXMAP(type, 0xffd6,          GHOST_kKeyNumpadSlash);
 
1478
                        GXMAP(type, 0xffd7,          GHOST_kKeyNumpadAsterisk);
1186
1479
#endif
1187
1480
 
1188
 
                        default :
 
1481
                        default:
1189
1482
                                type = GHOST_kKeyUnknown;
1190
1483
                                break;
1191
1484
                }
1198
1491
 
1199
1492
/* from xclip.c xcout() v0.11 */
1200
1493
 
1201
 
#define XCLIB_XCOUT_NONE                0 /* no context */
1202
 
#define XCLIB_XCOUT_SENTCONVSEL         1 /* sent a request */
1203
 
#define XCLIB_XCOUT_INCR                2 /* in an incr loop */
1204
 
#define XCLIB_XCOUT_FALLBACK            3 /* STRING failed, need fallback to UTF8 */
1205
 
#define XCLIB_XCOUT_FALLBACK_UTF8       4 /* UTF8 failed, move to compouned */
1206
 
#define XCLIB_XCOUT_FALLBACK_COMP       5 /* compouned failed, move to text. */
1207
 
#define XCLIB_XCOUT_FALLBACK_TEXT       6
 
1494
#define XCLIB_XCOUT_NONE            0 /* no context */
 
1495
#define XCLIB_XCOUT_SENTCONVSEL     1 /* sent a request */
 
1496
#define XCLIB_XCOUT_INCR            2 /* in an incr loop */
 
1497
#define XCLIB_XCOUT_FALLBACK        3 /* STRING failed, need fallback to UTF8 */
 
1498
#define XCLIB_XCOUT_FALLBACK_UTF8   4 /* UTF8 failed, move to compouned */
 
1499
#define XCLIB_XCOUT_FALLBACK_COMP   5 /* compouned failed, move to text. */
 
1500
#define XCLIB_XCOUT_FALLBACK_TEXT   6
1208
1501
 
1209
 
// Retrieves the contents of a selections.
 
1502
/* Retrieves the contents of a selections. */
1210
1503
void GHOST_SystemX11::getClipboard_xcout(XEvent evt,
1211
 
        Atom sel, Atom target, unsigned char **txt,
1212
 
        unsigned long *len, unsigned int *context) const
 
1504
                Atom sel, Atom target, unsigned char **txt,
 
1505
                unsigned long *len, unsigned int *context) const
1213
1506
{
1214
1507
        Atom pty_type;
1215
1508
        int pty_format;
1216
1509
        unsigned char *buffer;
1217
1510
        unsigned long pty_size, pty_items;
1218
 
        unsigned char *ltxt= *txt;
 
1511
        unsigned char *ltxt = *txt;
1219
1512
 
1220
1513
        vector<GHOST_IWindow *> & win_vec = m_windowManager->getWindows();
1221
1514
        vector<GHOST_IWindow *>::iterator win_it = win_vec.begin();
1222
 
        GHOST_WindowX11 * window = static_cast<GHOST_WindowX11 *>(*win_it);
 
1515
        GHOST_WindowX11 *window = static_cast<GHOST_WindowX11 *>(*win_it);
1223
1516
        Window win = window->getXWindow();
1224
1517
 
1225
1518
        switch (*context) {
1226
 
                // There is no context, do an XConvertSelection()
 
1519
                /* There is no context, do an XConvertSelection() */
1227
1520
                case XCLIB_XCOUT_NONE:
1228
 
                        // Initialise return length to 0
 
1521
                        /* Initialise return length to 0 */
1229
1522
                        if (*len > 0) {
1230
1523
                                free(*txt);
1231
1524
                                *len = 0;
1232
1525
                        }
1233
1526
 
1234
 
                        // Send a selection request
1235
 
                        XConvertSelection(m_display, sel, target, m_xclip_out, win, CurrentTime);
 
1527
                        /* Send a selection request */
 
1528
                        XConvertSelection(m_display, sel, target, m_atom.XCLIP_OUT, win, CurrentTime);
1236
1529
                        *context = XCLIB_XCOUT_SENTCONVSEL;
1237
1530
                        return;
1238
1531
 
1240
1533
                        if (evt.type != SelectionNotify)
1241
1534
                                return;
1242
1535
 
1243
 
                        if (target == m_utf8_string && evt.xselection.property == None) {
1244
 
                                *context= XCLIB_XCOUT_FALLBACK_UTF8;
1245
 
                                return;
1246
 
                        }
1247
 
                        else if (target == m_compound_text && evt.xselection.property == None) {
1248
 
                                *context= XCLIB_XCOUT_FALLBACK_COMP;
1249
 
                                return;
1250
 
                        }
1251
 
                        else if (target == m_text && evt.xselection.property == None) {
1252
 
                                *context= XCLIB_XCOUT_FALLBACK_TEXT;
 
1536
                        if (target == m_atom.UTF8_STRING && evt.xselection.property == None) {
 
1537
                                *context = XCLIB_XCOUT_FALLBACK_UTF8;
 
1538
                                return;
 
1539
                        }
 
1540
                        else if (target == m_atom.COMPOUND_TEXT && evt.xselection.property == None) {
 
1541
                                *context = XCLIB_XCOUT_FALLBACK_COMP;
 
1542
                                return;
 
1543
                        }
 
1544
                        else if (target == m_atom.TEXT && evt.xselection.property == None) {
 
1545
                                *context = XCLIB_XCOUT_FALLBACK_TEXT;
1253
1546
                                return;
1254
1547
                        }
1255
1548
 
1256
 
                        // find the size and format of the data in property
1257
 
                        XGetWindowProperty(m_display, win, m_xclip_out, 0, 0, False,
1258
 
                                AnyPropertyType, &pty_type, &pty_format,
1259
 
                                &pty_items, &pty_size, &buffer);
 
1549
                        /* find the size and format of the data in property */
 
1550
                        XGetWindowProperty(m_display, win, m_atom.XCLIP_OUT, 0, 0, False,
 
1551
                                           AnyPropertyType, &pty_type, &pty_format,
 
1552
                                           &pty_items, &pty_size, &buffer);
1260
1553
                        XFree(buffer);
1261
1554
 
1262
 
                        if (pty_type == m_incr) {
1263
 
                                // start INCR mechanism by deleting property
1264
 
                                XDeleteProperty(m_display, win, m_xclip_out);
 
1555
                        if (pty_type == m_atom.INCR) {
 
1556
                                /* start INCR mechanism by deleting property */
 
1557
                                XDeleteProperty(m_display, win, m_atom.XCLIP_OUT);
1265
1558
                                XFlush(m_display);
1266
1559
                                *context = XCLIB_XCOUT_INCR;
1267
1560
                                return;
1268
1561
                        }
1269
1562
 
1270
 
                        // if it's not incr, and not format == 8, then there's
1271
 
                        // nothing in the selection (that xclip understands, anyway)
 
1563
                        /* if it's not incr, and not format == 8, then there's
 
1564
                         * nothing in the selection (that xclip understands, anyway) */
1272
1565
 
1273
1566
                        if (pty_format != 8) {
1274
1567
                                *context = XCLIB_XCOUT_NONE;
1276
1569
                        }
1277
1570
 
1278
1571
                        // not using INCR mechanism, just read the property
1279
 
                        XGetWindowProperty(m_display, win, m_xclip_out, 0, (long) pty_size,
1280
 
                                        False, AnyPropertyType, &pty_type,
1281
 
                                        &pty_format, &pty_items, &pty_size, &buffer);
1282
 
 
1283
 
                        // finished with property, delete it
1284
 
                        XDeleteProperty(m_display, win, m_xclip_out);
1285
 
 
1286
 
                        // copy the buffer to the pointer for returned data
 
1572
                        XGetWindowProperty(m_display, win, m_atom.XCLIP_OUT, 0, (long) pty_size,
 
1573
                                           False, AnyPropertyType, &pty_type,
 
1574
                                           &pty_format, &pty_items, &pty_size, &buffer);
 
1575
 
 
1576
                        /* finished with property, delete it */
 
1577
                        XDeleteProperty(m_display, win, m_atom.XCLIP_OUT);
 
1578
 
 
1579
                        /* copy the buffer to the pointer for returned data */
1287
1580
                        ltxt = (unsigned char *) malloc(pty_items);
1288
1581
                        memcpy(ltxt, buffer, pty_items);
1289
1582
 
1290
 
                        // set the length of the returned data
 
1583
                        /* set the length of the returned data */
1291
1584
                        *len = pty_items;
1292
1585
                        *txt = ltxt;
1293
1586
 
1294
 
                        // free the buffer
 
1587
                        /* free the buffer */
1295
1588
                        XFree(buffer);
1296
1589
 
1297
1590
                        *context = XCLIB_XCOUT_NONE;
1298
1591
 
1299
 
                        // complete contents of selection fetched, return 1
 
1592
                        /* complete contents of selection fetched, return 1 */
1300
1593
                        return;
1301
1594
 
1302
1595
                case XCLIB_XCOUT_INCR:
1303
 
                        // To use the INCR method, we basically delete the
1304
 
                        // property with the selection in it, wait for an
1305
 
                        // event indicating that the property has been created,
1306
 
                        // then read it, delete it, etc.
 
1596
                        /* To use the INCR method, we basically delete the
 
1597
                         * property with the selection in it, wait for an
 
1598
                         * event indicating that the property has been created,
 
1599
                         * then read it, delete it, etc. */
1307
1600
 
1308
 
                        // make sure that the event is relevant
 
1601
                        /* make sure that the event is relevant */
1309
1602
                        if (evt.type != PropertyNotify)
1310
1603
                                return;
1311
1604
 
1312
 
                        // skip unless the property has a new value
 
1605
                        /* skip unless the property has a new value */
1313
1606
                        if (evt.xproperty.state != PropertyNewValue)
1314
1607
                                return;
1315
1608
 
1316
 
                        // check size and format of the property
1317
 
                        XGetWindowProperty(m_display, win, m_xclip_out, 0, 0, False,
1318
 
                                AnyPropertyType, &pty_type, &pty_format,
1319
 
                                &pty_items, &pty_size, (unsigned char **) &buffer);
 
1609
                        /* check size and format of the property */
 
1610
                        XGetWindowProperty(m_display, win, m_atom.XCLIP_OUT, 0, 0, False,
 
1611
                                           AnyPropertyType, &pty_type, &pty_format,
 
1612
                                           &pty_items, &pty_size, &buffer);
1320
1613
 
1321
1614
                        if (pty_format != 8) {
1322
 
                                // property does not contain text, delete it
1323
 
                                // to tell the other X client that we have read 
1324
 
                                // it and to send the next property
 
1615
                                /* property does not contain text, delete it
 
1616
                                 * to tell the other X client that we have read
 
1617
                                 * it and to send the next property */
1325
1618
                                XFree(buffer);
1326
 
                                XDeleteProperty(m_display, win, m_xclip_out);
 
1619
                                XDeleteProperty(m_display, win, m_atom.XCLIP_OUT);
1327
1620
                                return;
1328
1621
                        }
1329
1622
 
1330
1623
                        if (pty_size == 0) {
1331
 
                                // no more data, exit from loop
 
1624
                                /* no more data, exit from loop */
1332
1625
                                XFree(buffer);
1333
 
                                XDeleteProperty(m_display, win, m_xclip_out);
 
1626
                                XDeleteProperty(m_display, win, m_atom.XCLIP_OUT);
1334
1627
                                *context = XCLIB_XCOUT_NONE;
1335
1628
 
1336
 
                                // this means that an INCR transfer is now
1337
 
                                // complete, return 1
 
1629
                                /* this means that an INCR transfer is now
 
1630
                                 * complete, return 1 */
1338
1631
                                return;
1339
1632
                        }
1340
1633
 
1341
1634
                        XFree(buffer);
1342
1635
 
1343
 
                        // if we have come this far, the propery contains
1344
 
                        // text, we know the size.
1345
 
                        XGetWindowProperty(m_display, win, m_xclip_out, 0, (long) pty_size,
1346
 
                                False, AnyPropertyType, &pty_type, &pty_format,
1347
 
                                &pty_items, &pty_size, (unsigned char **) &buffer);
 
1636
                        /* if we have come this far, the property contains
 
1637
                         * text, we know the size. */
 
1638
                        XGetWindowProperty(m_display, win, m_atom.XCLIP_OUT, 0, (long) pty_size,
 
1639
                                           False, AnyPropertyType, &pty_type, &pty_format,
 
1640
                                           &pty_items, &pty_size, &buffer);
1348
1641
 
1349
 
                        // allocate memory to accommodate data in *txt
 
1642
                        /* allocate memory to accommodate data in *txt */
1350
1643
                        if (*len == 0) {
1351
1644
                                *len = pty_items;
1352
1645
                                ltxt = (unsigned char *) malloc(*len);
1356
1649
                                ltxt = (unsigned char *) realloc(ltxt, *len);
1357
1650
                        }
1358
1651
 
1359
 
                        // add data to ltxt
 
1652
                        /* add data to ltxt */
1360
1653
                        memcpy(&ltxt[*len - pty_items], buffer, pty_items);
1361
1654
 
1362
1655
                        *txt = ltxt;
1363
1656
                        XFree(buffer);
1364
1657
 
1365
 
                        // delete property to get the next item
1366
 
                        XDeleteProperty(m_display, win, m_xclip_out);
 
1658
                        /* delete property to get the next item */
 
1659
                        XDeleteProperty(m_display, win, m_atom.XCLIP_OUT);
1367
1660
                        XFlush(m_display);
1368
1661
                        return;
1369
1662
        }
1373
1666
GHOST_TUns8 *GHOST_SystemX11::getClipboard(bool selection) const
1374
1667
{
1375
1668
        Atom sseln;
1376
 
        Atom target= m_utf8_string;
 
1669
        Atom target = m_atom.UTF8_STRING;
1377
1670
        Window owner;
1378
1671
 
1379
 
        // from xclip.c doOut() v0.11
 
1672
        /* from xclip.c doOut() v0.11 */
1380
1673
        unsigned char *sel_buf;
1381
 
        unsigned long sel_len= 0;
 
1674
        unsigned long sel_len = 0;
1382
1675
        XEvent evt;
1383
 
        unsigned int context= XCLIB_XCOUT_NONE;
 
1676
        unsigned int context = XCLIB_XCOUT_NONE;
1384
1677
 
1385
1678
        if (selection == True)
1386
 
                sseln= m_primary;
 
1679
                sseln = m_atom.PRIMARY;
1387
1680
        else
1388
 
                sseln= m_clipboard;
 
1681
                sseln = m_atom.CLIPBOARD;
1389
1682
 
1390
1683
        vector<GHOST_IWindow *> & win_vec = m_windowManager->getWindows();
1391
1684
        vector<GHOST_IWindow *>::iterator win_it = win_vec.begin();
1392
 
        GHOST_WindowX11 * window = static_cast<GHOST_WindowX11 *>(*win_it);
 
1685
        GHOST_WindowX11 *window = static_cast<GHOST_WindowX11 *>(*win_it);
1393
1686
        Window win = window->getXWindow();
1394
1687
 
1395
1688
        /* check if we are the owner. */
1396
 
        owner= XGetSelectionOwner(m_display, sseln);
 
1689
        owner = XGetSelectionOwner(m_display, sseln);
1397
1690
        if (owner == win) {
1398
 
                if (sseln == m_clipboard) {
1399
 
                        sel_buf= (unsigned char *)malloc(strlen(txt_cut_buffer)+1);
 
1691
                if (sseln == m_atom.CLIPBOARD) {
 
1692
                        sel_buf = (unsigned char *)malloc(strlen(txt_cut_buffer) + 1);
1400
1693
                        strcpy((char *)sel_buf, txt_cut_buffer);
1401
 
                        return((GHOST_TUns8*)sel_buf);
 
1694
                        return sel_buf;
1402
1695
                }
1403
1696
                else {
1404
 
                        sel_buf= (unsigned char *)malloc(strlen(txt_select_buffer)+1);
 
1697
                        sel_buf = (unsigned char *)malloc(strlen(txt_select_buffer) + 1);
1405
1698
                        strcpy((char *)sel_buf, txt_select_buffer);
1406
 
                        return((GHOST_TUns8*)sel_buf);
 
1699
                        return sel_buf;
1407
1700
                }
1408
1701
        }
1409
1702
        else if (owner == None)
1419
1712
 
1420
1713
                /* fallback is needed. set XA_STRING to target and restart the loop. */
1421
1714
                if (context == XCLIB_XCOUT_FALLBACK) {
1422
 
                        context= XCLIB_XCOUT_NONE;
1423
 
                        target= m_string;
 
1715
                        context = XCLIB_XCOUT_NONE;
 
1716
                        target = m_atom.STRING;
1424
1717
                        continue;
1425
1718
                }
1426
1719
                else if (context == XCLIB_XCOUT_FALLBACK_UTF8) {
1427
1720
                        /* utf8 fail, move to compouned text. */
1428
 
                        context= XCLIB_XCOUT_NONE;
1429
 
                        target= m_compound_text;
 
1721
                        context = XCLIB_XCOUT_NONE;
 
1722
                        target = m_atom.COMPOUND_TEXT;
1430
1723
                        continue;
1431
1724
                }
1432
1725
                else if (context == XCLIB_XCOUT_FALLBACK_COMP) {
1433
1726
                        /* compouned text faile, move to text. */
1434
 
                        context= XCLIB_XCOUT_NONE;
1435
 
                        target= m_text;
 
1727
                        context = XCLIB_XCOUT_NONE;
 
1728
                        target = m_atom.TEXT;
1436
1729
                        continue;
1437
1730
                }
1438
1731
 
1445
1738
                /* only print the buffer out, and free it, if it's not
1446
1739
                 * empty
1447
1740
                 */
1448
 
                unsigned char *tmp_data = (unsigned char*) malloc(sel_len+1);
1449
 
                memcpy((char*)tmp_data, (char*)sel_buf, sel_len);
 
1741
                unsigned char *tmp_data = (unsigned char *) malloc(sel_len + 1);
 
1742
                memcpy((char *)tmp_data, (char *)sel_buf, sel_len);
1450
1743
                tmp_data[sel_len] = '\0';
1451
1744
                
1452
 
                if (sseln == m_string)
 
1745
                if (sseln == m_atom.STRING)
1453
1746
                        XFree(sel_buf);
1454
1747
                else
1455
1748
                        free(sel_buf);
1456
1749
                
1457
 
                return (GHOST_TUns8*)tmp_data;
 
1750
                return tmp_data;
1458
1751
        }
1459
1752
        return(NULL);
1460
1753
}
1463
1756
{
1464
1757
        Window m_window, owner;
1465
1758
 
1466
 
        vector<GHOST_IWindow *> & win_vec = m_windowManager->getWindows();      
 
1759
        vector<GHOST_IWindow *> & win_vec = m_windowManager->getWindows();
1467
1760
        vector<GHOST_IWindow *>::iterator win_it = win_vec.begin();
1468
 
        GHOST_WindowX11 * window = static_cast<GHOST_WindowX11 *>(*win_it);
 
1761
        GHOST_WindowX11 *window = static_cast<GHOST_WindowX11 *>(*win_it);
1469
1762
        m_window = window->getXWindow();
1470
1763
 
1471
1764
        if (buffer) {
1472
1765
                if (selection == False) {
1473
 
                        XSetSelectionOwner(m_display, m_clipboard, m_window, CurrentTime);
1474
 
                        owner= XGetSelectionOwner(m_display, m_clipboard);
 
1766
                        XSetSelectionOwner(m_display, m_atom.CLIPBOARD, m_window, CurrentTime);
 
1767
                        owner = XGetSelectionOwner(m_display, m_atom.CLIPBOARD);
1475
1768
                        if (txt_cut_buffer)
1476
 
                                free((void*)txt_cut_buffer);
 
1769
                                free((void *)txt_cut_buffer);
1477
1770
 
1478
 
                        txt_cut_buffer = (char*) malloc(strlen(buffer)+1);
 
1771
                        txt_cut_buffer = (char *) malloc(strlen(buffer) + 1);
1479
1772
                        strcpy(txt_cut_buffer, buffer);
1480
 
                } else {
1481
 
                        XSetSelectionOwner(m_display, m_primary, m_window, CurrentTime);
1482
 
                        owner= XGetSelectionOwner(m_display, m_primary);
 
1773
                }
 
1774
                else {
 
1775
                        XSetSelectionOwner(m_display, m_atom.PRIMARY, m_window, CurrentTime);
 
1776
                        owner = XGetSelectionOwner(m_display, m_atom.PRIMARY);
1483
1777
                        if (txt_select_buffer)
1484
 
                                free((void*)txt_select_buffer);
 
1778
                                free((void *)txt_select_buffer);
1485
1779
 
1486
 
                        txt_select_buffer = (char*) malloc(strlen(buffer)+1);
 
1780
                        txt_select_buffer = (char *) malloc(strlen(buffer) + 1);
1487
1781
                        strcpy(txt_select_buffer, buffer);
1488
1782
                }
1489
1783
 
1494
1788
 
1495
1789
#ifdef WITH_XDND
1496
1790
GHOST_TSuccess GHOST_SystemX11::pushDragDropEvent(GHOST_TEventType eventType, 
1497
 
                                                                                                        GHOST_TDragnDropTypes draggedObjectType,
1498
 
                                                                                                        GHOST_IWindow* window,
1499
 
                                                                                                        int mouseX, int mouseY,
1500
 
                                                                                                        void* data)
 
1791
                GHOST_TDragnDropTypes draggedObjectType,
 
1792
                GHOST_IWindow *window,
 
1793
                int mouseX, int mouseY,
 
1794
                void *data)
1501
1795
{
1502
 
        GHOST_SystemX11* system = ((GHOST_SystemX11*)getSystem());
 
1796
        GHOST_SystemX11 *system = ((GHOST_SystemX11 *)getSystem());
1503
1797
        return system->pushEvent(new GHOST_EventDragnDrop(system->getMilliSeconds(),
1504
 
                                                                                                          eventType,
1505
 
                                                                                                          draggedObjectType,
1506
 
                                                                                                          window,mouseX,mouseY,data)
1507
 
                        );
1508
 
}
1509
 
#endif
 
1798
                                                          eventType,
 
1799
                                                          draggedObjectType,
 
1800
                                                          window, mouseX, mouseY, data)
 
1801
                                 );
 
1802
}
 
1803
#endif
 
1804
 
 
1805
#ifdef WITH_X11_XINPUT
 
1806
/* 
 
1807
 * Dummy function to get around IO Handler exiting if device invalid
 
1808
 * Basically it will not crash blender now if you have a X device that
 
1809
 * is configured but not plugged in.
 
1810
 */
 
1811
int GHOST_X11_ApplicationErrorHandler(Display *display, XErrorEvent *theEvent)
 
1812
{
 
1813
        fprintf(stderr, "Ignoring Xlib error: error code %d request code %d\n",
 
1814
                theEvent->error_code, theEvent->request_code);
 
1815
 
 
1816
        /* No exit! - but keep lint happy */
 
1817
        return 0;
 
1818
}
 
1819
 
 
1820
int GHOST_X11_ApplicationIOErrorHandler(Display *display)
 
1821
{
 
1822
        fprintf(stderr, "Ignoring Xlib error: error IO\n");
 
1823
 
 
1824
        /* No exit! - but keep lint happy */
 
1825
        return 0;
 
1826
}
 
1827
 
 
1828
/* These C functions are copied from Wine 1.1.13's wintab.c */
 
1829
#define BOOL int
 
1830
#define TRUE 1
 
1831
#define FALSE 0
 
1832
 
 
1833
static bool match_token(const char *haystack, const char *needle)
 
1834
{
 
1835
        const char *p, *q;
 
1836
        for (p = haystack; *p; )
 
1837
        {
 
1838
                while (*p && isspace(*p))
 
1839
                        p++;
 
1840
                if (!*p)
 
1841
                        break;
 
1842
 
 
1843
                for (q = needle; *q && *p && tolower(*p) == tolower(*q); q++)
 
1844
                        p++;
 
1845
                if (!*q && (isspace(*p) || !*p))
 
1846
                        return TRUE;
 
1847
 
 
1848
                while (*p && !isspace(*p))
 
1849
                        p++;
 
1850
        }
 
1851
        return FALSE;
 
1852
}
 
1853
 
 
1854
 
 
1855
/* Determining if an X device is a Tablet style device is an imperfect science.
 
1856
 * We rely on common conventions around device names as well as the type reported
 
1857
 * by Wacom tablets.  This code will likely need to be expanded for alternate tablet types
 
1858
 *
 
1859
 * Wintab refers to any device that interacts with the tablet as a cursor,
 
1860
 * (stylus, eraser, tablet mouse, airbrush, etc)
 
1861
 * this is not to be confused with wacom x11 configuration "cursor" device.
 
1862
 * Wacoms x11 config "cursor" refers to its device slot (which we mirror with
 
1863
 * our gSysCursors) for puck like devices (tablet mice essentially).
 
1864
 */
 
1865
#if 0 // unused
 
1866
static BOOL is_tablet_cursor(const char *name, const char *type)
 
1867
{
 
1868
        int i;
 
1869
        static const char *tablet_cursor_whitelist[] = {
 
1870
                "wacom",
 
1871
                "wizardpen",
 
1872
                "acecad",
 
1873
                "tablet",
 
1874
                "cursor",
 
1875
                "stylus",
 
1876
                "eraser",
 
1877
                "pad",
 
1878
                NULL
 
1879
        };
 
1880
 
 
1881
        for (i = 0; tablet_cursor_whitelist[i] != NULL; i++) {
 
1882
                if (name && match_token(name, tablet_cursor_whitelist[i]))
 
1883
                        return TRUE;
 
1884
                if (type && match_token(type, tablet_cursor_whitelist[i]))
 
1885
                        return TRUE;
 
1886
        }
 
1887
        return FALSE;
 
1888
}
 
1889
#endif
 
1890
static BOOL is_stylus(const char *name, const char *type)
 
1891
{
 
1892
        int i;
 
1893
        static const char *tablet_stylus_whitelist[] = {
 
1894
                "stylus",
 
1895
                "wizardpen",
 
1896
                "acecad",
 
1897
                NULL
 
1898
        };
 
1899
 
 
1900
        for (i = 0; tablet_stylus_whitelist[i] != NULL; i++) {
 
1901
                if (name && match_token(name, tablet_stylus_whitelist[i]))
 
1902
                        return TRUE;
 
1903
                if (type && match_token(type, tablet_stylus_whitelist[i]))
 
1904
                        return TRUE;
 
1905
        }
 
1906
 
 
1907
        return FALSE;
 
1908
}
 
1909
 
 
1910
static BOOL is_eraser(const char *name, const char *type)
 
1911
{
 
1912
        if (name && match_token(name, "eraser"))
 
1913
                return TRUE;
 
1914
        if (type && match_token(type, "eraser"))
 
1915
                return TRUE;
 
1916
        return FALSE;
 
1917
}
 
1918
#undef BOOL
 
1919
#undef TRUE
 
1920
#undef FALSE
 
1921
/* end code copied from wine */
 
1922
 
 
1923
void GHOST_SystemX11::initXInputDevices()
 
1924
{
 
1925
        static XErrorHandler   old_handler = (XErrorHandler) 0;
 
1926
        static XIOErrorHandler old_handler_io = (XIOErrorHandler) 0;
 
1927
 
 
1928
        XExtensionVersion *version = XGetExtensionVersion(m_display, INAME);
 
1929
 
 
1930
        if (version && (version != (XExtensionVersion *)NoSuchExtension)) {
 
1931
                if (version->present) {
 
1932
                        int device_count;
 
1933
                        XDeviceInfo *device_info = XListInputDevices(m_display, &device_count);
 
1934
                        m_xtablet.StylusDevice = NULL;
 
1935
                        m_xtablet.EraserDevice = NULL;
 
1936
 
 
1937
                        /* Install our error handler to override Xlib's termination behavior */
 
1938
                        old_handler = XSetErrorHandler(GHOST_X11_ApplicationErrorHandler);
 
1939
                        old_handler_io = XSetIOErrorHandler(GHOST_X11_ApplicationIOErrorHandler);
 
1940
 
 
1941
                        for (int i = 0; i < device_count; ++i) {
 
1942
                                char *device_type = device_info[i].type ? XGetAtomName(m_display, device_info[i].type) : NULL;
 
1943
                                
 
1944
//                              printf("Tablet type:'%s', name:'%s', index:%d\n", device_type, device_info[i].name, i);
 
1945
 
 
1946
 
 
1947
                                if ((m_xtablet.StylusDevice == NULL) &&
 
1948
                                    (is_stylus(device_info[i].name, device_type) || (device_info[i].type == m_atom.TABLET)))
 
1949
                                {
 
1950
//                                      printf("\tfound stylus\n");
 
1951
                                        m_xtablet.StylusID = device_info[i].id;
 
1952
                                        m_xtablet.StylusDevice = XOpenDevice(m_display, m_xtablet.StylusID);
 
1953
 
 
1954
                                        if (m_xtablet.StylusDevice != NULL) {
 
1955
                                                /* Find how many pressure levels tablet has */
 
1956
                                                XAnyClassPtr ici = device_info[i].inputclassinfo;
 
1957
                                                for (int j = 0; j < m_xtablet.StylusDevice->num_classes; ++j) {
 
1958
                                                        if (ici->c_class == ValuatorClass) {
 
1959
//                                                              printf("\t\tfound ValuatorClass\n");
 
1960
                                                                XValuatorInfo *xvi = (XValuatorInfo *)ici;
 
1961
                                                                m_xtablet.PressureLevels = xvi->axes[2].max_value;
 
1962
 
 
1963
                                                                if (xvi->num_axes > 3) {
 
1964
                                                                        /* this is assuming that the tablet has the same tilt resolution in both
 
1965
                                                                         * positive and negative directions. It would be rather weird if it didn't.. */
 
1966
                                                                        m_xtablet.XtiltLevels = xvi->axes[3].max_value;
 
1967
                                                                        m_xtablet.YtiltLevels = xvi->axes[4].max_value;
 
1968
                                                                }
 
1969
                                                                else {
 
1970
                                                                        m_xtablet.XtiltLevels = 0;
 
1971
                                                                        m_xtablet.YtiltLevels = 0;
 
1972
                                                                }
 
1973
 
 
1974
                                                                break;
 
1975
                                                        }
 
1976
                                                
 
1977
                                                        ici = (XAnyClassPtr)(((char *)ici) + ici->length);
 
1978
                                                }
 
1979
                                        }
 
1980
                                        else {
 
1981
                                                m_xtablet.StylusID = 0;
 
1982
                                        }
 
1983
                                }
 
1984
                                else if ((m_xtablet.EraserDevice == NULL) &&
 
1985
                                         (is_eraser(device_info[i].name, device_type)))
 
1986
                                {
 
1987
//                                      printf("\tfound eraser\n");
 
1988
                                        m_xtablet.EraserID = device_info[i].id;
 
1989
                                        m_xtablet.EraserDevice = XOpenDevice(m_display, m_xtablet.EraserID);
 
1990
                                        if (m_xtablet.EraserDevice == NULL) m_xtablet.EraserID = 0;
 
1991
                                }
 
1992
 
 
1993
                                if (device_type) {
 
1994
                                        XFree((void *)device_type);
 
1995
                                }
 
1996
                        }
 
1997
 
 
1998
                        /* Restore handler */
 
1999
                        (void) XSetErrorHandler(old_handler);
 
2000
                        (void) XSetIOErrorHandler(old_handler_io);
 
2001
 
 
2002
                        XFreeDeviceList(device_info);
 
2003
                }
 
2004
                XFree(version);
 
2005
        }
 
2006
}
 
2007
 
 
2008
#endif /* WITH_X11_XINPUT */