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