Two in one:
[blender.git] / source / blender / src / ghostwinlay.c
index c04fdf095ba58964aa1fe9eac47b3ea6f33bf776..d63574e79f9fc002c3659285bfceebac05301e73 100644 (file)
 #include <config.h>
 #endif
 
-#ifdef WIN32
-#include "BLI_winstuff.h"
-#endif
-
 #include "MEM_guardedalloc.h"
 
 #include "DNA_listBase.h"      
 
 #include "winlay.h"
 
+#ifdef __APPLE__
+#include <OpenGL/OpenGL.h>
+#define __CARBONSOUND__
+#include <Carbon/Carbon.h>
+
+/*declarations*/
+int checkAppleVideoCard(void);
+void getMacAvailableBounds(short *, short *, short *, short *);
+
+#endif
 ///
 
 struct _Window {
@@ -79,9 +85,8 @@ struct _Window {
        
                /* Last known mouse/button/qualifier state */
        int             lmouse[2];
-       int             lqual;          /* (LR_SHFTKEY, LR_CTRLKEY, LR_ALTKEY) */
+       int             lqual;          /* (LR_SHFTKEY, LR_CTRLKEY, LR_ALTKEY, LR_COMMANDKEY) */
        int             lmbut;          /* (L_MOUSE, M_MOUSE, R_MOUSE) */
-       int             commandqual;
 
                /* Tracks the faked mouse button, if non-zero it is
                 * the event number of the last faked button.
@@ -94,6 +99,82 @@ struct _Window {
 
 ///
 
+#ifdef __APPLE__
+
+/* to avoid killing small end comps, we want to allow
+   blender to start maximised if all the followings are true :
+               - Renderer is OpenGL capable
+               - Hardware acceleration
+               - VRAM > 16 Mo
+               
+   we will bail out if VRAM is less than 8Mo
+               */
+               
+static int macPrefState = 0;
+               
+int checkAppleVideoCard(void) {
+       long theErr;
+       unsigned long display_mask;
+       CGLRendererInfoObj rend;
+       long nrend;
+       int j;
+       long value;
+       long maxvram = 0;   /* we get always more than 1 renderer, check one, at least, has 8 Mo */
+       
+       display_mask = CGDisplayIDToOpenGLDisplayMask (CGMainDisplayID() );     
+       
+       theErr = CGLQueryRendererInfo( display_mask, &rend, &nrend);
+       if (theErr == 0) {
+               theErr = CGLDescribeRenderer (rend, 0, kCGLRPRendererCount, &nrend);
+               if (theErr == 0) {
+                       for (j = 0; j < nrend; j++) {
+                               theErr = CGLDescribeRenderer (rend, j, kCGLRPVideoMemory, &value); 
+                               if (value > maxvram)
+                                       maxvram = value;
+                               if ((theErr == 0) && (value >= 20000000)) {
+                                       theErr = CGLDescribeRenderer (rend, j, kCGLRPAccelerated, &value); 
+                                       if ((theErr == 0) && (value != 0)) {
+                                               theErr = CGLDescribeRenderer (rend, j, kCGLRPCompliant, &value); 
+                                               if ((theErr == 0) && (value != 0)) {
+                                                       /*fprintf(stderr,"make it big\n");*/
+                                                       CGLDestroyRendererInfo (rend);
+                                                       macPrefState = 8;
+                                                       return 1;
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+       if (maxvram < 7500000 ) {       /* put a standard alert and quit*/ 
+               SInt16 junkHit;
+               char  inError[] = "* Not enough VRAM    ";
+               char  inText[] = "* blender needs at least 8Mb    ";
+               inError[0] = 16;
+               inText[0] = 28;
+                               
+               fprintf(stderr, " vram is %li . not enough, aborting\n", maxvram);
+               StandardAlert (   kAlertStopAlert, (ConstStr255Param) &inError, (ConstStr255Param)&inText,NULL,&junkHit);
+               abort();
+       }
+       CGLDestroyRendererInfo (rend);
+       return 0;
+}
+
+void getMacAvailableBounds(short *top, short *left, short *bottom, short *right) {
+       Rect outAvailableRect;
+       
+       GetAvailableWindowPositioningBounds ( GetMainDevice(), &outAvailableRect);
+       
+       *top = outAvailableRect.top;  
+    *left = outAvailableRect.left;
+    *bottom = outAvailableRect.bottom; 
+    *right = outAvailableRect.right;
+}
+
+#endif
+
+
 static GHOST_SystemHandle g_system= 0;
 
        /* Some simple ghost <-> blender conversions */
@@ -160,6 +241,7 @@ static int convert_key(GHOST_TKey key) {
                case GHOST_kKeyRightShift:              return RIGHTSHIFTKEY;
                case GHOST_kKeyLeftControl:             return LEFTCTRLKEY;
                case GHOST_kKeyRightControl:    return RIGHTCTRLKEY;
+               case GHOST_kKeyCommand:                 return COMMANDKEY;
                case GHOST_kKeyLeftAlt:                 return LEFTALTKEY;
                case GHOST_kKeyRightAlt:                return RIGHTALTKEY;
 
@@ -188,6 +270,9 @@ static int convert_key(GHOST_TKey key) {
                case GHOST_kKeyNumpadMinus:             return PADMINUS;
                case GHOST_kKeyNumpadAsterisk:  return PADASTERKEY;
                case GHOST_kKeyNumpadSlash:             return PADSLASHKEY;
+
+               case GHOST_kKeyGrLess:              return GRLESSKEY; 
+                       
                case GHOST_kKeyUnknown:                 return UNKNOWNKEY;
 
                default:
@@ -245,12 +330,13 @@ Window *window_open(char *title, int posx, int posy, int sizex, int sizey, int s
                GHOST_kWindowStateFullScreen:GHOST_kWindowStateNormal;
 #else
 #ifdef _WIN32  // FULLSCREEN
-       if (start_maximized == G_WINDOWSTATE_FULLSCREEN)
-               inital_state= GHOST_kWindowStateFullScreen;
-       else
+//     if (start_maximized == G_WINDOWSTATE_FULLSCREEN)
+//             inital_state= GHOST_kWindowStateFullScreen;
+//     else
                inital_state= start_maximized?GHOST_kWindowStateMaximized:GHOST_kWindowStateNormal;
 #else                  // APPLE
        inital_state= start_maximized?GHOST_kWindowStateMaximized:GHOST_kWindowStateNormal;
+       inital_state += macPrefState;
 #endif
 #endif
 
@@ -274,6 +360,8 @@ Window *window_open(char *title, int posx, int posy, int sizex, int sizey, int s
                        
                        win->lmouse[0]= win->size[0]/2;
                        win->lmouse[1]= win->size[1]/2;
+                       
+                       
                } else {
                        GHOST_DisposeWindow(g_system, ghostwin);
                }
@@ -324,7 +412,18 @@ void window_set_cursor(Window *win, int curs) {
                GHOST_SetCursorVisibility(win->ghostwin, 0);
        } else {
                GHOST_SetCursorVisibility(win->ghostwin, 1);
-               GHOST_SetCursorShape(win->ghostwin, convert_cursor(curs));
+               
+               /* detect if we use system cursor or Blender cursor */
+               switch(curs) {
+                       case CURSOR_TEXTEDIT:
+                               SetBlenderCursor(BC_TEXTEDITCURSOR);
+                               break;
+                       case CURSOR_VPAINT:
+                               SetBlenderCursor(BC_PAINTBRUSHCURSOR);
+                               break;
+                       default:
+                               GHOST_SetCursorShape(win->ghostwin, convert_cursor(curs));
+               }
        }
 }
 
@@ -351,6 +450,7 @@ void window_set_custom_cursor_ex(Window *win, BCursor *cursor, int useBig) {
 
 void window_make_active(Window *win) {
        if (win != active_gl_window) {
+               win->lmbut= 0;  /* keeps hanging when mousepressed while other window opened */
                active_gl_window= win;
                GHOST_ActivateWindowDrawingContext(win->ghostwin);
        }
@@ -436,7 +536,7 @@ static int event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private)
                
                        if (bbut==LEFTMOUSE) {
                                if (val) {
-                                       if (win->commandqual) {
+                                       if (win->lqual & LR_COMMANDKEY) {
                                                bbut= win->faked_mbut= RIGHTMOUSE;
                                        } else if ((win->lqual & LR_ALTKEY) && (U.flag & USER_TWOBUTTONMOUSE)) {
                                                /* finally, it actually USES the userpref! :) -intrr */
@@ -468,10 +568,6 @@ static int event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private)
                        int val= (type==GHOST_kEventKeyDown);
                        int bkey= convert_key(kd->key);
 
-                       if (kd->key == GHOST_kKeyCommand) {
-                               win->commandqual= val;
-                       }
-
                        if (bkey) {
                                if (bkey==LEFTSHIFTKEY || bkey==RIGHTSHIFTKEY) {
                                        win->lqual= change_bit(win->lqual, LR_SHIFTKEY, val);
@@ -479,6 +575,8 @@ static int event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private)
                                        win->lqual= change_bit(win->lqual, LR_CTRLKEY, val);
                                } else if (bkey==LEFTALTKEY || bkey==RIGHTALTKEY) {
                                        win->lqual= change_bit(win->lqual, LR_ALTKEY, val);
+                               } else if (bkey==COMMANDKEY) {
+                                       win->lqual= change_bit(win->lqual, LR_COMMANDKEY, val);
                                }
 
                                window_handle_ext(win, bkey, val, kd->ascii);
@@ -515,7 +613,10 @@ static int event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private)
                                        win->lqual= change_bit(win->lqual, LR_ALTKEY, 0);
                                        window_handle(win, LEFTALTKEY, 0);
                                }
-                               win->commandqual= query_qual('C');
+                               if ((win->lqual & LR_COMMANDKEY) && !query_qual('C')) {
+                                       win->lqual= change_bit(win->lqual, LR_COMMANDKEY, 0);
+                                       window_handle(win, LR_COMMANDKEY, 0);
+                               }
 
                                /* 
                                 * XXX quick hack so OSX version works better
@@ -566,6 +667,10 @@ static int event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private)
                        window_handle(win, RESHAPE, 1);
                        break;
                }
+               case GHOST_kEventUnknown:
+               case GHOST_kEventQuit:
+               case GHOST_kNumEventTypes:
+                       break;
        }
        }
        
@@ -584,8 +689,15 @@ void window_set_title(Window *win, char *title) {
        GHOST_SetTitle(win->ghostwin, title);
 }
 
-short window_get_qual(Window *win) {
-       return win->lqual;
+short window_get_qual(Window *win) 
+{
+       int qual= 0;
+       
+       if( query_qual('s')) qual |= LR_SHIFTKEY;
+       if( query_qual('a')) qual |= LR_ALTKEY;
+       if( query_qual('c')) qual |= LR_CTRLKEY;
+       return qual;
+//     return win->lqual;
 }
 
 short window_get_mbut(Window *win) {
@@ -602,6 +714,11 @@ void window_get_position(Window *win, int *posx_r, int *posy_r) {
        *posy_r= win->position[1];
 }
 
+const GHOST_TabletData* window_get_tablet_data(Window *win)
+{
+       return GHOST_GetTabletData(win->ghostwin);
+}
+
 void window_get_size(Window *win, int *width_r, int *height_r) {
        *width_r= win->size[0];
        *height_r= win->size[1];
@@ -617,9 +734,13 @@ void window_lower(Window *win) {
 
 void window_raise(Window *win) {
        GHOST_SetWindowOrder(win->ghostwin, GHOST_kWindowOrderTop);
+#ifdef _WIN32
+       markdirty_all(); /* to avoid redraw errors in fullscreen mode (aphex) */
+#endif
 }
 
-#ifdef _WIN32  //FULLSCREEN
+#if 0
+//#ifdef _WIN32        //FULLSCREEN
 void window_toggle_fullscreen(Window *win, int fullscreen) {
        /* these two lines make sure front and backbuffer are equal. for swapbuffers */
        markdirty_all();
@@ -633,9 +754,15 @@ void window_toggle_fullscreen(Window *win, int fullscreen) {
 #endif
 
 void window_warp_pointer(Window *win, int x, int y) {
+       int oldx=x, oldy=y;
+       
        y= win->size[1] - y - 1;
        GHOST_ClientToScreen(win->ghostwin, x, y, &x, &y);
        GHOST_SetCursorPosition(g_system, x, y);
+       
+       /* on OSX (for example) the setcursor doesnt create event */
+       win->lmouse[0]= oldx;
+       win->lmouse[1]= oldy;
 }
 
 void window_queue_redraw(Window *win) {