- removed debug prints that had no meaning to most people
[blender.git] / source / blender / src / ghostwinlay.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  */
32 #include <stdlib.h>
33 #include <stdio.h>
34
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
38
39 #ifdef WIN32
40 #include "BLI_winstuff.h"
41 #endif
42
43 #include "MEM_guardedalloc.h"
44
45 #include "DNA_listBase.h"       
46 #include "DNA_userdef_types.h"  /* U.flag & TWOBUTTONMOUSE */
47
48 #include "BLI_blenlib.h"
49
50 #include "GHOST_C-api.h"
51
52 #include "BKE_utildefines.h"
53 #include "BKE_global.h"
54
55 #include "BIF_gl.h"
56 #include "BIF_graphics.h"
57 #include "BIF_mywindow.h"
58 #include "BIF_screen.h"
59 #include "BIF_usiblender.h"
60 #include "BIF_cursors.h"
61
62 #include "mydevice.h"
63 #include "blendef.h"
64
65 #include "winlay.h"
66
67 ///
68
69 struct _Window {
70         GHOST_WindowHandle      ghostwin;
71         
72                 /* Handler and private data for handler */
73         WindowHandlerFP         handler;
74         void                            *user_data;
75         
76                 /* Window state */
77         int             size[2], position[2];
78         int             active, visible;
79         
80                 /* Last known mouse/button/qualifier state */
81         int             lmouse[2];
82         int             lqual;          /* (LR_SHFTKEY, LR_CTRLKEY, LR_ALTKEY) */
83         int             lmbut;          /* (L_MOUSE, M_MOUSE, R_MOUSE) */
84         int             commandqual;
85
86                 /* Tracks the faked mouse button, if non-zero it is
87                  * the event number of the last faked button.
88                  */
89         int             faked_mbut;
90
91         GHOST_TimerTaskHandle   timer;
92         int                                             timer_event;
93 };
94
95 ///
96
97 static GHOST_SystemHandle g_system= 0;
98
99         /* Some simple ghost <-> blender conversions */
100         
101 static GHOST_TStandardCursor convert_cursor(int curs) {
102         switch(curs) {
103         default:
104         case CURSOR_STD:                return GHOST_kStandardCursorDefault;
105         case CURSOR_VPAINT:             return GHOST_kStandardCursorRightArrow;
106         case CURSOR_FACESEL:            return GHOST_kStandardCursorRightArrow;
107         case CURSOR_WAIT:               return GHOST_kStandardCursorWait;
108         case CURSOR_EDIT:               return GHOST_kStandardCursorCrosshair;
109         case CURSOR_HELP:               return GHOST_kStandardCursorHelp;
110         case CURSOR_X_MOVE:             return GHOST_kStandardCursorLeftRight;
111         case CURSOR_Y_MOVE:             return GHOST_kStandardCursorUpDown;
112         case CURSOR_PENCIL:             return GHOST_kStandardCursorPencil;
113         }
114 }
115
116 static int convert_mbut(GHOST_TButtonMask but) {
117         if (but == GHOST_kButtonMaskLeft) {
118                 return LEFTMOUSE;
119         } else if (but == GHOST_kButtonMaskRight) {
120                 return RIGHTMOUSE;
121         } else {
122                 return MIDDLEMOUSE;
123         }
124 }
125
126 static int convert_key(GHOST_TKey key) {
127         if (key>=GHOST_kKeyA && key<=GHOST_kKeyZ) {
128                 return (AKEY + ((int) key - GHOST_kKeyA));
129         } else if (key>=GHOST_kKey0 && key<=GHOST_kKey9) {
130                 return (ZEROKEY + ((int) key - GHOST_kKey0));
131         } else if (key>=GHOST_kKeyNumpad0 && key<=GHOST_kKeyNumpad9) {
132                 return (PAD0 + ((int) key - GHOST_kKeyNumpad0));
133         } else if (key>=GHOST_kKeyF1 && key<=GHOST_kKeyF12) {
134                 return (F1KEY + ((int) key - GHOST_kKeyF1));
135         } else {
136                 switch (key) {
137                 case GHOST_kKeyBackSpace:               return BACKSPACEKEY;
138                 case GHOST_kKeyTab:                             return TABKEY;
139                 case GHOST_kKeyLinefeed:                return LINEFEEDKEY;
140                 case GHOST_kKeyClear:                   return 0;
141                 case GHOST_kKeyEnter:                   return RETKEY;
142         
143                 case GHOST_kKeyEsc:                             return ESCKEY;
144                 case GHOST_kKeySpace:                   return SPACEKEY;
145                 case GHOST_kKeyQuote:                   return QUOTEKEY;
146                 case GHOST_kKeyComma:                   return COMMAKEY;
147                 case GHOST_kKeyMinus:                   return MINUSKEY;
148                 case GHOST_kKeyPeriod:                  return PERIODKEY;
149                 case GHOST_kKeySlash:                   return SLASHKEY;
150
151                 case GHOST_kKeySemicolon:               return SEMICOLONKEY;
152                 case GHOST_kKeyEqual:                   return EQUALKEY;
153
154                 case GHOST_kKeyLeftBracket:             return LEFTBRACKETKEY;
155                 case GHOST_kKeyRightBracket:    return RIGHTBRACKETKEY;
156                 case GHOST_kKeyBackslash:               return BACKSLASHKEY;
157                 case GHOST_kKeyAccentGrave:             return ACCENTGRAVEKEY;
158
159                 case GHOST_kKeyLeftShift:               return LEFTSHIFTKEY;
160                 case GHOST_kKeyRightShift:              return RIGHTSHIFTKEY;
161                 case GHOST_kKeyLeftControl:             return LEFTCTRLKEY;
162                 case GHOST_kKeyRightControl:    return RIGHTCTRLKEY;
163                 case GHOST_kKeyLeftAlt:                 return LEFTALTKEY;
164                 case GHOST_kKeyRightAlt:                return RIGHTALTKEY;
165
166                 case GHOST_kKeyCapsLock:                return CAPSLOCKKEY;
167                 case GHOST_kKeyNumLock:                 return 0;
168                 case GHOST_kKeyScrollLock:              return 0;
169
170                 case GHOST_kKeyLeftArrow:               return LEFTARROWKEY;
171                 case GHOST_kKeyRightArrow:              return RIGHTARROWKEY;
172                 case GHOST_kKeyUpArrow:                 return UPARROWKEY;
173                 case GHOST_kKeyDownArrow:               return DOWNARROWKEY;
174
175                 case GHOST_kKeyPrintScreen:             return 0;
176                 case GHOST_kKeyPause:                   return PAUSEKEY;
177
178                 case GHOST_kKeyInsert:                  return INSERTKEY;
179                 case GHOST_kKeyDelete:                  return DELKEY;
180                 case GHOST_kKeyHome:                    return HOMEKEY;
181                 case GHOST_kKeyEnd:                             return ENDKEY;
182                 case GHOST_kKeyUpPage:                  return PAGEUPKEY;
183                 case GHOST_kKeyDownPage:                return PAGEDOWNKEY;
184
185                 case GHOST_kKeyNumpadPeriod:    return PADPERIOD;
186                 case GHOST_kKeyNumpadEnter:             return PADENTER;
187                 case GHOST_kKeyNumpadPlus:              return PADPLUSKEY;
188                 case GHOST_kKeyNumpadMinus:             return PADMINUS;
189                 case GHOST_kKeyNumpadAsterisk:  return PADASTERKEY;
190                 case GHOST_kKeyNumpadSlash:             return PADSLASHKEY;
191                 case GHOST_kKeyUnknown:                 return UNKNOWNKEY;
192
193                 default:
194                         return 0;
195                 }
196         }
197 }
198
199         /***/
200         
201
202 static Window *window_new(GHOST_WindowHandle ghostwin)
203 {
204         Window *win= MEM_callocN(sizeof(*win), "Window");
205         win->ghostwin= ghostwin;
206         
207         return win;
208 }
209
210 static void window_handle(Window *win, short event, short val)
211 {
212         if (win->handler) {
213                 win->handler(win, win->user_data, event, val, 0);
214         }
215 }
216
217 static void window_handle_ext(Window *win, short event, short val, short extra)
218 {
219         if (win->handler) {
220                 win->handler(win, win->user_data, event, val, extra);
221         }
222 }
223
224 static void window_free(Window *win) 
225 {
226         MEM_freeN(win);
227 }
228
229         /***/
230
231 static Window *active_gl_window= NULL;
232
233 Window *window_open(char *title, int posx, int posy, int sizex, int sizey, int start_maximized)
234 {
235         GHOST_WindowHandle ghostwin;
236         GHOST_TWindowState inital_state;
237         int scr_w, scr_h;
238
239         winlay_get_screensize(&scr_w, &scr_h);
240         posy= (scr_h-posy-sizey);
241         
242         /* create a fullscreen window on unix by default*/
243 #if !defined(WIN32) && !defined(__APPLE__)
244         inital_state= start_maximized?
245                 GHOST_kWindowStateFullScreen:GHOST_kWindowStateNormal;
246 #else
247 #ifdef _WIN32   // FULLSCREEN
248         if (start_maximized == G_WINDOWSTATE_FULLSCREEN)
249                 inital_state= GHOST_kWindowStateFullScreen;
250         else
251                 inital_state= start_maximized?GHOST_kWindowStateMaximized:GHOST_kWindowStateNormal;
252 #else                   // APPLE
253         inital_state= start_maximized?GHOST_kWindowStateMaximized:GHOST_kWindowStateNormal;
254 #endif
255 #endif
256
257         ghostwin= GHOST_CreateWindow(g_system, 
258                                                                 title, 
259                                                                 posx, posy, sizex, sizey, 
260                                                                 inital_state, 
261                                                                 GHOST_kDrawingContextTypeOpenGL,
262                                                                 0 /* no stereo */);
263         
264         if (ghostwin) {
265                 Window *win= window_new(ghostwin);
266                 
267                 if (win) {
268                         GHOST_SetWindowUserData(ghostwin, win);
269                         
270                         win->position[0]= posx;
271                         win->position[1]= posy;
272                         win->size[0]= sizex;
273                         win->size[1]= sizey;
274                         
275                         win->lmouse[0]= win->size[0]/2;
276                         win->lmouse[1]= win->size[1]/2;
277                 } else {
278                         GHOST_DisposeWindow(g_system, ghostwin);
279                 }
280                 
281                 return win;
282         } else {
283                 return NULL;
284         }
285 }
286
287 void window_set_handler(Window *win, WindowHandlerFP handler, void *user_data)
288 {
289         win->handler= handler;
290         win->user_data= user_data;
291 }
292
293 static void window_timer_proc(GHOST_TimerTaskHandle timer, GHOST_TUns64 time)
294 {
295         Window *win= GHOST_GetTimerTaskUserData(timer);
296
297         win->handler(win, win->user_data, win->timer_event, 0, 0);
298 }
299
300 void window_set_timer(Window *win, int delay_ms, int event)
301 {
302         if (win->timer) GHOST_RemoveTimer(g_system, win->timer);
303
304         win->timer_event= event;
305         win->timer= GHOST_InstallTimer(g_system, delay_ms, delay_ms, window_timer_proc, win);
306 }
307
308 void window_destroy(Window *win) {
309         if (active_gl_window==win) {
310                 active_gl_window= NULL;
311         }
312         
313         if (win->timer) {
314                 GHOST_RemoveTimer(g_system, win->timer);
315                 win->timer= NULL;
316         }
317
318         GHOST_DisposeWindow(g_system, win->ghostwin);
319         window_free(win);
320 }
321
322 void window_set_cursor(Window *win, int curs) {
323         if (curs==CURSOR_NONE) {
324                 GHOST_SetCursorVisibility(win->ghostwin, 0);
325         } else {
326                 GHOST_SetCursorVisibility(win->ghostwin, 1);
327                 GHOST_SetCursorShape(win->ghostwin, convert_cursor(curs));
328         }
329 }
330
331 void window_set_custom_cursor(Window *win, unsigned char mask[16][2], 
332                                         unsigned char bitmap[16][2], int hotx, int hoty) {
333         GHOST_SetCustomCursorShape(win->ghostwin, bitmap, mask, hotx, hoty);
334 }
335
336 void window_set_custom_cursor_ex(Window *win, BCursor *cursor, int useBig) {
337         if (useBig) {
338                 GHOST_SetCustomCursorShapeEx(win->ghostwin, 
339                         cursor->big_bm, cursor->big_mask, 
340                         cursor->big_sizex,cursor->big_sizey,
341                         cursor->big_hotx,cursor->big_hoty,
342                         cursor->fg_color, cursor->bg_color);
343         } else {
344                 GHOST_SetCustomCursorShapeEx(win->ghostwin, 
345                         cursor->small_bm, cursor->small_mask, 
346                         cursor->small_sizex,cursor->small_sizey,
347                         cursor->small_hotx,cursor->small_hoty,
348                         cursor->fg_color, cursor->bg_color);
349         }
350 }
351
352 void window_make_active(Window *win) {
353         if (win != active_gl_window) {
354                 active_gl_window= win;
355                 GHOST_ActivateWindowDrawingContext(win->ghostwin);
356         }
357 }
358
359 void window_swap_buffers(Window *win) {
360         GHOST_SwapWindowBuffers(win->ghostwin);
361 }
362
363 static int query_qual(char qual) {
364         GHOST_TModifierKeyMask left, right;
365         int val= 0;
366         
367         if (qual=='s') {
368                 left= GHOST_kModifierKeyLeftShift;
369                 right= GHOST_kModifierKeyRightShift;
370         } else if (qual=='c') {
371                 left= GHOST_kModifierKeyLeftControl;
372                 right= GHOST_kModifierKeyRightControl;
373         } else if (qual=='C') {
374                 left= right= GHOST_kModifierKeyCommand;
375         } else {
376                 left= GHOST_kModifierKeyLeftAlt;
377                 right= GHOST_kModifierKeyRightAlt;
378         }
379
380         GHOST_GetModifierKeyState(g_system, left, &val);
381         if (!val)
382                 GHOST_GetModifierKeyState(g_system, right, &val);
383         
384         return val;
385 }
386
387 static int change_bit(int val, int bit, int to_on) {
388         return to_on?(val|bit):(val&~bit);
389 }
390
391 static int event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private) 
392 {
393         GHOST_TEventType type= GHOST_GetEventType(evt);
394
395         if (type == GHOST_kEventQuit) {
396                 exit_usiblender();
397         } else {
398                 GHOST_WindowHandle ghostwin= GHOST_GetEventWindow(evt);
399                 GHOST_TEventDataPtr data= GHOST_GetEventData(evt);
400                 Window *win;
401                 
402                 if (!ghostwin) {
403                         // XXX - should be checked, why are we getting an event here, and
404                         //      what is it?
405
406                         return 1;
407                 } else if (!GHOST_ValidWindow(g_system, ghostwin)) {
408                         // XXX - should be checked, why are we getting an event here, and
409                         //      what is it?
410
411                         return 1;
412                 } else {
413                         win= GHOST_GetWindowUserData(ghostwin);
414                 }
415                 
416                 switch (type) {
417                 case GHOST_kEventCursorMove: {
418                         if(win->active == 1) {
419                                 GHOST_TEventCursorData *cd= data;
420                                 int cx, cy;
421                                 
422                                 GHOST_ScreenToClient(win->ghostwin, cd->x, cd->y, &cx, &cy);
423                                 win->lmouse[0]= cx;
424                                 win->lmouse[1]= (win->size[1]-1) - cy;
425                                 
426                                 window_handle(win, MOUSEX, win->lmouse[0]);
427                                 window_handle(win, MOUSEY, win->lmouse[1]);
428                         }
429                         break;
430                 }
431                 case GHOST_kEventButtonDown:
432                 case GHOST_kEventButtonUp: {
433                         GHOST_TEventButtonData *bd= data;
434                         int val= (type==GHOST_kEventButtonDown);
435                         int bbut= convert_mbut(bd->button);
436                 
437                         if (bbut==LEFTMOUSE) {
438                                 if (val) {
439                                         if (win->commandqual) {
440                                                 bbut= win->faked_mbut= RIGHTMOUSE;
441                                         } else if ((win->lqual & LR_ALTKEY) && (U.flag & USER_TWOBUTTONMOUSE)) {
442                                                 /* finally, it actually USES the userpref! :) -intrr */
443                                                 bbut= win->faked_mbut= MIDDLEMOUSE;
444                                         }
445                                 } else {
446                                         if (win->faked_mbut) {
447                                                 bbut= win->faked_mbut;
448                                                 win->faked_mbut= 0;
449                                         }
450                                 }
451                         }
452
453                         if (bbut==LEFTMOUSE) {
454                                 win->lmbut= change_bit(win->lmbut, L_MOUSE, val);
455                         } else if (bbut==MIDDLEMOUSE) {
456                                 win->lmbut= change_bit(win->lmbut, M_MOUSE, val);
457                         } else {
458                                 win->lmbut= change_bit(win->lmbut, R_MOUSE, val);
459                         }
460                         window_handle(win, bbut, val);
461                         
462                         break;
463                 }
464         
465                 case GHOST_kEventKeyDown:
466                 case GHOST_kEventKeyUp: {
467                         GHOST_TEventKeyData *kd= data;
468                         int val= (type==GHOST_kEventKeyDown);
469                         int bkey= convert_key(kd->key);
470
471                         if (kd->key == GHOST_kKeyCommand) {
472                                 win->commandqual= val;
473                         }
474
475                         if (bkey) {
476                                 if (bkey==LEFTSHIFTKEY || bkey==RIGHTSHIFTKEY) {
477                                         win->lqual= change_bit(win->lqual, LR_SHIFTKEY, val);
478                                 } else if (bkey==LEFTCTRLKEY || bkey==RIGHTCTRLKEY) {
479                                         win->lqual= change_bit(win->lqual, LR_CTRLKEY, val);
480                                 } else if (bkey==LEFTALTKEY || bkey==RIGHTALTKEY) {
481                                         win->lqual= change_bit(win->lqual, LR_ALTKEY, val);
482                                 }
483
484                                 window_handle_ext(win, bkey, val, kd->ascii);
485                         }
486                         
487                         break;
488                 }
489
490                 case GHOST_kEventWheel: {
491                         GHOST_TEventWheelData* wheelData = (GHOST_TEventWheelData*) data;
492                         if (wheelData->z > 0) {
493                                 window_handle(win, WHEELUPMOUSE, 1);
494                         } else {
495                                 window_handle(win, WHEELDOWNMOUSE, 1);
496                         }
497                         break;
498                 }
499
500                 case GHOST_kEventWindowDeactivate:
501                 case GHOST_kEventWindowActivate: {
502                         win->active= (type==GHOST_kEventWindowActivate);
503                         window_handle(win, INPUTCHANGE, win->active);
504                         
505                         if (win->active) {
506                                 if ((win->lqual & LR_SHIFTKEY) && !query_qual('s')) {
507                                         win->lqual= change_bit(win->lqual, LR_SHIFTKEY, 0);
508                                         window_handle(win, LEFTSHIFTKEY, 0);
509                                 }
510                                 if ((win->lqual & LR_CTRLKEY) && !query_qual('c')) {
511                                         win->lqual= change_bit(win->lqual, LR_CTRLKEY, 0);
512                                         window_handle(win, LEFTCTRLKEY, 0);
513                                 }
514                                 if ((win->lqual & LR_ALTKEY) && !query_qual('a')) {
515                                         win->lqual= change_bit(win->lqual, LR_ALTKEY, 0);
516                                         window_handle(win, LEFTALTKEY, 0);
517                                 }
518                                 win->commandqual= query_qual('C');
519
520                                 /* 
521                                  * XXX quick hack so OSX version works better
522                                  * when the window is clicked on (focused).
523                                  *
524                                  * it used to pass on the old win->lmouse value,
525                                  * which causes a wrong click in Blender.
526                                  * Actually, a 'focus' click should not be passed
527                                  * on to blender... (ton)
528                                  */
529                                 if(1) { /* enables me to add locals */
530                                         int cx, cy, wx, wy;
531                                         GHOST_GetCursorPosition(g_system, &wx, &wy);
532
533                                         GHOST_ScreenToClient(win->ghostwin, wx, wy, &cx, &cy);
534                                         win->lmouse[0]= cx;
535                                         win->lmouse[1]= (win->size[1]-1) - cy;
536                                         window_handle(win, MOUSEX, win->lmouse[0]);
537                                         window_handle(win, MOUSEY, win->lmouse[1]);
538                                 }
539                         }
540                         
541                         break;
542                 }
543                 case GHOST_kEventWindowClose: {
544                         window_handle(win, WINCLOSE, 1);
545                         break;
546                 }
547                 case GHOST_kEventWindowUpdate: {
548                         window_handle(win, REDRAW, 1);
549                         break;
550                 }
551                 case GHOST_kEventWindowSize: {
552                         GHOST_RectangleHandle client_rect;
553                         int l, t, r, b, scr_w, scr_h;
554
555                         client_rect= GHOST_GetClientBounds(win->ghostwin);
556                         GHOST_GetRectangle(client_rect, &l, &t, &r, &b);
557                         
558                         GHOST_DisposeRectangle(client_rect);
559                         
560                         winlay_get_screensize(&scr_w, &scr_h);
561                         win->position[0]= l;
562                         win->position[1]= scr_h - b - 1;
563                         win->size[0]= r-l;
564                         win->size[1]= b-t;
565
566                         window_handle(win, RESHAPE, 1);
567                         break;
568                 }
569         }
570         }
571         
572         return 1;
573 }
574
575 char *window_get_title(Window *win) {
576         char *title= GHOST_GetTitle(win->ghostwin);
577         char *mem_title= BLI_strdup(title);
578         free(title);
579
580         return mem_title;
581 }
582
583 void window_set_title(Window *win, char *title) {
584         GHOST_SetTitle(win->ghostwin, title);
585 }
586
587 short window_get_qual(Window *win) {
588         return win->lqual;
589 }
590
591 short window_get_mbut(Window *win) {
592         return win->lmbut;
593 }
594
595 void window_get_mouse(Window *win, short *mval) {
596         mval[0]= win->lmouse[0];
597         mval[1]= win->lmouse[1];
598 }
599
600 void window_get_position(Window *win, int *posx_r, int *posy_r) {
601         *posx_r= win->position[0];
602         *posy_r= win->position[1];
603 }
604
605 void window_get_size(Window *win, int *width_r, int *height_r) {
606         *width_r= win->size[0];
607         *height_r= win->size[1];
608 }
609
610 void window_set_size(Window *win, int width, int height) {
611         GHOST_SetClientSize(win->ghostwin, width, height);
612 }
613
614 void window_lower(Window *win) {
615         GHOST_SetWindowOrder(win->ghostwin, GHOST_kWindowOrderBottom);
616 }
617
618 void window_raise(Window *win) {
619         GHOST_SetWindowOrder(win->ghostwin, GHOST_kWindowOrderTop);
620 }
621
622 #ifdef _WIN32   //FULLSCREEN
623 void window_toggle_fullscreen(Window *win, int fullscreen) {
624         /* these two lines make sure front and backbuffer are equal. for swapbuffers */
625         markdirty_all();
626         screen_swapbuffers();
627
628         if(fullscreen)
629                 GHOST_SetWindowState(win->ghostwin, GHOST_kWindowStateFullScreen);
630         else
631                 GHOST_SetWindowState(win->ghostwin, GHOST_kWindowStateMaximized);
632 }
633 #endif
634
635 void window_warp_pointer(Window *win, int x, int y) {
636         y= win->size[1] - y - 1;
637         GHOST_ClientToScreen(win->ghostwin, x, y, &x, &y);
638         GHOST_SetCursorPosition(g_system, x, y);
639 }
640
641 void window_queue_redraw(Window *win) {
642         GHOST_InvalidateWindow(win->ghostwin); // ghost will send back a redraw to blender
643 }
644
645 /***/
646
647 void winlay_process_events(int wait_for_event) {
648         GHOST_ProcessEvents(g_system, wait_for_event);
649         GHOST_DispatchEvents(g_system);
650 }
651
652 void winlay_get_screensize(int *width_r, int *height_r) {
653         unsigned int uiwidth;
654         unsigned int uiheight;
655         
656         if (!g_system) {
657                 GHOST_EventConsumerHandle consumer= GHOST_CreateEventConsumer(event_proc, NULL);
658         
659                 g_system= GHOST_CreateSystem();
660                 GHOST_AddEventConsumer(g_system, consumer);
661         }
662         
663         GHOST_GetMainDisplayDimensions(g_system, &uiwidth, &uiheight);
664         *width_r= uiwidth;
665         *height_r= uiheight;
666 }
667
668 Window *winlay_get_active_window(void) {
669         return active_gl_window;
670 }