merge with/from trunk at r35190
[blender.git] / intern / ghost / intern / GHOST_SystemX11.cpp
index ad8647d2246047b5d19bf00dccc59b78860c06ed..09a4d9d4de262cd8a947c7e8fad44bcf26ef94af 100644 (file)
@@ -1,4 +1,4 @@
-/**
+/*
  * $Id$
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -14,7 +14,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  *
  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
  * All rights reserved.
  * ***** END GPL LICENSE BLOCK *****
  */
 
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
+/** \file ghost/intern/GHOST_SystemX11.cpp
+ *  \ingroup GHOST
+ */
+
 
 #include "GHOST_SystemX11.h"
 #include "GHOST_WindowX11.h"
 #include <X11/keysym.h>
 #include <X11/XKBlib.h> /* allow detectable autorepeate */
 
+#ifdef WITH_XF86KEYSYM
+#include <X11/XF86keysym.h>
+#endif
+
 #ifdef __sgi
 
 #if defined(_SGI_EXTRA_PREDEFINES) && !defined(NO_FAST_ATOMS)
 #include <stdio.h> // for fprintf only
 #include <cstdlib> // for exit
 
+#ifndef PREFIX
+#error "PREFIX not defined"
+#endif
+
 typedef struct NDOFPlatformInfo {
        Display *display;
        Window window;
@@ -228,6 +237,8 @@ getMainDisplayDimensions(
         * @param       height  The height the window.
         * @param       state   The state of the window when opened.
         * @param       type    The type of drawing context installed in this window.
+        * @param       stereoVisual    Stereo visual for quad buffered stereo.
+        * @param       numOfAASamples  Number of samples used for AA (zero if no AA)
         * @param       parentWindow    Parent (embedder) window
         * @return      The new window (or 0 if creation failed).
         */
@@ -242,6 +253,7 @@ createWindow(
        GHOST_TWindowState state,
        GHOST_TDrawingContextType type,
        bool stereoVisual,
+       const GHOST_TUns16 numOfAASamples,
        const GHOST_TEmbedderWindowID parentWindow
 ){
        GHOST_WindowX11 * window = 0;
@@ -385,6 +397,10 @@ processEvents(
        
        bool anyProcessed = false;
        
+       if (playingEvents(&anyProcessed)) {
+               return anyProcessed;
+       }
+       
        do {
                GHOST_TimerManager* timerMgr = getTimerManager();
                
@@ -466,7 +482,7 @@ GHOST_SystemX11::processEvent(XEvent *xe)
 
                                /* could also clamp to screen bounds
                                 * wrap with a window outside the view will fail atm  */
-                               bounds.wrapPoint(x_new, y_new, 2); /* offset of one incase blender is at screen bounds */
+                               bounds.wrapPoint(x_new, y_new, 8); /* offset of one incase blender is at screen bounds */
                                window->getCursorGrabAccum(x_accum, y_accum);
 
                                if(x_new != xme.x_root || y_new != xme.y_root) {
@@ -533,38 +549,43 @@ GHOST_SystemX11::processEvent(XEvent *xe)
                }
 
                case ButtonPress:
-               {
-                       /* process wheel mouse events and break */
-                       if (xe->xbutton.button == 4) {
-                               g_event = new GHOST_EventWheel(getMilliSeconds(), window, 1);
-                               break;
-                       }
-                       if (xe->xbutton.button == 5) {
-                               g_event = new GHOST_EventWheel(getMilliSeconds(), window, -1);
-                               break;
-                       }
-               }
                case ButtonRelease:
                {
-
                        XButtonEvent & xbe = xe->xbutton;
                        GHOST_TButtonMask gbmask = GHOST_kButtonMaskLeft;
-                       switch (xbe.button) {
-                               case Button1 : gbmask = GHOST_kButtonMaskLeft; break;
-                               case Button3 : gbmask = GHOST_kButtonMaskRight; break;
-                               /* It seems events 6 and 7 are for horizontal scrolling.
-                                * you can re-order button mapping like this... (swaps 6,7 with 8,9)
-                                *   xmodmap -e "pointer = 1 2 3 4 5 8 9 6 7" 
-                                */
-                               case 8 : gbmask = GHOST_kButtonMaskButton4; break; /* Button4 is the wheel */
-                               case 9 : gbmask = GHOST_kButtonMaskButton5; break; /* Button5 is a wheel too */
-                               default:
-                               case Button2 : gbmask = GHOST_kButtonMaskMiddle; break;
-                       }
-                       
                        GHOST_TEventType type = (xbe.type == ButtonPress) ? 
                                GHOST_kEventButtonDown : GHOST_kEventButtonUp;
+
+                       /* process wheel mouse events and break, only pass on press events */
+                       if(xbe.button == Button4) {
+                               if(xbe.type == ButtonPress)
+                                       g_event = new GHOST_EventWheel(getMilliSeconds(), window, 1);
+                               break;
+                       }
+                       else if(xbe.button == Button5) {
+                               if(xbe.type == ButtonPress)
+                                       g_event = new GHOST_EventWheel(getMilliSeconds(), window, -1);
+                               break;
+                       }
                        
+                       /* process rest of normal mouse buttons */
+                       if(xbe.button == Button1)
+                               gbmask = GHOST_kButtonMaskLeft;
+                       else if(xbe.button == Button2)
+                               gbmask = GHOST_kButtonMaskMiddle;
+                       else if(xbe.button == Button3)
+                               gbmask = GHOST_kButtonMaskRight;
+                       /* It seems events 6 and 7 are for horizontal scrolling.
+                       * you can re-order button mapping like this... (swaps 6,7 with 8,9)
+                       *   xmodmap -e "pointer = 1 2 3 4 5 8 9 6 7" 
+                       */
+                       else if(xbe.button == 8)
+                               gbmask = GHOST_kButtonMaskButton4;
+                       else if(xbe.button == 9)
+                               gbmask = GHOST_kButtonMaskButton5;
+                       else
+                               break;
+
                        g_event = new
                        GHOST_EventButton(
                                getMilliSeconds(),
@@ -827,7 +848,10 @@ GHOST_SystemX11::
 getModifierKeys(
        GHOST_ModifierKeys& keys
 ) const {
-
+       if (this->playingEvents(NULL)) {
+               return getEventManager()->getModifierKeys(keys);
+       }
+       
        // analyse the masks retuned from XQueryPointer.
 
        memset((void *)m_keyboard_vector,0,sizeof(m_keyboard_vector));
@@ -843,6 +867,8 @@ getModifierKeys(
        const KeyCode control_r = XKeysymToKeycode(m_display,XK_Control_R);
        const KeyCode alt_l = XKeysymToKeycode(m_display,XK_Alt_L);
        const KeyCode alt_r = XKeysymToKeycode(m_display,XK_Alt_R);
+       const KeyCode super_l = XKeysymToKeycode(m_display,XK_Super_L);
+       const KeyCode super_r = XKeysymToKeycode(m_display,XK_Super_R);
 
        // Shift
        if ((m_keyboard_vector[shift_l >> 3] >> (shift_l & 7)) & 1) {
@@ -880,6 +906,15 @@ getModifierKeys(
        } else {
                keys.set(GHOST_kModifierKeyRightAlt,false);
        }
+
+       // Super (Windows) - only one GHOST-kModifierKeyOS, so mapping
+       // to either
+       if ( ((m_keyboard_vector[super_l >> 3] >> (super_l & 7)) & 1) || 
+            ((m_keyboard_vector[super_r >> 3] >> (super_r & 7)) & 1) ) {
+               keys.set(GHOST_kModifierKeyOS,true);
+       } else {
+               keys.set(GHOST_kModifierKeyOS,false);
+       }
        return GHOST_kSuccess;
 }
 
@@ -938,7 +973,11 @@ getCursorPosition(
        Window root_return, child_return;
        int rx,ry,wx,wy;
        unsigned int mask_return;
-
+       
+       if (playingEvents(NULL)) {
+               return getEventManager()->getCursorPosition(x, y);
+       }
+       
        if (XQueryPointer(
                m_display,
                RootWindow(m_display,DefaultScreen(m_display)),
@@ -962,7 +1001,7 @@ GHOST_SystemX11::
 setCursorPosition(
        GHOST_TInt32 x,
        GHOST_TInt32 y
-) const {
+) {
 
        // This is a brute force move in screen coordinates
        // XWarpPointer does relative moves so first determine the
@@ -1087,6 +1126,8 @@ convertXKey(
                        GXMAP(type,XK_Control_R,        GHOST_kKeyRightControl);
                        GXMAP(type,XK_Alt_L,            GHOST_kKeyLeftAlt);
                        GXMAP(type,XK_Alt_R,            GHOST_kKeyRightAlt);
+                       GXMAP(type,XK_Super_L,          GHOST_kKeyOS);
+                       GXMAP(type,XK_Super_R,          GHOST_kKeyOS);
 
                        GXMAP(type,XK_Insert,           GHOST_kKeyInsert);
                        GXMAP(type,XK_Delete,           GHOST_kKeyDelete);
@@ -1136,6 +1177,16 @@ convertXKey(
                        GXMAP(type,XK_KP_Multiply,      GHOST_kKeyNumpadAsterisk);
                        GXMAP(type,XK_KP_Divide,        GHOST_kKeyNumpadSlash);
 
+                       /* Media keys in some keyboards and laptops with XFree86/Xorg */
+#ifdef WITH_XF86KEYSYM
+                       GXMAP(type,XF86XK_AudioPlay,    GHOST_kKeyMediaPlay);
+                       GXMAP(type,XF86XK_AudioStop,    GHOST_kKeyMediaStop);
+                       GXMAP(type,XF86XK_AudioPrev,    GHOST_kKeyMediaFirst);
+                       GXMAP(type,XF86XK_AudioRewind,  GHOST_kKeyMediaFirst);
+                       GXMAP(type,XF86XK_AudioNext,    GHOST_kKeyMediaLast);
+                       GXMAP(type,XF86XK_AudioForward, GHOST_kKeyMediaLast);
+#endif
+
                                /* some extra sun cruft (NICE KEYBOARD!) */
 #ifdef __sun__
                        GXMAP(type,0xffde,                      GHOST_kKeyNumpad1);
@@ -1454,3 +1505,5 @@ void GHOST_SystemX11::putClipboard(GHOST_TInt8 *buffer, bool selection) const
                        fprintf(stderr, "failed to own primary\n");
        }
 }
+
+