~siretart/ubuntu/utopic/blender/libav10

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): Matteo F. Vescovi
  • Date: 2012-07-23 08:54:18 UTC
  • mfrom: (14.2.16 sid)
  • mto: (14.2.19 sid)
  • mto: This revision was merged to the branch mainline in revision 42.
  • Revision ID: package-import@ubuntu.com-20120723085418-9foz30v6afaf5ffs
Tags: 2.63a-2
* debian/: Cycles support added (Closes: #658075)
  For now, this top feature has been enabled only
  on [any-amd64 any-i386] architectures because
  of OpenImageIO failing on all others
* debian/: scripts installation path changed
  from /usr/lib to /usr/share:
  + debian/patches/: patchset re-worked for path changing
  + debian/control: "Breaks" field added on yafaray-exporter

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * ***** BEGIN GPL LICENSE BLOCK *****
 
3
 *
 
4
 * This program is free software; you can redistribute it and/or
 
5
 * modify it under the terms of the GNU General Public License
 
6
 * as published by the Free Software Foundation; either version 2
 
7
 * of the License, or (at your option) any later version.
 
8
 *
 
9
 * This program is distributed in the hope that it will be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 * GNU General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU General Public License
 
15
 * along with this program; if not, write to the Free Software Foundation,
 
16
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 
17
 *
 
18
 * Contributor(s): Campbell Barton
 
19
 *
 
20
 * ***** END GPL LICENSE BLOCK *****
 
21
 */
 
22
 
 
23
/** \file ghost/intern/GHOST_SystemSDL.cpp
 
24
 *  \ingroup GHOST
 
25
 */
 
26
 
 
27
#include <assert.h>
 
28
 
 
29
#include "GHOST_SystemSDL.h"
 
30
 
 
31
#include "GHOST_WindowManager.h"
 
32
 
 
33
#include "GHOST_EventCursor.h"
 
34
#include "GHOST_EventKey.h"
 
35
#include "GHOST_EventButton.h"
 
36
#include "GHOST_EventWheel.h"
 
37
 
 
38
GHOST_SystemSDL::GHOST_SystemSDL()
 
39
    :
 
40
      GHOST_System()
 
41
{
 
42
        if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) != 0) {
 
43
                printf ("Error initializing SDL:  %s\n", SDL_GetError());
 
44
        }
 
45
 
 
46
        /* SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); */
 
47
    /* SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4); */
 
48
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
 
49
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
 
50
    SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
 
51
    SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
 
52
    SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
 
53
    SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
 
54
}
 
55
 
 
56
GHOST_SystemSDL::~GHOST_SystemSDL()
 
57
{
 
58
        SDL_Quit();
 
59
}
 
60
 
 
61
GHOST_IWindow *
 
62
GHOST_SystemSDL::createWindow(const STR_String& title,
 
63
                              GHOST_TInt32 left,
 
64
                              GHOST_TInt32 top,
 
65
                              GHOST_TUns32 width,
 
66
                              GHOST_TUns32 height,
 
67
                              GHOST_TWindowState state,
 
68
                              GHOST_TDrawingContextType type,
 
69
                              bool stereoVisual,
 
70
                              const GHOST_TUns16 numOfAASamples,
 
71
                              const GHOST_TEmbedderWindowID parentWindow
 
72
                              )
 
73
{
 
74
        GHOST_WindowSDL *window= NULL;
 
75
 
 
76
        window= new GHOST_WindowSDL (this, title, left, top, width, height, state, parentWindow, type, stereoVisual, 1);
 
77
 
 
78
        if (window) {
 
79
                if (GHOST_kWindowStateFullScreen == state) {
 
80
                        SDL_Window *sdl_win = window->getSDLWindow();
 
81
                        SDL_DisplayMode mode;
 
82
 
 
83
                        static_cast<GHOST_DisplayManagerSDL *> (m_displayManager)->getCurrentDisplayModeSDL(mode);
 
84
 
 
85
                        SDL_SetWindowDisplayMode(sdl_win, &mode);
 
86
                        SDL_ShowWindow(sdl_win);
 
87
                        SDL_SetWindowFullscreen(sdl_win, SDL_TRUE);
 
88
                }
 
89
 
 
90
                if (window->getValid()) {
 
91
                        m_windowManager->addWindow(window);
 
92
                        pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window));
 
93
                }
 
94
                else {
 
95
                        delete window;
 
96
                        window= NULL;
 
97
                }
 
98
        }
 
99
        return window;
 
100
}
 
101
 
 
102
GHOST_TSuccess
 
103
GHOST_SystemSDL::init() {
 
104
        GHOST_TSuccess success = GHOST_System::init();
 
105
 
 
106
        if (success) {
 
107
                m_displayManager = new GHOST_DisplayManagerSDL(this);
 
108
 
 
109
                if (m_displayManager) {
 
110
                        return GHOST_kSuccess;
 
111
                }
 
112
        }
 
113
 
 
114
        return GHOST_kFailure;
 
115
}
 
116
 
 
117
void
 
118
GHOST_SystemSDL::getMainDisplayDimensions(GHOST_TUns32& width,
 
119
                                          GHOST_TUns32& height) const
 
120
{
 
121
        SDL_DisplayMode mode;
 
122
        SDL_GetCurrentDisplayMode(0, &mode); /* note, always 0 display */
 
123
        width= mode.w;
 
124
        height= mode.h;
 
125
}
 
126
 
 
127
GHOST_TUns8
 
128
GHOST_SystemSDL::getNumDisplays() const
 
129
{
 
130
        return SDL_GetNumVideoDisplays();
 
131
}
 
132
 
 
133
GHOST_TSuccess
 
134
GHOST_SystemSDL::getModifierKeys(GHOST_ModifierKeys& keys) const
 
135
{
 
136
        SDL_Keymod mod= SDL_GetModState();
 
137
 
 
138
        keys.set(GHOST_kModifierKeyLeftShift,    (mod & KMOD_LSHIFT) != 0);
 
139
        keys.set(GHOST_kModifierKeyRightShift,   (mod & KMOD_RSHIFT) != 0);
 
140
        keys.set(GHOST_kModifierKeyLeftControl,  (mod & KMOD_LCTRL) != 0);
 
141
        keys.set(GHOST_kModifierKeyRightControl, (mod & KMOD_RCTRL) != 0);
 
142
        keys.set(GHOST_kModifierKeyLeftAlt,      (mod & KMOD_LALT) != 0);
 
143
        keys.set(GHOST_kModifierKeyRightAlt,     (mod & KMOD_RALT) != 0);
 
144
        keys.set(GHOST_kModifierKeyOS,           (mod & (KMOD_LGUI|KMOD_RGUI)) != 0);
 
145
 
 
146
        return GHOST_kSuccess;
 
147
}
 
148
 
 
149
#define GXMAP(k,x,y) case x: k= y; break;
 
150
 
 
151
static GHOST_TKey
 
152
convertSDLKey(SDL_Scancode key)
 
153
{
 
154
        GHOST_TKey type;
 
155
 
 
156
        if ((key >= SDL_SCANCODE_A) && (key <= SDL_SCANCODE_Z)) {
 
157
                type= GHOST_TKey( key - SDL_SCANCODE_A + int(GHOST_kKeyA));
 
158
        } else if ((key >= SDL_SCANCODE_1) && (key <= SDL_SCANCODE_0)) {
 
159
                type= (key == SDL_SCANCODE_0) ? GHOST_kKey0 : GHOST_TKey(key - SDL_SCANCODE_1 + int(GHOST_kKey1));
 
160
        } else if ((key >= SDL_SCANCODE_F1) && (key <= SDL_SCANCODE_F12)) {
 
161
                type= GHOST_TKey(key - SDL_SCANCODE_F1 + int(GHOST_kKeyF1));
 
162
        } else if ((key >= SDL_SCANCODE_F13) && (key <= SDL_SCANCODE_F24)) {
 
163
                type= GHOST_TKey(key - SDL_SCANCODE_F13 + int(GHOST_kKeyF13));
 
164
        } else {
 
165
                switch(key) {
 
166
                        /* TODO SDL_SCANCODE_NONUSBACKSLASH */
 
167
 
 
168
                GXMAP(type,SDL_SCANCODE_BACKSPACE,      GHOST_kKeyBackSpace);
 
169
                GXMAP(type,SDL_SCANCODE_TAB,            GHOST_kKeyTab);
 
170
                GXMAP(type,SDL_SCANCODE_RETURN,         GHOST_kKeyEnter);
 
171
                GXMAP(type,SDL_SCANCODE_ESCAPE,         GHOST_kKeyEsc);
 
172
                GXMAP(type,SDL_SCANCODE_SPACE,          GHOST_kKeySpace);
 
173
 
 
174
                GXMAP(type,SDL_SCANCODE_SEMICOLON,      GHOST_kKeySemicolon);
 
175
                GXMAP(type,SDL_SCANCODE_PERIOD,         GHOST_kKeyPeriod);
 
176
                GXMAP(type,SDL_SCANCODE_COMMA,          GHOST_kKeyComma);
 
177
                GXMAP(type,SDL_SCANCODE_APOSTROPHE,     GHOST_kKeyQuote);
 
178
                GXMAP(type,SDL_SCANCODE_GRAVE,          GHOST_kKeyAccentGrave);
 
179
                GXMAP(type,SDL_SCANCODE_MINUS,          GHOST_kKeyMinus);
 
180
                GXMAP(type,SDL_SCANCODE_EQUALS,         GHOST_kKeyEqual);
 
181
 
 
182
                GXMAP(type,SDL_SCANCODE_SLASH,          GHOST_kKeySlash);
 
183
                GXMAP(type,SDL_SCANCODE_BACKSLASH,      GHOST_kKeyBackslash);
 
184
                GXMAP(type,SDL_SCANCODE_KP_EQUALS,      GHOST_kKeyEqual);
 
185
                GXMAP(type,SDL_SCANCODE_LEFTBRACKET,    GHOST_kKeyLeftBracket);
 
186
                GXMAP(type,SDL_SCANCODE_RIGHTBRACKET,   GHOST_kKeyRightBracket);
 
187
                GXMAP(type,SDL_SCANCODE_PAUSE,          GHOST_kKeyPause);
 
188
 
 
189
                GXMAP(type,SDL_SCANCODE_LSHIFT,         GHOST_kKeyLeftShift);
 
190
                GXMAP(type,SDL_SCANCODE_RSHIFT,         GHOST_kKeyRightShift);
 
191
                GXMAP(type,SDL_SCANCODE_LCTRL,          GHOST_kKeyLeftControl);
 
192
                GXMAP(type,SDL_SCANCODE_RCTRL,          GHOST_kKeyRightControl);
 
193
                GXMAP(type,SDL_SCANCODE_LALT,           GHOST_kKeyLeftAlt);
 
194
                GXMAP(type,SDL_SCANCODE_RALT,           GHOST_kKeyRightAlt);
 
195
                GXMAP(type,SDL_SCANCODE_LGUI,           GHOST_kKeyOS);
 
196
                GXMAP(type,SDL_SCANCODE_RGUI,           GHOST_kKeyOS);
 
197
 
 
198
                GXMAP(type,SDL_SCANCODE_INSERT,         GHOST_kKeyInsert);
 
199
                GXMAP(type,SDL_SCANCODE_DELETE,         GHOST_kKeyDelete);
 
200
                GXMAP(type,SDL_SCANCODE_HOME,           GHOST_kKeyHome);
 
201
                GXMAP(type,SDL_SCANCODE_END,            GHOST_kKeyEnd);
 
202
                GXMAP(type,SDL_SCANCODE_PAGEUP,         GHOST_kKeyUpPage);
 
203
                GXMAP(type,SDL_SCANCODE_PAGEDOWN,       GHOST_kKeyDownPage);
 
204
 
 
205
                GXMAP(type,SDL_SCANCODE_LEFT,           GHOST_kKeyLeftArrow);
 
206
                GXMAP(type,SDL_SCANCODE_RIGHT,          GHOST_kKeyRightArrow);
 
207
                GXMAP(type,SDL_SCANCODE_UP,             GHOST_kKeyUpArrow);
 
208
                GXMAP(type,SDL_SCANCODE_DOWN,           GHOST_kKeyDownArrow);
 
209
 
 
210
                GXMAP(type,SDL_SCANCODE_CAPSLOCK,       GHOST_kKeyCapsLock);
 
211
                GXMAP(type,SDL_SCANCODE_SCROLLLOCK,     GHOST_kKeyScrollLock);
 
212
                GXMAP(type,SDL_SCANCODE_NUMLOCKCLEAR,   GHOST_kKeyNumLock);
 
213
                GXMAP(type,SDL_SCANCODE_PRINTSCREEN,    GHOST_kKeyPrintScreen);
 
214
 
 
215
                /* keypad events */
 
216
 
 
217
                /* note, sdl defines a bunch of kp defines I never saw before like
 
218
                 * SDL_SCANCODE_KP_PERCENT, SDL_SCANCODE_KP_XOR - campbell */
 
219
                GXMAP(type,SDL_SCANCODE_KP_0,           GHOST_kKeyNumpad0);
 
220
                GXMAP(type,SDL_SCANCODE_KP_1,           GHOST_kKeyNumpad1);
 
221
                GXMAP(type,SDL_SCANCODE_KP_2,           GHOST_kKeyNumpad2);
 
222
                GXMAP(type,SDL_SCANCODE_KP_3,           GHOST_kKeyNumpad3);
 
223
                GXMAP(type,SDL_SCANCODE_KP_4,           GHOST_kKeyNumpad4);
 
224
                GXMAP(type,SDL_SCANCODE_KP_5,           GHOST_kKeyNumpad5);
 
225
                GXMAP(type,SDL_SCANCODE_KP_6,           GHOST_kKeyNumpad6);
 
226
                GXMAP(type,SDL_SCANCODE_KP_7,           GHOST_kKeyNumpad7);
 
227
                GXMAP(type,SDL_SCANCODE_KP_8,           GHOST_kKeyNumpad8);
 
228
                GXMAP(type,SDL_SCANCODE_KP_9,           GHOST_kKeyNumpad9);
 
229
                GXMAP(type,SDL_SCANCODE_KP_PERIOD,      GHOST_kKeyNumpadPeriod);
 
230
 
 
231
        GXMAP(type,SDL_SCANCODE_KP_ENTER,       GHOST_kKeyNumpadEnter);
 
232
        GXMAP(type,SDL_SCANCODE_KP_PLUS,        GHOST_kKeyNumpadPlus);
 
233
        GXMAP(type,SDL_SCANCODE_KP_MINUS,       GHOST_kKeyNumpadMinus);
 
234
        GXMAP(type,SDL_SCANCODE_KP_MULTIPLY,    GHOST_kKeyNumpadAsterisk);
 
235
        GXMAP(type,SDL_SCANCODE_KP_DIVIDE,      GHOST_kKeyNumpadSlash);
 
236
 
 
237
        /* Media keys in some keyboards and laptops with XFree86/Xorg */
 
238
        GXMAP(type,SDL_SCANCODE_AUDIOPLAY,      GHOST_kKeyMediaPlay);
 
239
        GXMAP(type,SDL_SCANCODE_AUDIOSTOP,      GHOST_kKeyMediaStop);
 
240
        GXMAP(type,SDL_SCANCODE_AUDIOPREV,      GHOST_kKeyMediaFirst);
 
241
        // GXMAP(type,XF86XK_AudioRewind,       GHOST_kKeyMediaFirst);
 
242
        GXMAP(type,SDL_SCANCODE_AUDIONEXT,      GHOST_kKeyMediaLast);
 
243
 
 
244
                default:
 
245
                        printf("Unknown\n");
 
246
                        type= GHOST_kKeyUnknown;
 
247
                        break;
 
248
                }
 
249
        }
 
250
 
 
251
        return type;
 
252
}
 
253
#undef GXMAP
 
254
 
 
255
 
 
256
void
 
257
GHOST_SystemSDL::processEvent(SDL_Event *sdl_event)
 
258
{
 
259
        GHOST_Event * g_event= NULL;
 
260
 
 
261
        switch(sdl_event->type) {
 
262
        case SDL_WINDOWEVENT:
 
263
                {
 
264
                        SDL_WindowEvent &sdl_sub_evt= sdl_event->window;
 
265
                        GHOST_WindowSDL *window= findGhostWindow(SDL_GetWindowFromID(sdl_sub_evt.windowID));
 
266
                        //assert(window != NULL); // can be NULL on close window.
 
267
 
 
268
                        switch (sdl_sub_evt.event) {
 
269
                        case SDL_WINDOWEVENT_EXPOSED:
 
270
                                g_event= new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowUpdate, window);
 
271
                                break;
 
272
                        case SDL_WINDOWEVENT_RESIZED:
 
273
                                g_event= new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window);
 
274
                                break;
 
275
                        case SDL_WINDOWEVENT_MOVED:
 
276
                                g_event= new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowMove, window);
 
277
                                break;
 
278
                        case SDL_WINDOWEVENT_FOCUS_GAINED:
 
279
                                g_event= new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowActivate, window);
 
280
                                break;
 
281
                        case SDL_WINDOWEVENT_FOCUS_LOST:
 
282
                                g_event= new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowDeactivate, window);
 
283
                                break;
 
284
                        case SDL_WINDOWEVENT_CLOSE:
 
285
                                g_event= new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowClose, window);
 
286
                                break;
 
287
                        }
 
288
                }
 
289
                break;
 
290
        case SDL_QUIT:
 
291
                g_event= new GHOST_Event(getMilliSeconds(), GHOST_kEventQuit, NULL);
 
292
                break;
 
293
 
 
294
        case SDL_MOUSEMOTION:
 
295
                {
 
296
                        SDL_MouseMotionEvent &sdl_sub_evt= sdl_event->motion;
 
297
                        SDL_Window *sdl_win= SDL_GetWindowFromID(sdl_sub_evt.windowID);
 
298
                        GHOST_WindowSDL *window= findGhostWindow(sdl_win);
 
299
                        assert(window != NULL);
 
300
 
 
301
                        int x_win, y_win;
 
302
                        SDL_GetWindowPosition(sdl_win, &x_win, &y_win);
 
303
 
 
304
                        GHOST_TInt32 x_root= sdl_sub_evt.x + x_win;
 
305
                        GHOST_TInt32 y_root= sdl_sub_evt.y + y_win;
 
306
 
 
307
#if 0
 
308
                        if(window->getCursorGrabMode() != GHOST_kGrabDisable && window->getCursorGrabMode() != GHOST_kGrabNormal)
 
309
                        {
 
310
                                GHOST_TInt32 x_new= x_root;
 
311
                                GHOST_TInt32 y_new= y_root;
 
312
                                GHOST_TInt32 x_accum, y_accum;
 
313
                                GHOST_Rect bounds;
 
314
 
 
315
                                /* fallback to window bounds */
 
316
                                if(window->getCursorGrabBounds(bounds)==GHOST_kFailure)
 
317
                                        window->getClientBounds(bounds);
 
318
 
 
319
                                /* could also clamp to screen bounds
 
320
                                 * wrap with a window outside the view will fail atm  */
 
321
                                bounds.wrapPoint(x_new, y_new, 8); /* offset of one incase blender is at screen bounds */
 
322
                                window->getCursorGrabAccum(x_accum, y_accum);
 
323
 
 
324
                                // cant use setCursorPosition because the mouse may have no focus!
 
325
                                if(x_new != x_root || y_new != y_root) {
 
326
                                        if (1 ) { //xme.time > m_last_warp) {
 
327
                                                /* when wrapping we don't need to add an event because the
 
328
                                                 * setCursorPosition call will cause a new event after */
 
329
                                                SDL_WarpMouseInWindow(sdl_win, x_new - x_win, y_new - y_win); /* wrap */
 
330
                                                window->setCursorGrabAccum(x_accum + (x_root - x_new), y_accum + (y_root - y_new));
 
331
                                                // m_last_warp= lastEventTime(xme.time);
 
332
                                        } else {
 
333
                                                // setCursorPosition(x_new, y_new); /* wrap but don't accumulate */
 
334
                                                SDL_WarpMouseInWindow(sdl_win, x_new - x_win, y_new - y_win);
 
335
                                        }
 
336
 
 
337
                                        g_event = new GHOST_EventCursor(getMilliSeconds(), GHOST_kEventCursorMove, window, x_new, y_new);
 
338
                                }
 
339
                                else {
 
340
                                        g_event = new GHOST_EventCursor(getMilliSeconds(), GHOST_kEventCursorMove, window, x_root + x_accum, y_root + y_accum);
 
341
                                }
 
342
                        }
 
343
                        else
 
344
#endif
 
345
                        {
 
346
                                g_event= new GHOST_EventCursor(getMilliSeconds(), GHOST_kEventCursorMove, window, x_root, y_root);
 
347
                        }
 
348
                        break;
 
349
                }
 
350
        case SDL_MOUSEBUTTONUP:
 
351
        case SDL_MOUSEBUTTONDOWN:
 
352
                {
 
353
                        SDL_MouseButtonEvent &sdl_sub_evt= sdl_event->button;
 
354
                        GHOST_TButtonMask gbmask= GHOST_kButtonMaskLeft;
 
355
                        GHOST_TEventType type= (sdl_sub_evt.state==SDL_PRESSED) ? GHOST_kEventButtonDown : GHOST_kEventButtonUp;
 
356
 
 
357
                        GHOST_WindowSDL *window= findGhostWindow(SDL_GetWindowFromID(sdl_sub_evt.windowID));
 
358
                        assert(window != NULL);
 
359
 
 
360
                        /* process rest of normal mouse buttons */
 
361
                        if(sdl_sub_evt.button == SDL_BUTTON_LEFT)
 
362
                                gbmask= GHOST_kButtonMaskLeft;
 
363
                        else if(sdl_sub_evt.button == SDL_BUTTON_MIDDLE)
 
364
                                gbmask= GHOST_kButtonMaskMiddle;
 
365
                        else if(sdl_sub_evt.button == SDL_BUTTON_RIGHT)
 
366
                                gbmask= GHOST_kButtonMaskRight;
 
367
                        /* these buttons are untested! */
 
368
                        else if(sdl_sub_evt.button == SDL_BUTTON_X1)
 
369
                                gbmask= GHOST_kButtonMaskButton4;
 
370
                        else if(sdl_sub_evt.button == SDL_BUTTON_X2)
 
371
                                gbmask= GHOST_kButtonMaskButton5;
 
372
                        else
 
373
                                break;
 
374
 
 
375
                        g_event= new GHOST_EventButton(getMilliSeconds(), type, window, gbmask);
 
376
                        break;
 
377
                }
 
378
        case SDL_MOUSEWHEEL:
 
379
                {
 
380
                        SDL_MouseWheelEvent &sdl_sub_evt= sdl_event->wheel;
 
381
                        GHOST_WindowSDL *window= findGhostWindow(SDL_GetWindowFromID(sdl_sub_evt.windowID));
 
382
                        assert(window != NULL);
 
383
                        g_event= new GHOST_EventWheel(getMilliSeconds(), window, sdl_sub_evt.y);
 
384
                }
 
385
                break;
 
386
        case SDL_KEYDOWN:
 
387
        case SDL_KEYUP:
 
388
                {
 
389
                        SDL_KeyboardEvent &sdl_sub_evt= sdl_event->key;
 
390
                        SDL_Keycode sym= sdl_sub_evt.keysym.sym;
 
391
                        GHOST_TEventType type= (sdl_sub_evt.state == SDL_PRESSED) ? GHOST_kEventKeyDown : GHOST_kEventKeyUp;
 
392
 
 
393
                        GHOST_WindowSDL *window= findGhostWindow(SDL_GetWindowFromID(sdl_sub_evt.windowID));
 
394
                        assert(window != NULL);
 
395
 
 
396
                        GHOST_TKey gkey= convertSDLKey(sdl_sub_evt.keysym.scancode);
 
397
                        /* note, the sdl_sub_evt.keysym.sym is truncated, for unicode support ghost has to be modified */
 
398
                        /* printf("%d\n", sym); */
 
399
                        if(sym > 127) {
 
400
                                switch(sym) {
 
401
                                        case SDLK_KP_DIVIDE: sym= '/'; break;
 
402
                                    case SDLK_KP_MULTIPLY: sym= '*'; break;
 
403
                                    case SDLK_KP_MINUS: sym= '-'; break;
 
404
                                    case SDLK_KP_PLUS: sym= '+'; break;
 
405
                                    case SDLK_KP_1: sym= '1'; break;
 
406
                                    case SDLK_KP_2: sym= '2'; break;
 
407
                                    case SDLK_KP_3: sym= '3'; break;
 
408
                                    case SDLK_KP_4: sym= '4'; break;
 
409
                                    case SDLK_KP_5: sym= '5'; break;
 
410
                                    case SDLK_KP_6: sym= '6'; break;
 
411
                                    case SDLK_KP_7: sym= '7'; break;
 
412
                                    case SDLK_KP_8: sym= '8'; break;
 
413
                                    case SDLK_KP_9: sym= '9'; break;
 
414
                                    case SDLK_KP_0: sym= '0'; break;
 
415
                                    case SDLK_KP_PERIOD: sym= '.'; break;
 
416
                                        default: sym= 0; break;
 
417
                                }
 
418
                        }
 
419
                        else {
 
420
                                if(sdl_sub_evt.keysym.mod & (KMOD_LSHIFT|KMOD_RSHIFT)) {
 
421
                                        /* lame US keyboard assumptions */
 
422
                                        if(sym >= 'a' && sym <= ('a' + 32)) {
 
423
                                                sym -= 32;
 
424
                                        }
 
425
                                        else {
 
426
                                                switch(sym) {
 
427
                                                        case '`': sym= '~'; break;
 
428
                                                        case '1': sym= '!'; break;
 
429
                                                        case '2': sym= '@'; break;
 
430
                                                        case '3': sym= '#'; break;
 
431
                                                        case '4': sym= '$'; break;
 
432
                                                        case '5': sym= '%'; break;
 
433
                                                        case '6': sym= '^'; break;
 
434
                                                        case '7': sym= '&'; break;
 
435
                                                        case '8': sym= '*'; break;
 
436
                                                        case '9': sym= '('; break;
 
437
                                                        case '0': sym= ')'; break;
 
438
                                                        case '-': sym= '_'; break;
 
439
                                                        case '=': sym= '+'; break;
 
440
                                                        case '[': sym= '{'; break;
 
441
                                                        case ']': sym= '}'; break;
 
442
                                                        case '\\': sym= '|'; break;
 
443
                                                        case ';': sym= ':'; break;
 
444
                                                        case '\'': sym= '"'; break;
 
445
                                                        case ',': sym= '<'; break;
 
446
                                                        case '.': sym= '>'; break;
 
447
                                                        case '/': sym= '?'; break;
 
448
                                                        default:            break;
 
449
                                                }
 
450
                                        }
 
451
                                }
 
452
                        }
 
453
 
 
454
                        g_event= new GHOST_EventKey(getMilliSeconds(), type, window, gkey, sym, NULL);
 
455
                }
 
456
                break;
 
457
        }
 
458
 
 
459
        if (g_event) {
 
460
                pushEvent(g_event);
 
461
        }
 
462
}
 
463
 
 
464
GHOST_TSuccess
 
465
GHOST_SystemSDL::getCursorPosition(GHOST_TInt32& x,
 
466
                                   GHOST_TInt32& y) const
 
467
{
 
468
        int x_win, y_win;
 
469
        SDL_Window *win= SDL_GetMouseFocus();
 
470
        SDL_GetWindowPosition(win, &x_win, &y_win);
 
471
 
 
472
        int xi, yi;
 
473
        SDL_GetMouseState(&xi, &yi);
 
474
        x= xi + x_win;
 
475
        y= yi + x_win;
 
476
 
 
477
        return GHOST_kSuccess;
 
478
}
 
479
 
 
480
GHOST_TSuccess
 
481
GHOST_SystemSDL::setCursorPosition(GHOST_TInt32 x,
 
482
                                   GHOST_TInt32 y)
 
483
{
 
484
        int x_win, y_win;
 
485
        SDL_Window *win= SDL_GetMouseFocus();
 
486
        SDL_GetWindowPosition(win, &x_win, &y_win);
 
487
 
 
488
        SDL_WarpMouseInWindow(win, x - x_win, y - y_win);
 
489
        return GHOST_kSuccess;
 
490
}
 
491
 
 
492
bool
 
493
GHOST_SystemSDL::generateWindowExposeEvents()
 
494
{
 
495
        std::vector<GHOST_WindowSDL *>::iterator w_start= m_dirty_windows.begin();
 
496
        std::vector<GHOST_WindowSDL *>::const_iterator w_end= m_dirty_windows.end();
 
497
        bool anyProcessed= false;
 
498
 
 
499
        for (;w_start != w_end; ++w_start) {
 
500
                GHOST_Event * g_event= new
 
501
                        GHOST_Event(
 
502
                                getMilliSeconds(),
 
503
                                GHOST_kEventWindowUpdate,
 
504
                                *w_start
 
505
                        );
 
506
 
 
507
                (*w_start)->validate();
 
508
 
 
509
                if (g_event) {
 
510
                        printf("Expose events pushed\n");
 
511
                        pushEvent(g_event);
 
512
                        anyProcessed= true;
 
513
                }
 
514
        }
 
515
 
 
516
        m_dirty_windows.clear();
 
517
        return anyProcessed;
 
518
}
 
519
 
 
520
 
 
521
bool
 
522
GHOST_SystemSDL::processEvents(bool waitForEvent)
 
523
{
 
524
        // Get all the current events -- translate them into
 
525
        // ghost events and call base class pushEvent() method.
 
526
 
 
527
        bool anyProcessed= false;
 
528
 
 
529
        do {
 
530
                GHOST_TimerManager* timerMgr= getTimerManager();
 
531
 
 
532
                if (waitForEvent && m_dirty_windows.empty() && !SDL_HasEvents(SDL_FIRSTEVENT, SDL_LASTEVENT)) {
 
533
                        GHOST_TUns64 next= timerMgr->nextFireTime();
 
534
 
 
535
                        if (next==GHOST_kFireTimeNever) {
 
536
                                SDL_WaitEventTimeout(NULL, -1);
 
537
                                //SleepTillEvent(m_display, -1);
 
538
                        } else {
 
539
                                GHOST_TInt64 maxSleep= next - getMilliSeconds();
 
540
 
 
541
                                if(maxSleep >= 0) {
 
542
                                        SDL_WaitEventTimeout(NULL, next - getMilliSeconds());
 
543
                                        // SleepTillEvent(m_display, next - getMilliSeconds()); // X11
 
544
                                }
 
545
                        }
 
546
                }
 
547
 
 
548
                if (timerMgr->fireTimers(getMilliSeconds())) {
 
549
                        anyProcessed= true;
 
550
                }
 
551
 
 
552
                SDL_Event sdl_event;
 
553
                while (SDL_PollEvent(&sdl_event)) {
 
554
                        processEvent(&sdl_event);
 
555
                        anyProcessed= true;
 
556
                }
 
557
 
 
558
                if (generateWindowExposeEvents()) {
 
559
                        anyProcessed= true;
 
560
                }
 
561
        } while (waitForEvent && !anyProcessed);
 
562
 
 
563
        return anyProcessed;
 
564
}
 
565
 
 
566
 
 
567
GHOST_WindowSDL *
 
568
GHOST_SystemSDL::findGhostWindow(SDL_Window *sdl_win)
 
569
{
 
570
        if (sdl_win == NULL) return NULL;
 
571
 
 
572
        // It is not entirely safe to do this as the backptr may point
 
573
        // to a window that has recently been removed.
 
574
        // We should always check the window manager's list of windows
 
575
        // and only process events on these windows.
 
576
 
 
577
        std::vector<GHOST_IWindow *> & win_vec= m_windowManager->getWindows();
 
578
 
 
579
        std::vector<GHOST_IWindow *>::iterator win_it= win_vec.begin();
 
580
        std::vector<GHOST_IWindow *>::const_iterator win_end= win_vec.end();
 
581
 
 
582
        for (; win_it != win_end; ++win_it) {
 
583
                GHOST_WindowSDL * window= static_cast<GHOST_WindowSDL *>(*win_it);
 
584
                if (window->getSDLWindow() == sdl_win) {
 
585
                        return window;
 
586
                }
 
587
        }
 
588
        return NULL;
 
589
}
 
590
 
 
591
 
 
592
void
 
593
GHOST_SystemSDL::addDirtyWindow(GHOST_WindowSDL *bad_wind)
 
594
{
 
595
        GHOST_ASSERT((bad_wind != NULL), "addDirtyWindow() NULL ptr trapped (window)");
 
596
 
 
597
        m_dirty_windows.push_back(bad_wind);
 
598
}
 
599
 
 
600
 
 
601
GHOST_TSuccess GHOST_SystemSDL::getButtons(GHOST_Buttons& buttons) const
 
602
{
 
603
        Uint8 state= SDL_GetMouseState(NULL, NULL);
 
604
        buttons.set(GHOST_kButtonMaskLeft,   (state & SDL_BUTTON_LMASK) != 0);
 
605
        buttons.set(GHOST_kButtonMaskMiddle, (state & SDL_BUTTON_MMASK) != 0);
 
606
        buttons.set(GHOST_kButtonMaskRight,  (state & SDL_BUTTON_RMASK) != 0);
 
607
 
 
608
        return GHOST_kSuccess;
 
609
}
 
610
 
 
611
GHOST_TUns8 *
 
612
GHOST_SystemSDL::getClipboard(bool selection) const
 
613
{
 
614
        return (GHOST_TUns8 *)SDL_GetClipboardText();
 
615
}
 
616
 
 
617
void
 
618
GHOST_SystemSDL::putClipboard(GHOST_TInt8 *buffer, bool selection) const
 
619
{
 
620
        SDL_SetClipboardText(buffer);
 
621
}
 
622
 
 
623
GHOST_TUns64
 
624
GHOST_SystemSDL::getMilliSeconds()
 
625
{
 
626
        return GHOST_TUns64(SDL_GetTicks()); /* note, 32 -> 64bits */
 
627
}