]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - vid_agl.c
renamed IN_Activate to VID_GrabMouse and made it a public function in
[xonotic/darkplaces.git] / vid_agl.c
index cc1bb0c6e2d9dbdb5a9a7a53ee66a5bde81a0e95..671738800d584baf8009564c1bb5dc4f7798e1f1 100644 (file)
--- a/vid_agl.c
+++ b/vid_agl.c
 #include <AGL/agl.h>
 #include <OpenGL/OpenGL.h>
 #include <Carbon/Carbon.h>
-#include "vid_agl_mackeys.h" // this is SDL/src/video/maccommon/SDL_mackeys.h
+#include <IOKit/hidsystem/IOHIDLib.h>
+#include <IOKit/hidsystem/IOHIDParameter.h>
+#include <IOKit/hidsystem/event_status_driver.h>
 #include "quakedef.h"
+#include "vid_agl_mackeys.h" // this is SDL/src/video/maccommon/SDL_mackeys.h
 
 #ifndef kCGLCEMPEngine
 #define kCGLCEMPEngine 313
@@ -57,6 +60,7 @@ CGLContextObj (*qCGLGetCurrentContext) (void);
 static qboolean multithreadedgl;
 static qboolean mouse_avail = true;
 static qboolean vid_usingmouse = false;
+static qboolean vid_usingnoaccel = false;
 static float mouse_x, mouse_y;
 
 static qboolean vid_isfullscreen = false;
@@ -66,11 +70,34 @@ static qboolean sound_active = true;
 
 static int scr_width, scr_height;
 
-static cvar_t apple_multithreadedgl = {CVAR_SAVE, "apple_multithreadedgl", "0", "makes use of a second thread for the OpenGL driver (if possible) rather than using the engine thread (note: this is done automatically on most other operating systems)"};
+static cvar_t apple_multithreadedgl = {CVAR_SAVE, "apple_multithreadedgl", "1", "makes use of a second thread for the OpenGL driver (if possible) rather than using the engine thread (note: this is done automatically on most other operating systems)"};
+static cvar_t apple_mouse_noaccel = {CVAR_SAVE, "apple_mouse_noaccel", "1", "disables mouse acceleration while DarkPlaces is active"};
 
 static AGLContext context;
 static WindowRef window;
 
+static double originalMouseSpeed = -1.0;
+
+io_connect_t IN_GetIOHandle()
+{
+       io_connect_t iohandle = MACH_PORT_NULL;
+       kern_return_t status;
+       io_service_t iohidsystem = MACH_PORT_NULL;
+       mach_port_t masterport;
+
+       status = IOMasterPort(MACH_PORT_NULL, &masterport);
+       if(status != KERN_SUCCESS)
+               return 0;
+
+       iohidsystem = IORegistryEntryFromPath(masterport, kIOServicePlane ":/IOResources/IOHIDSystem");
+       if(!iohidsystem)
+               return 0;
+
+       status = IOServiceOpen(iohidsystem, mach_task_self(), kIOHIDParamConnectType, &iohandle);
+       IOObjectRelease(iohidsystem);
+
+       return iohandle;
+}
 
 void VID_GetWindowSize (int *x, int *y, int *width, int *height)
 {
@@ -79,10 +106,12 @@ void VID_GetWindowSize (int *x, int *y, int *width, int *height)
        *height = scr_height;
 }
 
-static void IN_Activate( qboolean grab )
+void VID_GrabMouse(qboolean grab)
 {
        if (grab)
        {
+               if(vid_usingmouse && (vid_usingnoaccel != !!apple_mouse_noaccel.integer))
+                       VID_GrabMouse(false); // ungrab first!
                if (!vid_usingmouse && mouse_avail && window)
                {
                        Rect winBounds;
@@ -100,14 +129,59 @@ static void IN_Activate( qboolean grab )
                        // Lock the mouse pointer at its current position
                        CGAssociateMouseAndMouseCursorPosition(false);
 
+                       // Save the status of mouse acceleration
+                       originalMouseSpeed = -1.0; // in case of error
+                       if(apple_mouse_noaccel.integer)
+                       {
+                               io_connect_t mouseDev = IN_GetIOHandle();
+                               if(mouseDev != 0)
+                               {
+                                       if(IOHIDGetAccelerationWithKey(mouseDev, CFSTR(kIOHIDMouseAccelerationType), &originalMouseSpeed) == kIOReturnSuccess)
+                                       {
+                                               Con_DPrintf("previous mouse acceleration: %f\n", originalMouseSpeed);
+                                               if(IOHIDSetAccelerationWithKey(mouseDev, CFSTR(kIOHIDMouseAccelerationType), -1.0) != kIOReturnSuccess)
+                                               {
+                                                       Con_Print("Could not disable mouse acceleration (failed at IOHIDSetAccelerationWithKey).\n");
+                                                       Cvar_SetValueQuick(&apple_mouse_noaccel, 0);
+                                               }
+                                       }
+                                       else
+                                       {
+                                               Con_Print("Could not disable mouse acceleration (failed at IOHIDGetAccelerationWithKey).\n");
+                                               Cvar_SetValueQuick(&apple_mouse_noaccel, 0);
+                                       }
+                                       IOServiceClose(mouseDev);
+                               }
+                               else
+                               {
+                                       Con_Print("Could not disable mouse acceleration (failed at IO_GetIOHandle).\n");
+                                       Cvar_SetValueQuick(&apple_mouse_noaccel, 0);
+                               }
+                       }
+
                        mouse_x = mouse_y = 0;
                        vid_usingmouse = true;
+                       vid_usingnoaccel = !!apple_mouse_noaccel.integer;
                }
        }
        else
        {
                if (vid_usingmouse)
                {
+                       if(originalMouseSpeed != -1.0)
+                       {
+                               io_connect_t mouseDev = IN_GetIOHandle();
+                               if(mouseDev != 0)
+                               {
+                                       Con_DPrintf("restoring mouse acceleration to: %f\n", originalMouseSpeed);
+                                       if(IOHIDSetAccelerationWithKey(mouseDev, CFSTR(kIOHIDMouseAccelerationType), originalMouseSpeed) != kIOReturnSuccess)
+                                               Con_Print("Could not re-enable mouse acceleration (failed at IOHIDSetAccelerationWithKey).\n");
+                                       IOServiceClose(mouseDev);
+                               }
+                               else
+                                       Con_Print("Could not re-enable mouse acceleration (failed at IO_GetIOHandle).\n");
+                       }
+
                        CGAssociateMouseAndMouseCursorPosition(true);
                        CGDisplayShowCursor(CGMainDisplayID());
 
@@ -117,21 +191,10 @@ static void IN_Activate( qboolean grab )
 }
 
 #define GAMMA_TABLE_SIZE 256
-void VID_Finish (qboolean allowmousegrab)
+void VID_Finish (void)
 {
-       qboolean vid_usemouse;
        qboolean vid_usevsync;
 
-       // handle the mouse state when windowed if that's changed
-       vid_usemouse = false;
-       if (allowmousegrab && vid_mouse.integer && !key_consoleactive && (key_dest != key_game || !cls.demoplayback))
-               vid_usemouse = true;
-       if (!vid_activewindow)
-               vid_usemouse = false;
-       if (vid_isfullscreen)
-               vid_usemouse = true;
-       IN_Activate(vid_usemouse);
-
        // handle changes of the vsync option
        vid_usevsync = (vid_vsync.integer && !cls.timedemo);
        if (vid_usingvsync != vid_usevsync)
@@ -254,8 +317,7 @@ void signal_handler(int sig)
 {
        printf("Received signal %d, exiting...\n", sig);
        VID_RestoreSystemGamma();
-       Sys_Quit();
-       exit(0);
+       Sys_Quit(1);
 }
 
 void InitSig(void)
@@ -276,6 +338,7 @@ void VID_Init(void)
 {
        InitSig(); // trap evil signals
        Cvar_RegisterVariable(&apple_multithreadedgl);
+       Cvar_RegisterVariable(&apple_mouse_noaccel);
 // COMMANDLINEOPTION: Input: -nomouse disables mouse support (see also vid_mouse cvar)
        if (COM_CheckParm ("-nomouse"))
                mouse_avail = false;
@@ -336,7 +399,7 @@ void VID_Shutdown(void)
        if (context == NULL && window == NULL)
                return;
 
-       IN_Activate(false);
+       VID_GrabMouse(false);
        VID_RestoreSystemGamma();
 
        if (context != NULL)
@@ -422,32 +485,44 @@ static void VID_ProcessPendingAsyncEvents (void)
 
        // Closed
        if (AsyncEvent_Quitting)
-               Sys_Quit();
+               Sys_Quit(0);
 }
 
-static void VID_BuildAGLAttrib(GLint *attrib, qboolean stencil, qboolean fullscreen, qboolean stereobuffer)
+static void VID_BuildAGLAttrib(GLint *attrib, qboolean stencil, qboolean fullscreen, qboolean stereobuffer, int samples)
 {
        *attrib++ = AGL_RGBA;
-       *attrib++ = AGL_RED_SIZE;*attrib++ = 1;
-       *attrib++ = AGL_GREEN_SIZE;*attrib++ = 1;
-       *attrib++ = AGL_BLUE_SIZE;*attrib++ = 1;
+       *attrib++ = AGL_RED_SIZE;*attrib++ = stencil ? 8 : 5;
+       *attrib++ = AGL_GREEN_SIZE;*attrib++ = stencil ? 8 : 5;
+       *attrib++ = AGL_BLUE_SIZE;*attrib++ = stencil ? 8 : 5;
        *attrib++ = AGL_DOUBLEBUFFER;
-       *attrib++ = AGL_DEPTH_SIZE;*attrib++ = 1;
+       *attrib++ = AGL_DEPTH_SIZE;*attrib++ = stencil ? 24 : 16;
 
        // if stencil is enabled, ask for alpha too
        if (stencil)
        {
                *attrib++ = AGL_STENCIL_SIZE;*attrib++ = 8;
-               *attrib++ = AGL_ALPHA_SIZE;*attrib++ = 1;
+               *attrib++ = AGL_ALPHA_SIZE;*attrib++ = 8;
        }
        if (fullscreen)
                *attrib++ = AGL_FULLSCREEN;
        if (stereobuffer)
                *attrib++ = AGL_STEREO;
+#ifdef AGL_SAMPLE_BUFFERS_ARB
+#ifdef AGL_SAMPLES_ARB
+       if (samples > 1)
+       {
+               *attrib++ = AGL_SAMPLE_BUFFERS_ARB;
+               *attrib++ = 1;
+               *attrib++ = AGL_SAMPLES_ARB;
+               *attrib++ = samples;
+       }
+#endif
+#endif
+
        *attrib++ = AGL_NONE;
 }
 
-int VID_InitMode(int fullscreen, int width, int height, int bpp, int refreshrate, int stereobuffer)
+int VID_InitMode(int fullscreen, int width, int height, int bpp, int refreshrate, int stereobuffer, int samples)
 {
     const EventTypeSpec winEvents[] =
        {
@@ -518,7 +593,7 @@ int VID_InitMode(int fullscreen, int width, int height, int bpp, int refreshrate
                                                           GetEventTypeCount(winEvents), winEvents, window, NULL);
 
        // Create the desired attribute list
-       VID_BuildAGLAttrib(attributes, bpp == 32, fullscreen, stereobuffer);
+       VID_BuildAGLAttrib(attributes, bpp == 32, fullscreen, stereobuffer, samples);
 
        if (!fullscreen)
        {
@@ -617,10 +692,7 @@ int VID_InitMode(int fullscreen, int width, int height, int bpp, int refreshrate
        if ((qglGetString = (const GLubyte* (GLAPIENTRY *)(GLenum name))GL_GetProcAddress("glGetString")) == NULL)
                Sys_Error("glGetString not found in %s", gl_driver);
 
-       gl_renderer = (const char *)qglGetString(GL_RENDERER);
-       gl_vendor = (const char *)qglGetString(GL_VENDOR);
-       gl_version = (const char *)qglGetString(GL_VERSION);
-       gl_extensions = (const char *)qglGetString(GL_EXTENSIONS);
+       gl_platformextensions = "";
        gl_platform = "AGL";
        gl_videosyncavailable = true;
 
@@ -837,7 +909,7 @@ static void Handle_Key(unsigned char charcode, UInt32 mackeycode, qboolean keypr
                                                ascii = charcode;
                                        }
                                        else
-                                               Con_Printf(">> UNKNOWN char/keycode: %d/%u <<\n", charcode, (unsigned) mackeycode);
+                                               Con_DPrintf(">> UNKNOWN char/keycode: %d/%u <<\n", charcode, (unsigned) mackeycode);
                        }
        }
 
@@ -980,7 +1052,7 @@ void Sys_SendKeyEvents(void)
                                                VID_AppFocusChanged(false);
                                                break;
                                        case kEventAppQuit:
-                                               Sys_Quit();
+                                               Sys_Quit(0);
                                                break;
                                        case kEventAppActiveWindowChanged:
                                                break;