bring across the VID and IN modules for svga, x11 and glx from OT.

This commit is contained in:
Bill Currie 2000-05-23 06:36:33 +00:00
parent 55d2328c77
commit 3951d1fe4c
16 changed files with 2326 additions and 2002 deletions

52
include/context_x11.h Normal file
View file

@ -0,0 +1,52 @@
/*
context_x11.h
(description)
Copyright (C) 1996-1997 Id Software, Inc.
Copyright (C) 1999,2000 contributors of the QuakeForge project
Please see the file "AUTHORS" for a list of contributors
This program 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.
This program 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 this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
$Id$
*/
#ifndef __CONTEXT_X11_H__
#define __CONTEXT_X11_H__
#include <qtypes.h>
#include <X11/Xlib.h>
void GetEvent( void );
extern Display *x_disp;
extern Window x_win;
extern qboolean doShm;
extern int x_shmeventtype;
extern qboolean oktodraw;
qboolean x11_add_event( int event, void (*event_handler)(XEvent *));
qboolean x11_del_event( int event, void (*event_handler)(XEvent *));
void x11_process_event( void );
void x11_process_events( void );
void x11_open_display( void );
void x11_close_display( void );
#endif // __CONTEXT_X11_H__

53
include/dga_check.h Normal file
View file

@ -0,0 +1,53 @@
/*
dga_check.h
Definitions for XFree86 DGA and VidMode support
Copyright (C) 2000 Marcus Sundberg [mackan@stacken.kth.se]
Copyright (C) 2000 contributors of the QuakeForge project
Please see the file "AUTHORS" for a list of contributors
This program 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.
This program 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 this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
$Id$
*/
#ifndef DGA_CHECK_H
#define DGA_CHECK_H
#include <X11/Xlib.h>
extern cvar_t *vid_dga_mouseaccel;
/*
VID_CheckDGA
Check for the presence of the XFree86-DGA support in the X server
*/
int VID_CheckDGA(Display *dpy, int *maj_ver, int *min_ver, int *hasvideo);
/*
VID_CheckVMode
Check for the presence of the XFree86-VMode X server extension
*/
int VID_CheckVMode(Display *dpy, int *maj_ver, int *min_ver);
#endif /* DGA_CHECK_H */

View file

@ -40,6 +40,9 @@ void IN_Shutdown (void);
void IN_Commands (void);
// oportunity for devices to stick commands on the script buffer
void IN_SendKeyEvents (void);
// Perform Key_Event () callbacks until the input que is empty
void IN_Move (usercmd_t *cmd);
// add additional movement on top of the keyboard move cmd

View file

@ -72,9 +72,6 @@ void Sys_Sleep (void);
// called to yield for a little bit so as
// not to hog cpu when paused or debugging
void Sys_SendKeyEvents (void);
// Perform Key_Event () callbacks until the input que is empty
void Sys_LowFPPrecision (void);
void Sys_HighFPPrecision (void);
void Sys_SetFPCW (void);

View file

@ -58,7 +58,7 @@ soft_SOURCES= cl_model.c cl_trans.c d_edge.c d_fill.c d_init.c d_modech.c \
r_draw.c r_edge.c r_efrag.c r_light.c r_main.c r_misc.c \
r_part.c r_sky.c r_sprite.c r_surf.c r_vars.c sw_view.c \
screen.c \
d_copy.S d_draw.S d_draw16.S d_parta.S d_polysa.S d_scana.S \
d_draw.S d_draw16.S d_parta.S d_polysa.S d_scana.S \
d_spr8.S d_varsa.S r_aclipa.S r_aliasa.S r_drawa.S r_edgea.S \
r_varsa.S surf16.S surf8.S
ogl_SOURCES= gl_draw.c gl_mesh.c gl_model.c gl_ngraph.c gl_part.c \
@ -67,9 +67,9 @@ ogl_SOURCES= gl_draw.c gl_mesh.c gl_model.c gl_ngraph.c gl_part.c \
mgl_SOURCES= vid_mgl.c in_win.c
ggi_SOURCES= vid_ggi.c
svga_SOURCES= vid_svgalib.c
x11_SOURCES= vid_x11.c
glx_SOURCES= vid_glx.c
svga_SOURCES= d_copy.S vid_svgalib.c in_svgalib.c
x11_SOURCES= vid_x11.c in_x11.c context_x11.c dga_check.c
glx_SOURCES= vid_glx.c in_x11.c context_x11.c dga_check.c
wgl_SOURCES= vid_wgl.c
qf_server_SOURCES= $(common_SOURCES) $(server_SOURCES)

View file

@ -31,6 +31,7 @@
#endif
#include <ctype.h>
#include "bothdefs.h"
#include "input.h"
#include "in_win.h"
#include "sys.h"
#include "sys.h"
@ -1581,7 +1582,7 @@ void Host_Frame (float time)
host_frametime = 0.2;
// get new key events
Sys_SendKeyEvents ();
IN_SendKeyEvents ();
// allow mice or other external controllers to add commands
IN_Commands ();
@ -1744,9 +1745,9 @@ void Host_Init (quakeparms_t *parms)
if (!host_colormap)
Sys_Error ("Couldn't load gfx/colormap.lmp");
#ifdef __linux__
IN_Init ();
CDAudio_Init ();
VID_Init (host_basepal);
IN_Init ();
Draw_Init ();
SCR_Init ();
R_Init ();

View file

@ -29,6 +29,7 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "input.h"
#include "sys.h"
#include "console.h"
#include "keys.h"
@ -693,7 +694,7 @@ void Con_NotifyBox (char *text)
{
t1 = Sys_DoubleTime ();
SCR_UpdateScreen ();
Sys_SendKeyEvents ();
IN_SendKeyEvents ();
t2 = Sys_DoubleTime ();
realtime += t2-t1; // make the cursor blink
} while (key_count < 0);

163
source/context_x11.c Normal file
View file

@ -0,0 +1,163 @@
/*
context_x11.c
general x11 context layer
Copyright (C) 1996-1997 Id Software, Inc.
Copyright (C) 2000 Zephaniah E. Hull <warp@whitestar.soark.net>
Copyright (C) 1999,2000 contributors of the QuakeForge project
Please see the file "AUTHORS" for a list of contributors
This program 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.
This program 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 this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
$Id$
*/
#include <config.h>
#include <ctype.h>
#include <sys/time.h>
#include <sys/types.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/keysym.h>
#include <X11/extensions/XShm.h>
#include <errno.h>
#include <context_x11.h>
#include <qtypes.h>
#include <vid.h>
#include <sys.h>
static void (*event_handlers[LASTEvent]) (XEvent *);
qboolean oktodraw = false;
int x_shmeventtype;
static int x_disp_ref_count = 0;
Display *x_disp = NULL;
qboolean
x11_add_event(int event, void (*event_handler)(XEvent *))
{
if (event >= LASTEvent) {
printf("event: %d, LASTEvent: %d\n", event, LASTEvent);
return false;
}
if (event_handlers[event] != NULL)
return false;
event_handlers[event] = event_handler;
return true;
}
qboolean
x11_del_event(int event, void (*event_handler)(XEvent *))
{
if (event >= LASTEvent)
return false;
if (event_handlers[event] != event_handler)
return false;
event_handlers[event] = NULL;
return true;
}
void
x11_process_event( void )
{
XEvent x_event;
XNextEvent(x_disp, &x_event);
if ( x_event.type >= LASTEvent ) {
// FIXME: KLUGE!!!!!!
if (x_event.type == x_shmeventtype)
oktodraw = 1;
return;
}
if (event_handlers[x_event.type])
event_handlers[x_event.type](&x_event);
}
void
x11_process_events(void)
{
/* Get events from X server. */
while ( XPending( x_disp )) {
x11_process_event();
}
}
// ========================================================================
// Tragic death handler
// ========================================================================
static void
TragicDeath(int signal_num)
{
//XCloseDisplay(x_disp);
//VID_Shutdown();
Sys_Error("This death brought to you by the number %d\n", signal_num);
}
void
x11_open_display( void )
{
struct sigaction sa;
if ( !x_disp ) {
x_disp = XOpenDisplay( NULL );
if ( !x_disp ) {
Sys_Error("x11_open_display: Could not open display [%s]\n", XDisplayName( NULL ));
}
// catch signals
sigaction(SIGINT, 0, &sa);
sigaction(SIGTERM, 0, &sa);
sa.sa_handler = TragicDeath;
sigaction(SIGINT, &sa, 0);
sigaction(SIGTERM, &sa, 0);
// for debugging only
XSynchronize( x_disp, True );
x_disp_ref_count=1;
} else {
x_disp_ref_count++;
}
}
void
x11_close_display( void )
{
if (!--x_disp_ref_count) {
XCloseDisplay( x_disp );
x_disp = NULL;
}
}

107
source/dga_check.c Normal file
View file

@ -0,0 +1,107 @@
/*
dga_check.c
Routines to check for XFree86 DGA and VidMode extensions
Copyright (C) 2000 Marcus Sundberg [mackan@stacken.kth.se]
Copyright (C) 2000 contributors of the QuakeForge project
Please see the file "AUTHORS" for a list of contributors
This program 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.
This program 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 this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
$Id$
*/
#include <quakedef.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#if defined(HAS_DGA)
#include <X11/extensions/xf86dga.h>
#endif
#if defined(HAS_VIDMODE)
#include <X11/extensions/xf86vmode.h>
#endif
#include <dga_check.h>
/*
VID_CheckDGA
Check for the presence of the XFree86-DGA X server extension
*/
int
VID_CheckDGA(Display *dpy, int *maj_ver, int *min_ver, int *hasvideo)
{
#if defined(HAS_DGA)
int event_base, error_base, dgafeat, dummy;
if (! XF86DGAQueryExtension(dpy, &event_base, &error_base)) {
return 0;
}
if (maj_ver == NULL) maj_ver = &dummy;
if (min_ver == NULL) min_ver = &dummy;
if (! XF86DGAQueryVersion(dpy, maj_ver, min_ver)) {
return 0;
}
if (! XF86DGAQueryDirectVideo(dpy, DefaultScreen(dpy), &dgafeat)) {
*hasvideo = 0;
} else {
*hasvideo = (dgafeat & XF86DGADirectPresent);
}
return 1;
#else
return 0;
#endif // HAS_DGA
}
/*
VID_CheckVMode
Check for the presence of the XFree86-VidMode X server extension
*/
int
VID_CheckVMode(Display *dpy, int *maj_ver, int *min_ver)
{
#if defined(HAS_VIDMODE)
int event_base, error_base;
int dummy;
if (! XF86VidModeQueryExtension(dpy, &event_base, &error_base)) {
return 0;
}
if (maj_ver == NULL) maj_ver = &dummy;
if (min_ver == NULL) min_ver = &dummy;
if (! XF86VidModeQueryVersion(dpy, maj_ver, min_ver)) {
return 0;
}
return 1;
#else
return 0;
#endif // HAS_DGA
}

View file

@ -35,6 +35,7 @@
#include <stdlib.h>
#include <time.h>
#include "input.h"
#include "bothdefs.h" // needed by: common.h, net.h, client.h
#include "qendian.h"
#include "bspfile.h" // needed by: glquake.h
@ -1120,7 +1121,7 @@ int SCR_ModalMessage (char *text)
do
{
key_count = -1; // wait for a key down and up
Sys_SendKeyEvents ();
IN_SendKeyEvents ();
} while (key_lastpress != 'y' && key_lastpress != 'n' && key_lastpress != K_ESCAPE);
scr_fullupdate = 0;

381
source/in_svgalib.c Normal file
View file

@ -0,0 +1,381 @@
/*
in_svgalib.c
(description)
Copyright (C) 1996-1997 Id Software, Inc.
Copyright (C) 1999-2000 Marcus Sundberg [mackan@stacken.kth.se]
Copyright (C) 1999,2000 contributors of the QuakeForge project
Please see the file "AUTHORS" for a list of contributors
This program 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.
This program 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 this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
$Id$
*/
#include "qtypes.h"
#include "quakedef.h"
#include "keys.h"
#include "client.h"
#include "sys.h"
#include "console.h"
#include "cvar.h"
#include "cmd.h"
#include "qargs.h"
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <vga.h>
#include <vgakeyboard.h>
#include <vgamouse.h>
static int UseKeyboard = 1;
static int UseMouse = 1;
static int in_svgalib_inited = 0;
static unsigned char scantokey[128];
static int mouse_buttons;
static int mouse_buttonstate;
static int mouse_oldbuttonstate;
static float mouse_x, mouse_y;
static float old_mouse_x, old_mouse_y;
static int mx, my;
static void IN_init_kb();
static void IN_init_mouse();
cvar_t *_windowed_mouse;
cvar_t *m_filter;
static cvar_t *mouse_button_commands[3];
static void keyhandler(int scancode, int state)
{
int sc;
sc = scancode & 0x7f;
#if 0
Con_Printf("scancode=%x (%d%s)\n", scancode, sc, scancode&0x80?"+128":"");
#endif
Key_Event(scantokey[sc], state == KEY_EVENTPRESS);
}
static void mousehandler(int buttonstate, int dx, int dy, int dz, int drx, int dry, int drz)
{
mouse_buttonstate = buttonstate;
mx += dx;
my += dy;
if (drx > 0) {
Key_Event(K_MWHEELUP, 1);
Key_Event(K_MWHEELUP, 0);
} else if (drx < 0) {
Key_Event(K_MWHEELDOWN, 1);
Key_Event(K_MWHEELDOWN, 0);
}
}
void Force_CenterView_f(void)
{
cl.viewangles[PITCH] = 0;
}
int IN_Init(void)
{
if (COM_CheckParm("-nokbd")) UseKeyboard = 0;
if (COM_CheckParm("-nomouse")) UseMouse = 0;
if (UseKeyboard)
IN_init_kb();
if (UseMouse)
IN_init_mouse();
in_svgalib_inited = 1;
return 1;
}
static void IN_init_kb()
{
int i;
for (i=0 ; i<128 ; i++) {
scantokey[i] = ' ';
}
scantokey[ 1] = K_ESCAPE;
scantokey[ 2] = '1';
scantokey[ 3] = '2';
scantokey[ 4] = '3';
scantokey[ 5] = '4';
scantokey[ 6] = '5';
scantokey[ 7] = '6';
scantokey[ 8] = '7';
scantokey[ 9] = '8';
scantokey[ 10] = '9';
scantokey[ 11] = '0';
scantokey[ 12] = '-';
scantokey[ 13] = '=';
scantokey[ 14] = K_BACKSPACE;
scantokey[ 15] = K_TAB;
scantokey[ 16] = 'q';
scantokey[ 17] = 'w';
scantokey[ 18] = 'e';
scantokey[ 19] = 'r';
scantokey[ 20] = 't';
scantokey[ 21] = 'y';
scantokey[ 22] = 'u';
scantokey[ 23] = 'i';
scantokey[ 24] = 'o';
scantokey[ 25] = 'p';
scantokey[ 26] = '[';
scantokey[ 27] = ']';
scantokey[ 28] = K_ENTER;
scantokey[ 29] = K_CTRL; /*left */
scantokey[ 30] = 'a';
scantokey[ 31] = 's';
scantokey[ 32] = 'd';
scantokey[ 33] = 'f';
scantokey[ 34] = 'g';
scantokey[ 35] = 'h';
scantokey[ 36] = 'j';
scantokey[ 37] = 'k';
scantokey[ 38] = 'l';
scantokey[ 39] = ';';
scantokey[ 40] = '\'';
scantokey[ 41] = '`';
scantokey[ 42] = K_SHIFT; /*left */
scantokey[ 43] = '\\';
scantokey[ 44] = 'z';
scantokey[ 45] = 'x';
scantokey[ 46] = 'c';
scantokey[ 47] = 'v';
scantokey[ 48] = 'b';
scantokey[ 49] = 'n';
scantokey[ 50] = 'm';
scantokey[ 51] = ',';
scantokey[ 52] = '.';
scantokey[ 53] = '/';
scantokey[ 54] = K_SHIFT; /*right */
scantokey[ 55] = KP_MULTIPLY;
scantokey[ 56] = K_ALT; /*left */
scantokey[ 57] = ' ';
scantokey[ 58] = K_CAPSLOCK;
scantokey[ 59] = K_F1;
scantokey[ 60] = K_F2;
scantokey[ 61] = K_F3;
scantokey[ 62] = K_F4;
scantokey[ 63] = K_F5;
scantokey[ 64] = K_F6;
scantokey[ 65] = K_F7;
scantokey[ 66] = K_F8;
scantokey[ 67] = K_F9;
scantokey[ 68] = K_F10;
scantokey[ 69] = KP_NUMLCK;
scantokey[ 70] = K_SCRLCK;
scantokey[ 71] = KP_HOME;
scantokey[ 72] = KP_UPARROW;
scantokey[ 73] = KP_PGUP;
scantokey[ 74] = KP_MINUS;
scantokey[ 75] = KP_LEFTARROW;
scantokey[ 76] = KP_5;
scantokey[ 77] = KP_RIGHTARROW;
scantokey[ 79] = KP_END;
scantokey[ 78] = KP_PLUS;
scantokey[ 80] = KP_DOWNARROW;
scantokey[ 81] = KP_PGDN;
scantokey[ 82] = KP_INS;
scantokey[ 83] = KP_DEL;
/* 84 to 86 not used */
scantokey[ 87] = K_F11;
scantokey[ 88] = K_F12;
/* 89 to 95 not used */
scantokey[ 96] = KP_ENTER; /* keypad enter */
scantokey[ 97] = K_CTRL; /* right */
scantokey[ 98] = KP_DIVIDE;
scantokey[ 99] = K_PRNTSCR; /* print screen */
scantokey[100] = K_ALT; /* right */
scantokey[101] = K_PAUSE; /* break */
scantokey[102] = K_HOME;
scantokey[103] = K_UPARROW;
scantokey[104] = K_PGUP;
scantokey[105] = K_LEFTARROW;
scantokey[106] = K_RIGHTARROW;
scantokey[107] = K_END;
scantokey[108] = K_DOWNARROW;
scantokey[109] = K_PGDN;
scantokey[110] = K_INS;
scantokey[111] = K_DEL;
scantokey[119] = K_PAUSE;
if (keyboard_init()) {
Sys_Error("keyboard_init() failed");
}
keyboard_seteventhandler(keyhandler);
}
static void IN_init_mouse()
{
int mtype;
char *mousedev;
int mouserate = MOUSE_DEFAULTSAMPLERATE;
mouse_button_commands[0] = Cvar_Get ("mouse1","+attack",0,"None");
mouse_button_commands[1] = Cvar_Get ("mouse2","+strafe",0,"None");
mouse_button_commands[2] = Cvar_Get ("mouse2","+forward",0,"None");
m_filter = Cvar_Get ("m_filter","0",0,"None");
Cmd_AddCommand("force_centerview", Force_CenterView_f);
mouse_buttons = 3;
mtype = vga_getmousetype();
mousedev = "/dev/mouse";
if (getenv("MOUSEDEV")) mousedev = getenv("MOUSEDEV");
if (COM_CheckParm("-mdev")) {
mousedev = com_argv[COM_CheckParm("-mdev")+1];
}
if (getenv("MOUSERATE")) mouserate = atoi(getenv("MOUSERATE"));
if (COM_CheckParm("-mrate")) {
mouserate = atoi(com_argv[COM_CheckParm("-mrate")+1]);
}
#if 0
printf("Mouse: dev=%s,type=%s,speed=%d\n",
mousedev, mice[mtype].name, mouserate);
#endif
if (mouse_init(mousedev, mtype, mouserate)) {
Con_Printf("No mouse found\n");
UseMouse = 0;
} else{
mouse_seteventhandler((void*)mousehandler);
}
}
void IN_Shutdown(void)
{
Con_Printf("IN_Shutdown\n");
if (UseMouse) mouse_close();
if (UseKeyboard) keyboard_close();
in_svgalib_inited = 0;
}
void IN_SendKeyEvents(void)
{
if (!in_svgalib_inited) return;
if (UseKeyboard) {
while ((keyboard_update()));
}
}
void IN_Commands(void)
{
if (UseMouse)
{
/* Poll mouse values */
while (mouse_update())
;
/* Perform button actions */
if ((mouse_buttonstate & MOUSE_LEFTBUTTON) &&
!(mouse_oldbuttonstate & MOUSE_LEFTBUTTON))
Key_Event (K_MOUSE1, true);
else if (!(mouse_buttonstate & MOUSE_LEFTBUTTON) &&
(mouse_oldbuttonstate & MOUSE_LEFTBUTTON))
Key_Event (K_MOUSE1, false);
if ((mouse_buttonstate & MOUSE_RIGHTBUTTON) &&
!(mouse_oldbuttonstate & MOUSE_RIGHTBUTTON))
Key_Event (K_MOUSE2, true);
else if (!(mouse_buttonstate & MOUSE_RIGHTBUTTON) &&
(mouse_oldbuttonstate & MOUSE_RIGHTBUTTON))
Key_Event (K_MOUSE2, false);
if ((mouse_buttonstate & MOUSE_MIDDLEBUTTON) &&
!(mouse_oldbuttonstate & MOUSE_MIDDLEBUTTON))
Key_Event (K_MOUSE3, true);
else if (!(mouse_buttonstate & MOUSE_MIDDLEBUTTON) &&
(mouse_oldbuttonstate & MOUSE_MIDDLEBUTTON))
Key_Event (K_MOUSE3, false);
mouse_oldbuttonstate = mouse_buttonstate;
}
}
void IN_Move(usercmd_t *cmd)
{
if (!UseMouse) return;
/* Poll mouse values */
while (mouse_update())
;
if (m_filter->value) {
mouse_x = (mx + old_mouse_x) * 0.5;
mouse_y = (my + old_mouse_y) * 0.5;
} else {
mouse_x = mx;
mouse_y = my;
}
old_mouse_x = mx;
old_mouse_y = my;
/* Clear for next update */
mx = my = 0;
mouse_x *= sensitivity->value;
mouse_y *= sensitivity->value;
/* Add mouse X/Y movement to cmd */
if ( (in_strafe.state & 1) ||
(lookstrafe->value && (in_mlook.state & 1) )) {
cmd->sidemove += m_side->value * mouse_x;
} else {
cl.viewangles[YAW] -= m_yaw->value * mouse_x;
}
if ((in_mlook.state & 1)) V_StopPitchDrift();
if ((in_mlook.state & 1) && !(in_strafe.state & 1)) {
cl.viewangles[PITCH] += m_pitch->value * mouse_y;
if (cl.viewangles[PITCH] > 80) {
cl.viewangles[PITCH] = 80;
}
if (cl.viewangles[PITCH] < -70) {
cl.viewangles[PITCH] = -70;
}
} else {
if ((in_strafe.state & 1) && noclip_anglehack) {
cmd->upmove -= m_forward->value * mouse_y;
} else {
cmd->forwardmove -= m_forward->value * mouse_y;
}
}
}

510
source/in_x11.c Normal file
View file

@ -0,0 +1,510 @@
/*
in_x11.c
general x11 input driver
Copyright (C) 1996-1997 Id Software, Inc.
Copyright (C) 2000 Marcus Sundberg [mackan@stacken.kth.se]
Copyright (C) 1999,2000 contributors of the QuakeForge project
Please see the file "AUTHORS" for a list of contributors
This program 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.
This program 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 this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
$Id$
*/
#define _BSD
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <errno.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <X11/Xlib.h>
#include <X11/keysym.h>
#ifdef HAS_DGA
#include <X11/extensions/XShm.h>
#include <X11/extensions/xf86dga.h>
#endif
#include "quakedef.h"
#include "d_local.h"
#include "sound.h"
#include "keys.h"
#include "cvar.h"
#include "sys.h"
#include "cmd.h"
#include "draw.h"
#include "console.h"
#include "client.h"
#include "context_x11.h"
#include "qargs.h"
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
cvar_t *_windowed_mouse;
cvar_t *m_filter;
#ifdef HAS_DGA
cvar_t *in_dgamouse;
cvar_t *vid_dga_mouseaccel;
#endif
static qboolean mouse_avail;
static float mouse_x, mouse_y;
static float old_mouse_x, old_mouse_y;
static int p_mouse_x, p_mouse_y;
static float old__windowed_mouse;
static Cursor nullcursor = None;
#define KEY_MASK (KeyPressMask | KeyReleaseMask)
#define MOUSE_MASK (ButtonPressMask | ButtonReleaseMask | PointerMotionMask)
#define INPUT_MASK (KEY_MASK | MOUSE_MASK)
/*
======================
Create an empty cursor
======================
*/
static void
CreateNullCursor(Display *display, Window root)
{
Pixmap cursormask;
XGCValues xgc;
GC gc;
XColor dummycolour;
if (nullcursor != None) return;
cursormask = XCreatePixmap(display, root, 1, 1, 1/*depth*/);
xgc.function = GXclear;
gc = XCreateGC(display, cursormask, GCFunction, &xgc);
XFillRectangle(display, cursormask, gc, 0, 0, 1, 1);
dummycolour.pixel = 0;
dummycolour.red = 0;
dummycolour.flags = 04;
nullcursor = XCreatePixmapCursor(display, cursormask, cursormask,
&dummycolour,&dummycolour, 0,0);
XFreePixmap(display,cursormask);
XFreeGC(display,gc);
}
static int
XLateKey(XKeyEvent *ev)
{
int key = 0;
KeySym keysym;
keysym = XLookupKeysym(ev, 0);
switch(keysym) {
case XK_KP_Page_Up: key = KP_PGUP; break;
case XK_Page_Up: key = K_PGUP; break;
case XK_KP_Page_Down: key = KP_PGDN; break;
case XK_Page_Down: key = K_PGDN; break;
case XK_KP_Home: key = KP_HOME; break;
case XK_Home: key = K_HOME; break;
case XK_KP_End: key = KP_END; break;
case XK_End: key = K_END; break;
case XK_KP_Left: key = KP_LEFTARROW; break;
case XK_Left: key = K_LEFTARROW; break;
case XK_KP_Right: key = KP_RIGHTARROW; break;
case XK_Right: key = K_RIGHTARROW; break;
case XK_KP_Down: key = KP_DOWNARROW; break;
case XK_Down: key = K_DOWNARROW; break;
case XK_KP_Up: key = KP_UPARROW; break;
case XK_Up: key = K_UPARROW; break;
case XK_Escape: key = K_ESCAPE; break;
case XK_KP_Enter: key = KP_ENTER; break;
case XK_Return: key = K_ENTER; break;
case XK_Tab: key = K_TAB; break;
case XK_F1: key = K_F1; break;
case XK_F2: key = K_F2; break;
case XK_F3: key = K_F3; break;
case XK_F4: key = K_F4; break;
case XK_F5: key = K_F5; break;
case XK_F6: key = K_F6; break;
case XK_F7: key = K_F7; break;
case XK_F8: key = K_F8; break;
case XK_F9: key = K_F9; break;
case XK_F10: key = K_F10; break;
case XK_F11: key = K_F11; break;
case XK_F12: key = K_F12; break;
case XK_BackSpace: key = K_BACKSPACE; break;
case XK_KP_Delete: key = KP_DEL; break;
case XK_Delete: key = K_DEL; break;
case XK_Pause: key = K_PAUSE; break;
case XK_Shift_L:
case XK_Shift_R: key = K_SHIFT; break;
case XK_Execute:
case XK_Control_L:
case XK_Control_R: key = K_CTRL; break;
case XK_Mode_switch:
case XK_Alt_L:
case XK_Meta_L:
case XK_Alt_R:
case XK_Meta_R: key = K_ALT; break;
case XK_Caps_Lock: key = K_CAPSLOCK; break;
case XK_KP_Begin: key = K_AUX30; break;
case XK_Insert: key = K_INS; break;
case XK_KP_Insert: key = KP_INS; break;
case XK_KP_Multiply: key = KP_MULTIPLY; break;
case XK_KP_Add: key = KP_PLUS; break;
case XK_KP_Subtract: key = KP_MINUS; break;
case XK_KP_Divide: key = KP_DIVIDE; break;
/* For Sun keyboards */
case XK_F27: key = K_HOME; break;
case XK_F29: key = K_PGUP; break;
case XK_F33: key = K_END; break;
case XK_F35: key = K_PGDN; break;
#if 0
case 0x021: key = '1';break;/* [!] */
case 0x040: key = '2';break;/* [@] */
case 0x023: key = '3';break;/* [#] */
case 0x024: key = '4';break;/* [$] */
case 0x025: key = '5';break;/* [%] */
case 0x05e: key = '6';break;/* [^] */
case 0x026: key = '7';break;/* [&] */
case 0x02a: key = '8';break;/* [*] */
case 0x028: key = '9';;break;/* [(] */
case 0x029: key = '0';break;/* [)] */
case 0x05f: key = '-';break;/* [_] */
case 0x02b: key = '=';break;/* [+] */
case 0x07c: key = '\'';break;/* [|] */
case 0x07d: key = '[';break;/* [}] */
case 0x07b: key = ']';break;/* [{] */
case 0x022: key = '\'';break;/* ["] */
case 0x03a: key = ';';break;/* [:] */
case 0x03f: key = '/';break;/* [?] */
case 0x03e: key = '.';break;/* [>] */
case 0x03c: key = ',';break;/* [<] */
#endif
default:
if (keysym < 128) {
/* ASCII keys */
key = keysym;
if (key >= 'A' && key <= 'Z') {
key = key + ('a' - 'A');
}
}
break;
}
return key;
}
static void
event_key(XEvent *event)
{
Key_Event(XLateKey(&event->xkey), event->type == KeyPress);
}
static void
event_button(XEvent *event)
{
int but;
but = event->xbutton.button;
if (but == 2) but = 3;
else if (but == 3) but = 2;
switch(but) {
case 1:
case 2:
case 3:
Key_Event(K_MOUSE1 + but - 1, event->type == ButtonPress);
break;
case 4:
Key_Event(K_MWHEELUP, 1);
Key_Event(K_MWHEELUP, 0);
break;
case 5:
Key_Event(K_MWHEELDOWN, 1);
Key_Event(K_MWHEELDOWN, 0);
break;
}
}
static void
center_pointer(void)
{
XEvent event;
event.type = MotionNotify;
event.xmotion.display = x_disp;
event.xmotion.window = x_win;
event.xmotion.x = vid.width / 2;
event.xmotion.y = vid.height / 2;
XSendEvent(x_disp, x_win, False, PointerMotionMask, &event);
XWarpPointer(x_disp, None, x_win, 0, 0, 0, 0,
vid.width / 2, vid.height / 2);
}
static void
event_motion(XEvent *event)
{
#ifdef HAS_DGA
if (in_dgamouse->value) {
mouse_x += event->xmotion.x_root * vid_dga_mouseaccel->value;
mouse_y += event->xmotion.y_root * vid_dga_mouseaccel->value;
} else
#endif
{
//printf("_windowed_mouse: %f\n", _windowed_mouse->value);
//printf("CurrentTime: %ld\n", CurrentTime);
if (_windowed_mouse->value) {
if (!event->xmotion.send_event) {
mouse_x += (event->xmotion.x - p_mouse_x);
mouse_y += (event->xmotion.y - p_mouse_y);
#undef ABS
#define ABS(a) (((int)(a) < 0) ? -(a) : (a))
if (ABS(vid.width/2 - event->xmotion.x)
> vid.width / 4
|| ABS(vid.height/2 - event->xmotion.y)
> vid.height / 4) {
#undef ABS
center_pointer();
}
}
} else {
mouse_x += (event->xmotion.x - p_mouse_x);
mouse_y += (event->xmotion.y - p_mouse_y);
}
p_mouse_x = event->xmotion.x;
p_mouse_y = event->xmotion.y;
}
}
void
IN_Commands(void)
{
if (old__windowed_mouse != _windowed_mouse->value) {
old__windowed_mouse = _windowed_mouse->value;
if (!_windowed_mouse->value) {
/* ungrab the pointer */
XUngrabPointer(x_disp,CurrentTime);
} else {
/* grab the pointer */
XGrabPointer(x_disp, x_win, True, MOUSE_MASK, GrabModeAsync,
GrabModeAsync, x_win, None, CurrentTime);
//XGrabPointer(x_disp,x_win,True,0,GrabModeAsync,
// GrabModeAsync,x_win,None,CurrentTime);
}
}
}
void
IN_SendKeyEvents(void)
{
/* Get events from X server. */
x11_process_events();
}
void
IN_Move(usercmd_t *cmd)
{
if (!mouse_avail)
return;
if (m_filter->value) {
mouse_x = (mouse_x + old_mouse_x) * 0.5;
mouse_y = (mouse_y + old_mouse_y) * 0.5;
}
old_mouse_x = mouse_x;
old_mouse_y = mouse_y;
mouse_x *= sensitivity->value;
mouse_y *= sensitivity->value;
if ( (in_strafe.state & 1) || (lookstrafe->value && (in_mlook.state & 1) ))
cmd->sidemove += m_side->value * mouse_x;
else
cl.viewangles[YAW] -= m_yaw->value * mouse_x;
if (in_mlook.state & 1)
V_StopPitchDrift ();
if ( (in_mlook.state & 1) && !(in_strafe.state & 1)) {
cl.viewangles[PITCH] += m_pitch->value * mouse_y;
if (cl.viewangles[PITCH] > 80)
cl.viewangles[PITCH] = 80;
if (cl.viewangles[PITCH] < -70)
cl.viewangles[PITCH] = -70;
} else {
if ((in_strafe.state & 1) && noclip_anglehack)
cmd->upmove -= m_forward->value * mouse_y;
else
cmd->forwardmove -= m_forward->value * mouse_y;
}
mouse_x = mouse_y = 0.0;
}
/*
static void IN_ExtraOptionDraw(unsigned int options_draw_cursor)
{
// Windowed Mouse
M_Print(16, options_draw_cursor+=8, " Use Mouse");
M_DrawCheckbox(220, options_draw_cursor, _windowed_mouse->value);
}
static void IN_ExtraOptionCmd(int option_cursor)
{
switch (option_cursor) {
case 1: // _windowed_mouse
_windowed_mouse->value = !_windowed_mouse->value;
break;
}
}
*/
/*
Called at shutdown
*/
void
IN_Shutdown(void)
{
Con_Printf("IN_Shutdown\n");
mouse_avail = 0;
XAutoRepeatOn(x_disp);
if (nullcursor != None) {
XFreeCursor(x_disp, nullcursor);
nullcursor = None;
}
#ifdef HAS_DGA
XF86DGADirectVideo(x_disp, DefaultScreen(x_disp), 0);
#endif
x11_close_display();
}
extern int scr_width, scr_height;
int
IN_Init(void)
{
// open the display
if (!x_disp)
Sys_Error("IN: No display!!\n");
if (!x_win)
Sys_Error("IN: No window!!\n");
x11_open_display(); // call to increment the reference counter
{
int attribmask = CWEventMask;
XWindowAttributes attribs_1;
XSetWindowAttributes attribs_2;
XGetWindowAttributes(x_disp, x_win, &attribs_1);
attribs_2.event_mask = attribs_1.your_event_mask | INPUT_MASK;
XChangeWindowAttributes(x_disp, x_win, attribmask, &attribs_2);
}
_windowed_mouse = Cvar_Get ("_windowed_mouse","0",CVAR_ARCHIVE,"None");
Cvar_Alias_Get ("_windowed_mouse", _windowed_mouse);
m_filter = Cvar_Get ("m_filter","0",CVAR_ARCHIVE,"None");
#ifdef HAS_DGA
vid_dga_mouseaccel = Cvar_Get ("vid_dga_mouseaccel","1",CVAR_ARCHIVE,
"None");
if (!COM_CheckParm("-nodga")) {
// XF86DGASetViewPort, XF86DGASetVidPage, and XF86DGADirectVideo's
// XF86DGADirectVideo flag are disabled till someone has a chance to
// figure out what's wrong with them (if anything) --KB
// XF86DGASetViewPort(x_disp, DefaultScreen(x_disp), 0, 0);
XF86DGADirectVideo(x_disp, DefaultScreen(x_disp),
/*XF86DGADirectGraphics|*/
XF86DGADirectMouse|XF86DGADirectKeyb);
// XF86DGASetVidPage(x_disp, DefaultScreen(x_disp), 0);
XGrabKeyboard (x_disp, x_win, True, GrabModeAsync,
GrabModeAsync, CurrentTime);
XGrabPointer (x_disp, x_win, True, MOUSE_MASK, GrabModeAsync,
GrabModeAsync, x_win, None, CurrentTime);
XWarpPointer (x_disp, None, x_win, 0, 0, 0, 0, scr_width,
scr_height);
in_dgamouse = Cvar_Get ("in_dgamouse", "1", CVAR_ROM,
"1 if you have DGA mouse support");
} else
in_dgamouse = Cvar_Get ("in_dgamouse", "0", CVAR_ROM,
"1 if you have DGA mouse support");
#endif
if (COM_CheckParm("-nomouse")) return 1;
mouse_x = mouse_y = 0.0;
mouse_avail = 1;
/* Invisible cursor */
CreateNullCursor(x_disp, x_win);
XDefineCursor(x_disp, x_win, nullcursor);
x11_add_event(KeyPress, &event_key);
x11_add_event(KeyRelease, &event_key);
x11_add_event(ButtonPress, &event_button);
x11_add_event(ButtonRelease, &event_button);
x11_add_event(MotionNotify, &event_motion);
return 1;
}

View file

@ -29,6 +29,7 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "input.h"
#include "sys.h"
#include "screen.h"
#include "r_local.h"
@ -1060,7 +1061,7 @@ int SCR_ModalMessage (char *text)
do
{
key_count = -1; // wait for a key down and up
Sys_SendKeyEvents ();
IN_SendKeyEvents ();
} while (key_lastpress != 'y' && key_lastpress != 'n' && key_lastpress != K_ESCAPE);
scr_fullupdate = 0;

View file

@ -4,6 +4,10 @@
OpenGL GLX video driver
Copyright (C) 1996-1997 Id Software, Inc.
Copyright (C) 1999-2000 Nelson Rush.
Copyright (C) 2000 Marcus Sundberg [mackan@stacken.kth.se]
Copyright (C) 1999,2000 contributors of the QuakeForge project
Please see the file "AUTHORS" for a list of contributors
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@ -26,86 +30,96 @@
$Id$
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <signal.h>
#include <math.h>
#include "bothdefs.h" // needed by: common.h, net.h, client.h
#include <values.h>
#include "qtypes.h"
#include "quakedef.h"
#include "bspfile.h" // needed by: glquake.h
#include "vid.h"
#include "sys.h"
#include "zone.h" // needed by: client.h, gl_model.h
#include "mathlib.h" // needed by: protocol.h, render.h, client.h,
// modelgen.h, glmodel.h
#include "wad.h"
#include "draw.h"
#include "cvar.h"
#include "net.h" // needed by: client.h
#include "protocol.h" // needed by: client.h
#include "cmd.h"
#include "keys.h"
#include "sbar.h"
#include "sound.h"
#include "render.h" // needed by: client.h, gl_model.h, glquake.h
#include "client.h" // need cls in this file
#include "model.h" // needed by: glquake.h
#include "console.h"
#include "glquake.h"
#include "qendian.h"
#include "glquake.h"
#include "cvar.h"
#include "qargs.h"
#include "compat.h"
#include "input.h"
#include "console.h"
#include "keys.h"
#include "menu.h"
#include "sys.h"
#include "draw.h"
#include "context_x11.h"
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <signal.h>
#ifdef HAVE_DLFCN_H
# include <dlfcn.h>
#endif
#ifndef RTLD_LAZY
# ifdef DL_LAZY
# define RTLD_LAZY DL_LAZY
# else
# define RTLD_LAZY 0
# endif
#endif
#include <GL/glx.h>
#include <X11/keysym.h>
#include <X11/cursorfont.h>
#ifdef USE_DGA
#include <X11/extensions/xf86dga.h>
#ifdef HAS_DGA
# include <X11/extensions/xf86dga.h>
#endif
#ifdef HAS_VIDMODE
# include <X11/extensions/xf86vmode.h>
#endif
#include "dga_check.h"
#ifdef XMESA
# include <GL/xmesa.h>
#endif
#define WARP_WIDTH 320
#define WARP_HEIGHT 200
extern byte *host_colormap;
extern qboolean noclip_anglehack;
static qboolean vid_initialized = false;
static Display *x_disp = NULL;
static Window x_win;
static GLXContext ctx = NULL;
static int screen;
Window x_win;
static GLXContext ctx = NULL;
static float old_windowed_mouse = 0;
#define KEY_MASK (KeyPressMask | KeyReleaseMask)
#define MOUSE_MASK (ButtonPressMask | ButtonReleaseMask | \
PointerMotionMask)
#define X_MASK (KEY_MASK | MOUSE_MASK | VisibilityChangeMask)
#define X_MASK (VisibilityChangeMask | StructureNotifyMask)
unsigned short d_8to16table[256];
unsigned d_8to24table[256];
unsigned d_8to24table[256];
unsigned char d_15to8table[65536];
cvar_t *_windowed_mouse;
cvar_t *vid_mode;
static float mouse_x, mouse_y;
static float old_mouse_x, old_mouse_y;
cvar_t *vid_fullscreen;
extern cvar_t *gl_triplebuffer;
extern cvar_t *vid_dga_mouseaccel;
cvar_t *m_filter;
#ifdef HAS_VIDMODE
static XF86VidModeModeInfo **vidmodes;
static int nummodes, hasvidmode = 0;
#endif
#ifdef HAS_DGA
static int hasdgavideo = 0;
static int hasdga = 0;
#endif
static int scr_width, scr_height;
#ifdef HAVE_DLOPEN
static void *dlhand = NULL;
#endif
static GLboolean (*QF_XMesaSetFXmode)(GLint mode) = NULL;
int scr_width, scr_height;
#if defined(XMESA) || defined(HAS_DGA)
int VID_options_items = 2;
#else
int VID_options_items = 1;
#endif
/*-----------------------------------------------------------------------*/
@ -118,10 +132,8 @@ int texture_mode = GL_LINEAR;
int texture_extension_number = 1;
float gldepthmin, gldepthmax;
float gldepthmin, gldepthmax;
/* cvar_t gl_ztrick = {"gl_ztrick","1"};
CVAR_FIXME */
cvar_t *gl_ztrick;
const char *gl_vendor;
@ -141,318 +153,48 @@ void D_EndDirectRect (int x, int y, int width, int height)
{
}
/*
========================================================================
Create an empty cursor
========================================================================
*/
static Cursor nullcursor = None;
static Cursor
CreateNullCursor(Display *display, Window root)
void
VID_Shutdown(void)
{
Pixmap cursormask;
XGCValues xgc;
GC gc;
XColor dummycolour;
if (nullcursor != None) return nullcursor;
cursormask = XCreatePixmap(display, root, 1, 1, 1/*depth*/);
xgc.function = GXclear;
gc = XCreateGC(display, cursormask, GCFunction, &xgc);
XFillRectangle(display, cursormask, gc, 0, 0, 1, 1);
dummycolour.pixel = 0;
dummycolour.red = 0;
dummycolour.flags = 04;
nullcursor = XCreatePixmapCursor(display, cursormask, cursormask,
&dummycolour,&dummycolour, 0,0);
XFreePixmap(display,cursormask);
XFreeGC(display,gc);
return nullcursor;
}
static int XLateKey(XKeyEvent *ev)
{
int key;
char buf[64];
KeySym keysym;
key = 0;
XLookupString(ev, buf, sizeof buf, &keysym, 0);
switch(keysym)
{
case XK_KP_Page_Up:
case XK_Page_Up: key = K_PGUP; break;
case XK_KP_Page_Down:
case XK_Page_Down: key = K_PGDN; break;
case XK_KP_Home:
case XK_Home: key = K_HOME; break;
case XK_KP_End:
case XK_End: key = K_END; break;
case XK_KP_Left:
case XK_Left: key = K_LEFTARROW; break;
case XK_KP_Right:
case XK_Right: key = K_RIGHTARROW; break;
case XK_KP_Down:
case XK_Down: key = K_DOWNARROW; break;
case XK_KP_Up:
case XK_Up: key = K_UPARROW; break;
case XK_Escape: key = K_ESCAPE; break;
case XK_KP_Enter:
case XK_Return: key = K_ENTER; break;
case XK_Tab: key = K_TAB; break;
case XK_F1: key = K_F1; break;
case XK_F2: key = K_F2; break;
case XK_F3: key = K_F3; break;
case XK_F4: key = K_F4; break;
case XK_F5: key = K_F5; break;
case XK_F6: key = K_F6; break;
case XK_F7: key = K_F7; break;
case XK_F8: key = K_F8; break;
case XK_F9: key = K_F9; break;
case XK_F10: key = K_F10; break;
case XK_F11: key = K_F11; break;
case XK_F12: key = K_F12; break;
case XK_BackSpace: key = K_BACKSPACE; break;
case XK_KP_Delete:
case XK_Delete: key = K_DEL; break;
case XK_Pause: key = K_PAUSE; break;
case XK_Shift_L:
case XK_Shift_R: key = K_SHIFT; break;
case XK_Execute:
case XK_Control_L:
case XK_Control_R: key = K_CTRL; break;
case XK_Alt_L:
case XK_Meta_L:
case XK_Alt_R:
case XK_Meta_R: key = K_ALT; break;
case XK_KP_Begin: key = '5'; break;
case XK_KP_Insert:
case XK_Insert:key = K_INS; break;
case XK_KP_Multiply: key = '*'; break;
case XK_KP_Add: key = '+'; break;
case XK_KP_Subtract: key = '-'; break;
case XK_KP_Divide: key = '/'; break;
#if 0
case 0x021: key = '1';break;/* [!] */
case 0x040: key = '2';break;/* [@] */
case 0x023: key = '3';break;/* [#] */
case 0x024: key = '4';break;/* [$] */
case 0x025: key = '5';break;/* [%] */
case 0x05e: key = '6';break;/* [^] */
case 0x026: key = '7';break;/* [&] */
case 0x02a: key = '8';break;/* [*] */
case 0x028: key = '9';;break;/* [(] */
case 0x029: key = '0';break;/* [)] */
case 0x05f: key = '-';break;/* [_] */
case 0x02b: key = '=';break;/* [+] */
case 0x07c: key = '\'';break;/* [|] */
case 0x07d: key = '[';break;/* [}] */
case 0x07b: key = ']';break;/* [{] */
case 0x022: key = '\'';break;/* ["] */
case 0x03a: key = ';';break;/* [:] */
case 0x03f: key = '/';break;/* [?] */
case 0x03e: key = '.';break;/* [>] */
case 0x03c: key = ',';break;/* [<] */
#endif
default:
key = *(unsigned char*)buf;
if (key >= 'A' && key <= 'Z')
key = key - 'A' + 'a';
break;
}
return key;
}
static void install_grabs(void)
{
XGrabPointer(x_disp, x_win,
True,
0,
GrabModeAsync, GrabModeAsync,
x_win,
None,
CurrentTime);
#ifdef USE_DGA
XF86DGADirectVideo(x_disp, DefaultScreen(x_disp), XF86DGADirectMouse);
dgamouse = 1;
#else
XWarpPointer(x_disp, None, x_win,
0, 0, 0, 0,
vid.width / 2, vid.height / 2);
#endif
XGrabKeyboard(x_disp, x_win,
False,
GrabModeAsync, GrabModeAsync,
CurrentTime);
// XSync(x_disp, True);
}
static void uninstall_grabs(void)
{
#ifdef USE_DGA
XF86DGADirectVideo(x_disp, DefaultScreen(x_disp), 0);
dgamouse = 0;
#endif
XUngrabPointer(x_disp, CurrentTime);
XUngrabKeyboard(x_disp, CurrentTime);
// XSync(x_disp, True);
}
static void GetEvent(void)
{
XEvent event;
int b;
if (!x_disp)
if (!vid_initialized)
return;
XNextEvent(x_disp, &event);
switch (event.type) {
case KeyPress:
case KeyRelease:
Key_Event(XLateKey(&event.xkey), event.type == KeyPress);
break;
case MotionNotify:
#ifdef USE_DGA
/* if (dgamouse && _windowed_mouse.value) {
CVAR_FIXME */
if (dgamouse && _windowed_mouse->value) {
mouse_x = event.xmotion.x_root;
mouse_y = event.xmotion.y_root;
} else
#endif
{
/* if (_windowed_mouse.value) {
CVAR_FIXME */
if (_windowed_mouse->value) {
mouse_x = (float) ((int)event.xmotion.x - (int)(vid.width/2));
mouse_y = (float) ((int)event.xmotion.y - (int)(vid.height/2));
/* move the mouse to the window center again */
XSelectInput(x_disp, x_win, X_MASK & ~PointerMotionMask);
XWarpPointer(x_disp, None, x_win, 0, 0, 0, 0,
(vid.width/2), (vid.height/2));
XSelectInput(x_disp, x_win, X_MASK);
}
}
break;
case ButtonPress:
b=-1;
if (event.xbutton.button == 1)
b = 0;
else if (event.xbutton.button == 2)
b = 2;
else if (event.xbutton.button == 3)
b = 1;
if (b>=0)
Key_Event(K_MOUSE1 + b, true);
break;
case ButtonRelease:
b=-1;
if (event.xbutton.button == 1)
b = 0;
else if (event.xbutton.button == 2)
b = 2;
else if (event.xbutton.button == 3)
b = 1;
if (b>=0)
Key_Event(K_MOUSE1 + b, false);
break;
}
/* if (old_windowed_mouse != _windowed_mouse.value) {
CVAR_FIXME */
if (old_windowed_mouse != _windowed_mouse->value) {
/* old_windowed_mouse = _windowed_mouse.value;
CVAR_FIXME */
old_windowed_mouse = _windowed_mouse->value;
/* if (!_windowed_mouse.value) {
CVAR_FIXME */
if (!_windowed_mouse->value) {
/* ungrab the pointer */
uninstall_grabs();
} else {
/* grab the pointer */
install_grabs();
}
}
}
void VID_Shutdown(void)
{
Con_Printf("VID_Shutdown\n");
if (ctx) {
glXDestroyContext(x_disp, ctx);
glXDestroyContext(x_disp, ctx);
#ifdef HAS_VIDMODE
if (hasvidmode) {
int i;
XF86VidModeSwitchToMode (x_disp, DefaultScreen (x_disp),
vidmodes[0]);
for (i = 0; i < nummodes; i++) {
if (vidmodes[i]->private) XFree(vidmodes[i]->private);
}
XFree(vidmodes);
}
if (nullcursor != None) {
XFreeCursor(x_disp, nullcursor);
nullcursor = None;
#endif
#ifdef HAVE_DLOPEN
if (dlhand) {
dlclose(dlhand);
dlhand = NULL;
}
XCloseDisplay(x_disp);
#endif
x11_close_display();
}
void signal_handler(int sig)
static void
signal_handler(int sig)
{
printf("Received signal %d, exiting...\n", sig);
Sys_Quit();
exit(0);
exit(sig);
}
void InitSig(void)
static void
InitSig(void)
{
#if 0
signal(SIGHUP, signal_handler);
signal(SIGINT, signal_handler);
signal(SIGQUIT, signal_handler);
@ -460,10 +202,9 @@ void InitSig(void)
signal(SIGTRAP, signal_handler);
signal(SIGIOT, signal_handler);
signal(SIGBUS, signal_handler);
signal(SIGFPE, signal_handler);
/* signal(SIGFPE, signal_handler); */
signal(SIGSEGV, signal_handler);
signal(SIGTERM, signal_handler);
#endif
}
void VID_ShiftPalette(unsigned char *p)
@ -488,7 +229,7 @@ void VID_SetPalette (unsigned char *palette)
//
// 8 8 8 encoding
//
// Con_DPrintf("Converting 8to24\n");
// Con_Printf("Converting 8to24\n");
pal = palette;
table = d_8to24table;
@ -498,7 +239,7 @@ void VID_SetPalette (unsigned char *palette)
g = pal[1];
b = pal[2];
pal += 3;
// v = (255<<24) + (r<<16) + (g<<8) + (b<<0);
// v = (255<<0) + (r<<8) + (g<<16) + (b<<24);
v = (255<<24) + (r<<0) + (g<<8) + (b<<16);
@ -540,9 +281,9 @@ void VID_SetPalette (unsigned char *palette)
}
d_15to8table[i]=k;
}
snprintf (s, sizeof(s), "%s/glquake", com_gamedir);
snprintf(s, sizeof(s), "%s/glquake", com_gamedir);
Sys_mkdir (s);
snprintf (s, sizeof(s), "%s/glquake/15to8.pal", com_gamedir);
snprintf(s, sizeof(s), "%s/glquake/15to8.pal", com_gamedir);
if ((f = Qopen(s, "wb")) != NULL) {
Qwrite(f, d_15to8table, 1<<15);
Qclose(f);
@ -550,6 +291,7 @@ void VID_SetPalette (unsigned char *palette)
}
}
/*
===============
GL_Init
@ -569,7 +311,7 @@ void GL_Init (void)
// Con_Printf ("%s %s\n", gl_renderer, gl_version);
glClearColor (1,0,0,0);
glClearColor (0,0,0,0);
glCullFace(GL_FRONT);
glEnable(GL_TEXTURE_2D);
@ -625,8 +367,8 @@ qboolean VID_Is8bit(void)
return is8bit;
}
#ifdef GLX_EXT_SHARED
void VID_Init8bitPalette()
#ifdef GL_EXT_SHARED
void VID_Init8bitPalette()
{
// Check for 8bit Extensions and initialize them.
int i;
@ -656,34 +398,6 @@ void VID_Init8bitPalette(void)
{
}
#if 0
extern void gl3DfxSetPaletteEXT(GLuint *pal);
void VID_Init8bitPalette(void)
{
// Check for 8bit Extensions and initialize them.
int i;
GLubyte table[256][4];
char *oldpal;
if (strstr(gl_extensions, "3DFX_set_global_palette") == NULL)
return;
Con_SafePrintf("8-bit GL extensions enabled.\n");
glEnable( GL_SHARED_TEXTURE_PALETTE_EXT );
oldpal = (char *) d_8to24table; //d_8to24table3dfx;
for (i=0;i<256;i++) {
table[i][2] = *oldpal++;
table[i][1] = *oldpal++;
table[i][0] = *oldpal++;
table[i][3] = 255;
oldpal++;
}
gl3DfxSetPaletteEXT((GLuint *)table);
is8bit = true;
}
#endif
#endif
void VID_Init(unsigned char *palette)
@ -700,25 +414,27 @@ void VID_Init(unsigned char *palette)
};
char gldir[MAX_OSPATH];
int width = 640, height = 480;
int scrnum;
XSetWindowAttributes attr;
unsigned long mask;
Window root;
XVisualInfo *visinfo;
vid_mode = Cvar_Get("vid_mode", "0", CVAR_NONE, "None");
gl_ztrick = Cvar_Get("gl_ztrick", "0", CVAR_NONE, "None");
_windowed_mouse = Cvar_Get("_windowed_mouse", "0", CVAR_ARCHIVE, "None");
vid_mode = Cvar_Get ("vid_mode","0",0,"None");
gl_ztrick = Cvar_Get ("gl_ztrick","0",CVAR_ARCHIVE,"None");
vid_fullscreen = Cvar_Get ("vid_fullscreen","0",0,"None");
#ifdef HAS_DGA
vid_dga_mouseaccel = Cvar_Get("vid_dga_mouseaccel","1",CVAR_ARCHIVE,
"None");
#endif
vid.maxwarpwidth = WARP_WIDTH;
vid.maxwarpheight = WARP_HEIGHT;
vid.colormap = host_colormap;
vid.fullbright = 256 - LittleLong (*((int *)vid.colormap + 2048));
// interpret command-line params
/* Interpret command-line params
*/
// set vid parameters
/* Set vid parameters */
if ((i = COM_CheckParm("-width")) != 0)
width = atoi(com_argv[i+1]);
if ((i = COM_CheckParm("-height")) != 0)
@ -730,28 +446,82 @@ void VID_Init(unsigned char *palette)
vid.conwidth = width;
vid.conwidth &= 0xfff8; // make it a multiple of eight
vid.conwidth = max(vid.conwidth, 320);
if (vid.conwidth < 320)
vid.conwidth = 320;
// pick a conheight that matches with correct aspect
vid.conheight = vid.conwidth*3 / 4;
vid.conheight = vid.conwidth * 3 / 4;
if ((i = COM_CheckParm("-conheight")) != 0)
vid.conheight = max(atoi(com_argv[i+1]), 200);
i = COM_CheckParm ("-conheight");
if ( i != 0 ) // Set console height, but no smaller than 200 px
vid.conheight = atoi(com_argv[i+1]);
if (vid.conheight < 200)
vid.conheight = 200;
if (!(x_disp = XOpenDisplay(NULL))) {
fprintf(stderr, "Error couldn't open the X display\n");
exit(1);
}
x11_open_display();
scrnum = DefaultScreen(x_disp);
root = RootWindow(x_disp, scrnum);
screen = DefaultScreen(x_disp);
root = RootWindow(x_disp, screen);
visinfo = glXChooseVisual(x_disp, scrnum, attrib);
visinfo = glXChooseVisual(x_disp, screen, attrib);
if (!visinfo) {
fprintf(stderr, "qkHack: Error couldn't get an RGB, Double-buffered, Depth visual\n");
fprintf(stderr, "Error couldn't get an RGB, Double-buffered, Depth visual\n");
exit(1);
}
#ifdef HAS_DGA
{
int maj_ver;
hasdga = VID_CheckDGA(x_disp, &maj_ver, NULL, &hasdgavideo);
if (!hasdga || maj_ver < 1) {
hasdga = hasdgavideo = 0;
}
}
Con_SafePrintf ("hasdga = %i\nhasdgavideo = %i\n", hasdga, hasdgavideo);
#endif
#ifdef HAS_VIDMODE
hasvidmode = VID_CheckVMode(x_disp, NULL, NULL);
if (hasvidmode) {
if (! XF86VidModeGetAllModeLines(x_disp, DefaultScreen(x_disp),
&nummodes, &vidmodes)
|| nummodes <= 0) {
hasvidmode = 0;
}
}
Con_SafePrintf ("hasvidmode = %i\nnummodes = %i\n", hasvidmode, nummodes);
#endif
#ifdef HAVE_DLOPEN
dlhand = dlopen(NULL, RTLD_LAZY);
if (dlhand) {
QF_XMesaSetFXmode = dlsym(dlhand, "XMesaSetFXmode");
if (!QF_XMesaSetFXmode) {
QF_XMesaSetFXmode = dlsym(dlhand, "_XMesaSetFXmode");
}
} else {
QF_XMesaSetFXmode = NULL;
}
#else
#ifdef XMESA
QF_XMesaSetFXmode = XMesaSetFXmode;
#endif
#endif
if (QF_XMesaSetFXmode) {
#ifdef XMESA
const char *str = getenv("MESA_GLX_FX");
if (str != NULL && *str != 'd') {
if (tolower(*str) == 'w') {
Cvar_Set (vid_fullscreen, "0");
} else {
Cvar_Set (vid_fullscreen, "1");
}
}
#endif
/* Glide uses DGA internally, so we don't want to
mess with it. */
// hasdga = 0;
}
/* window attributes */
attr.background_pixel = 0;
attr.border_pixel = 0;
@ -759,18 +529,52 @@ void VID_Init(unsigned char *palette)
attr.event_mask = X_MASK;
mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
#ifdef HAS_VIDMODE
if (hasvidmode && vid_fullscreen->value) {
int smallest_mode=0, x=MAXINT, y=MAXINT;
attr.override_redirect=1;
mask|=CWOverrideRedirect;
// FIXME: does this depend on mode line order in XF86Config?
for (i=0; i<nummodes; i++) {
if (x>vidmodes[i]->hdisplay || y>vidmodes[i]->vdisplay) {
smallest_mode=i;
x=vidmodes[i]->hdisplay;
y=vidmodes[i]->vdisplay;
}
printf("%dx%d\n",vidmodes[i]->hdisplay,vidmodes[i]->vdisplay);
}
// chose the smallest mode that our window fits into;
for (i=smallest_mode;
i!=(smallest_mode+1)%nummodes;
i=(i?i-1:nummodes-1)) {
if (vidmodes[i]->hdisplay>=width
&& vidmodes[i]->vdisplay>=height) {
XF86VidModeSwitchToMode (x_disp, DefaultScreen (x_disp),
vidmodes[i]);
break;
}
}
XF86VidModeSetViewPort(x_disp, DefaultScreen (x_disp), 0, 0);
_windowed_mouse = Cvar_Get ("_windowed_mouse","1",CVAR_ARCHIVE|CVAR_ROM,"None");
} else
#endif
_windowed_mouse = Cvar_Get ("_windowed_mouse","0",CVAR_ARCHIVE,"None");
x_win = XCreateWindow(x_disp, root, 0, 0, width, height,
0, visinfo->depth, InputOutput,
visinfo->visual, mask, &attr);
/* Invisible Cursor */
XDefineCursor(x_disp, x_win, CreateNullCursor(x_disp, x_win));
/* Map the window */
XMapWindow(x_disp, x_win);
#ifdef HAS_VIDMODE
if (hasvidmode && vid_fullscreen->value) {
XRaiseWindow(x_disp, x_win);
XGrabKeyboard(x_disp, x_win, 1, GrabModeAsync, GrabModeAsync,
CurrentTime);
}
#endif
XMoveWindow(x_disp, x_win, 0, 0);
XFlush(x_disp);
XSync(x_disp, 0);
ctx = glXCreateContext(x_disp, visinfo, NULL, True);
@ -779,8 +583,12 @@ void VID_Init(unsigned char *palette)
scr_width = width;
scr_height = height;
vid.height = vid.conheight = min(height, vid.conheight);
vid.width = vid.conwidth = min(width, vid.conwidth);
if (vid.conheight > height)
vid.conheight = height;
if (vid.conwidth > width)
vid.conwidth = width;
vid.width = vid.conwidth;
vid.height = vid.conheight;
vid.aspect = ((float)vid.height / (float)vid.width) * (320.0 / 240.0);
vid.numpages = 2;
@ -789,7 +597,7 @@ void VID_Init(unsigned char *palette)
GL_Init();
snprintf (gldir, sizeof(gldir), "%s/glquake", com_gamedir);
snprintf(gldir, sizeof(gldir), "%s/glquake", com_gamedir);
Sys_mkdir (gldir);
VID_SetPalette(palette);
@ -797,96 +605,26 @@ void VID_Init(unsigned char *palette)
// Check for 3DFX Extensions and initialize them.
VID_Init8bitPalette();
Con_SafePrintf ("Video mode %dx%d initialized.\n", width, height);
Con_SafePrintf ("Video mode %dx%d initialized.\n",
width, height);
vid.recalc_refdef = 1; // force a surface cache flush
vid_initialized = true;
vid.recalc_refdef = 1; // force a surface cache flush
}
void Sys_SendKeyEvents(void)
void VID_InitCvars()
{
if (x_disp) {
while (XPending(x_disp))
GetEvent();
}
gl_triplebuffer = Cvar_Get("gl_triplebuffer","1",CVAR_ARCHIVE,"None");
}
void Force_CenterView_f (void)
{
cl.viewangles[PITCH] = 0;
}
void IN_Init(void)
void
VID_LockBuffer ( void )
{
}
void IN_Shutdown(void)
void
VID_UnlockBuffer ( void )
{
}
/*
===========
IN_Commands
===========
*/
void IN_Commands (void)
{
}
/*
===========
IN_Move
===========
*/
void IN_MouseMove (usercmd_t *cmd)
{
if (m_filter->value)
{
mouse_x = (mouse_x + old_mouse_x) * 0.5;
mouse_y = (mouse_y + old_mouse_y) * 0.5;
}
old_mouse_x = mouse_x;
old_mouse_y = mouse_y;
mouse_x *= sensitivity->value;
mouse_y *= sensitivity->value;
// add mouse X/Y movement to cmd
if ( (in_strafe.state & 1) || (lookstrafe->value && freelook ))
cmd->sidemove += m_side->value * mouse_x;
else
cl.viewangles[YAW] -= m_yaw->value * mouse_x;
if (freelook)
V_StopPitchDrift ();
if ( freelook && !(in_strafe.state & 1))
{
cl.viewangles[PITCH] += m_pitch->value * mouse_y;
if (cl.viewangles[PITCH] > 80)
cl.viewangles[PITCH] = 80;
if (cl.viewangles[PITCH] < -70)
cl.viewangles[PITCH] = -70;
}
else
{
if ((in_strafe.state & 1) && noclip_anglehack)
cmd->upmove -= m_forward->value * mouse_y;
else
cmd->forwardmove -= m_forward->value * mouse_y;
}
mouse_x = mouse_y = 0.0;
}
void IN_Move (usercmd_t *cmd)
{
IN_MouseMove(cmd);
}
void VID_InitCvars ()
{
m_filter = Cvar_Get("m_filter", "0", CVAR_NONE, "None");
}
void VID_UnlockBuffer() {}
void VID_LockBuffer() {}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff