⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 macosx_input.m

📁 quakeIII源码这个不用我多说吧
💻 M
📖 第 1 页 / 共 3 页
字号:
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.

This file is part of Quake III Arena source code.

Quake III Arena source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.

Quake III Arena source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
===========================================================================
*/
#import <AppKit/AppKit.h>
#import <Foundation/Foundation.h>
#include <ApplicationServices/ApplicationServices.h>

#import "../client/client.h"
#import "macosx_local.h"
#import "../renderer/tr_local.h"

#import "Q3Controller.h"
//#import "CGMouseDeltaFix.h"
#import "macosx_timers.h"
#import "macosx_display.h" // For Sys_SetScreenFade

#import <drivers/event_status_driver.h>
#import <sys/types.h>
#import <sys/time.h>
#import <unistd.h>


static qboolean inputActive;

static NSDate *distantPast;

static cvar_t *in_nomouse;
static cvar_t *in_showevents;
static cvar_t *in_mouseLowEndSlope;
static cvar_t *in_mouseHighEndCutoff;
static cvar_t *in_disableOSMouseScaling;

static void Sys_StartMouseInput();
static void Sys_StopMouseInput();
static qboolean mouseactive = qfalse;
static BOOL inputRectValid = NO;
static CGRect inputRect;
static NXMouseScaling originalScaling;

static unsigned int currentModifierFlags;



static void Sys_PreventMouseMovement(CGPoint point)
{
    CGEventErr err;

    //Com_Printf("**** Calling CGAssociateMouseAndMouseCursorPosition(false)\n");
    err = CGAssociateMouseAndMouseCursorPosition(false);
    if (err != CGEventNoErr) {
        Sys_Error("Could not disable mouse movement, CGAssociateMouseAndMouseCursorPosition returned %d\n", err);
    }

    // Put the mouse in the position we want to leave it at
    err = CGWarpMouseCursorPosition(point);
    if (err != CGEventNoErr) {
        Sys_Error("Could not disable mouse movement, CGWarpMouseCursorPosition returned %d\n", err);
    }
}

static void Sys_ReenableMouseMovement()
{
    CGEventErr err;
    
    //Com_Printf("**** Calling CGAssociateMouseAndMouseCursorPosition(true)\n");
    
    err = CGAssociateMouseAndMouseCursorPosition(true);
    if (err != CGEventNoErr) {
        Sys_Error("Could not reenable mouse movement, CGAssociateMouseAndMouseCursorPosition returned %d\n", err);
    }
    
    // Leave the mouse where it was -- don't warp here.
}


void Sys_InitInput(void)
{
    // no input with dedicated servers
    if ( com_dedicated->integer ) {
            return;
    }
	
    // The Cvars don't seem to work really early.
    [(Q3Controller *)[NSApp delegate] showBanner];

    Com_Printf( "------- Input Initialization -------\n" );

    if (!distantPast)
        distantPast = [[NSDate distantPast] retain];

    // For hide support.  If we don't do this, then the command key will get stuck on when we hide (since we won't get the flags changed event when it goes up).
    currentModifierFlags = 0;
    
    r_fullscreen = Cvar_Get( "r_fullscreen", "1", CVAR_ARCHIVE | CVAR_LATCH );
    in_nomouse = Cvar_Get( "in_nomouse", "0", 0 );
    in_showevents = Cvar_Get( "in_showevents", "0", 0 );

    // these defaults were arrived at via emprical testing between a Windows box and a Mac OS X box
#define ACT_LIKE_WINDOWS
#ifdef ACT_LIKE_WINDOWS
    in_mouseLowEndSlope = Cvar_Get("in_mouseLowEndSlope", "3.5", CVAR_ARCHIVE);
    if (in_mouseLowEndSlope->value < 1) {
        Cvar_Set("in_mouseLowEndSlope", "1");
    }
#else
    in_mouseLowEndSlope = Cvar_Get("in_mouseLowEndSlope", "1", CVAR_ARCHIVE);
    if (in_mouseLowEndSlope->value < 1) {
        Cvar_Set("in_mouseLowEndSlope", "1");
    }
#endif

    in_mouseHighEndCutoff = Cvar_Get("in_mouseHighEndCutoff", "20", CVAR_ARCHIVE);
    if (in_mouseLowEndSlope->value < 1) {
        Cvar_Set("in_mouseHighEndCutoff", "1");
    }
    in_disableOSMouseScaling = Cvar_Get("in_disableOSMouseScaling", "1", CVAR_ARCHIVE );
    
    glw_state.display = Sys_DisplayToUse();

    inputActive = qtrue;

    if ( in_nomouse->integer == 0 )
        Sys_StartMouseInput();
    else
        Com_Printf( "  in_nomouse is set, skipping.\n" );

    Com_Printf( "------------------------------------\n" );
}

void Sys_ShutdownInput(void)
{
    // no input with dedicated servers
    if ( !com_dedicated || com_dedicated->integer ) {
            return;
    }

    Com_Printf( "------- Input Shutdown -------\n" );
    if ( !inputActive ) {
        return;
    }
    inputActive = qfalse;

    if (mouseactive)
        Sys_StopMouseInput();

    Com_Printf( "------------------------------\n" );
}

static void Sys_LockMouseInInputRect(CGRect rect)
{
    CGPoint center;
    
    center.x = rect.origin.x + rect.size.width / 2.0;
    center.y = rect.origin.y + rect.size.height / 2.0;

    // Now, put the mouse in the middle of the input rect (anywhere over it would do)
    // and don't allow it to move.  This means that the user won't be able to accidentally
    // select another application.
    Sys_PreventMouseMovement(center);
}

extern void Sys_UpdateWindowMouseInputRect(void);

static void Sys_StartMouseInput()
{
    NXEventHandle eventStatus;
    CGMouseDelta dx, dy;

    if (mouseactive) {
        //Com_Printf("**** Attempted to start mouse input while already started\n");
        return;
    }

    Com_Printf("Starting mouse input\n");

    mouseactive = qtrue;
    if (inputRectValid && !glConfig.isFullscreen)
        // Make sure that if window moved we don't hose the user...
        Sys_UpdateWindowMouseInputRect();

    Sys_LockMouseInInputRect(inputRect);

    // Grab any mouse delta information to reset the last delta buffer
    CGGetLastMouseDelta(&dx, &dy);
    
    // Turn off mouse scaling
    if (in_disableOSMouseScaling->integer==0 && (eventStatus = NXOpenEventStatus())) {
        NXMouseScaling newScaling;

        NXGetMouseScaling(eventStatus, &originalScaling);
        newScaling.numScaleLevels = 1;
        newScaling.scaleThresholds[0] = 1;
        newScaling.scaleFactors[0] = -1;
        NXSetMouseScaling(eventStatus, &newScaling);
        NXCloseEventStatus(eventStatus);
    }
    
    [NSCursor hide];
}

static void Sys_StopMouseInput()
{
    NXEventHandle eventStatus;
    if (!mouseactive) {
        //Com_Printf("**** Attempted to stop mouse input while already stopped\n");
        return;
    }
    
    Com_Printf("Stopping mouse input\n");
    
    // Restore mouse scaling
    if (in_disableOSMouseScaling->integer == 0 && (eventStatus = NXOpenEventStatus())) {
        NXSetMouseScaling(eventStatus, &originalScaling);
        NXCloseEventStatus(eventStatus);
    }

    mouseactive = qfalse;
    Sys_ReenableMouseMovement();

    [NSCursor unhide];
}

//===========================================================================

#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h>

static char *Sys_ConsoleInput(void)
{
    extern qboolean stdin_active;
    static char text[256];
    int     len;
    fd_set	fdset;
    struct timeval timeout;

    if (!com_dedicated || !com_dedicated->integer)
        return NULL;
    
    if (!stdin_active)
        return NULL;
    
    FD_ZERO(&fdset);
    FD_SET(fileno(stdin), &fdset);
    timeout.tv_sec = 0;
    timeout.tv_usec = 0;
    if (select (1, &fdset, NULL, NULL, &timeout) == -1 || !FD_ISSET(fileno(stdin), &fdset))
        return NULL;

    len = read (fileno(stdin), text, sizeof(text));
    if (len == 0) { // eof!
        stdin_active = qfalse;
        return NULL;
    }

    if (len < 1)
        return NULL;
    text[len-1] = 0;    // rip off the /n and terminate

    return text;
}

//===========================================================================
// Mouse input
//===========================================================================

#define MAX_DISPLAYS 128

CGDirectDisplayID Sys_DisplayToUse(void)
{
    static BOOL gotDisplay =  NO;
    static CGDirectDisplayID displayToUse;
    
    cvar_t   *vid_screen;
    CGDisplayErr err;
    CGDirectDisplayID displays[MAX_DISPLAYS];
    CGDisplayCount displayCount;
    int displayIndex;
    
    if (gotDisplay)
        return displayToUse;
    gotDisplay = YES;    
    
    err = CGGetActiveDisplayList(MAX_DISPLAYS, displays, &displayCount);
    if (err != CGDisplayNoErr)
        Sys_Error("Cannot get display list -- CGGetActiveDisplayList returned %d.\n", err);

    // -1, the default, means to use the main screen

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -