Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5131 clevermous 1
/*
2
Copyright (C) 1996-1997 Id Software, Inc.
3
 
4
This program is free software; you can redistribute it and/or
5
modify it under the terms of the GNU General Public License
6
as published by the Free Software Foundation; either version 2
7
of the License, or (at your option) any later version.
8
 
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
 
13
See the GNU General Public License for more details.
14
 
15
You should have received a copy of the GNU General Public License
16
along with this program; if not, write to the Free Software
17
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
 
19
*/
20
// in_sun.c -- SUN/X mouse input handler
21
 
22
#include 
23
#include 
24
#include 
25
#include 
26
#include 
27
#include 
28
#include 
29
#include 
30
#include 
31
#include 
32
#include 
33
#include 
34
#include 
35
 
36
#include "quakedef.h"
37
 
38
 
39
//
40
// typedefs and defines
41
//
42
 
43
#define MOUSE_SCALE		4
44
 
45
//
46
// externs
47
//
48
 
49
extern Display			*x_disp;
50
extern int				x_screen, x_screen_width, x_screen_height;
51
extern int			x_center_height, x_center_width;
52
extern int				x_std_event_mask;
53
extern Window			x_win, x_root_win;
54
extern qboolean			x_fullscreen;
55
extern qboolean			x_focus;
56
extern int			global_dx, global_dy;
57
//
58
// globals
59
//
60
 
61
cvar_t					_windowed_mouse = {"_windowed_mouse","1", true};
62
int					x_root, y_root;
63
int					x_root_old, y_root_old;
64
//
65
// locals
66
//
67
 
68
static int				x_mouse_num, x_mouse_denom, x_mouse_thresh;
69
 
70
 
71
static qboolean x_grabbed = false;
72
 
73
//
74
// IN_CenterMouse - center the mouse in the screen
75
//
76
 
77
void IN_CenterMouse( void )
78
{
79
	CheckMouseState();
80
 
81
	if (!x_grabbed)
82
		return;
83
 
84
	XSelectInput( x_disp, x_win, x_std_event_mask & ~PointerMotionMask );
85
	XWarpPointer( x_disp, None, x_root_win, 0, 0, 0, 0, x_center_width,
86
		      x_center_height );
87
	XSelectInput( x_disp, x_win, x_std_event_mask );
88
}
89
 
90
//
91
// Check to see if we have grabbed the mouse or not and deal with it
92
// appropriately
93
//
94
static void CheckMouseState(void)
95
{
96
	if (x_focus && _windowed_mouse.value && !x_grabbed) {
97
		x_grabbed = true;
98
		printf("fooling with mouse!\n");
99
		if (XGetPointerControl( x_disp, &x_mouse_num, &x_mouse_denom, &x_mouse_thresh ))
100
			printf( "XGetPointerControl failed!\n" );
101
		//printf( "mouse %d/%d thresh %d\n", x_mouse_num, x_mouse_denom, x_mouse_thresh );
102
 
103
		// make input rawer
104
		XAutoRepeatOff(x_disp);
105
		XGrabKeyboard(x_disp, x_win, True, GrabModeAsync, GrabModeAsync, CurrentTime);
106
		XGrabPointer(x_disp, x_win, True,
107
			     PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
108
			     GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
109
 
110
//		if (XChangePointerControl( x_disp, True, True, 1, MOUSE_SCALE, x_mouse_thresh ))
111
//			printf( "XChangePointerControl failed!\n" );
112
 
113
		IN_CenterMouse();
114
 
115
		// safe initial values
116
		x_root = x_root_old = vid.width >> 1;
117
		y_root = y_root_old = vid.height >> 1;
118
	} else if (x_grabbed && (!_windowed_mouse.value || !x_focus)) {
119
		printf("fooling with mouse!\n");
120
		x_grabbed = false;
121
		// undo mouse warp
122
		if (XChangePointerControl( x_disp, True, True, x_mouse_num, x_mouse_denom, x_mouse_thresh ))
123
			printf( "XChangePointerControl failed!\n" );
124
 
125
		XUngrabPointer( x_disp, CurrentTime );
126
		XUngrabKeyboard( x_disp, CurrentTime );
127
		XAutoRepeatOn( x_disp );
128
	}
129
}
130
 
131
 
132
//
133
// IN_Init - setup mouse input
134
//
135
 
136
void IN_Init (void)
137
{
138
    if (!x_disp) Sys_Error( "X display not open!\n" );
139
 
140
    Cvar_RegisterVariable (&_windowed_mouse);
141
 
142
	// we really really want to clean these up...
143
    atexit( IN_Shutdown );
144
}
145
 
146
//
147
// IN_Shutdown - clean up mouse settings (must be done from signal handler too!)
148
//
149
 
150
void IN_Shutdown (void)
151
{
152
    if (!x_disp) return;
153
 
154
	// undo mouse warp
155
	if (XChangePointerControl( x_disp, True, True, x_mouse_num, x_mouse_denom, x_mouse_thresh ))
156
		printf( "XChangePointerControl failed!\n" );
157
 
158
	XUngrabPointer( x_disp, CurrentTime );
159
	XUngrabKeyboard( x_disp, CurrentTime );
160
	XAutoRepeatOn( x_disp );
161
}
162
 
163
//
164
// IN_Commands - process buttons
165
//
166
 
167
void IN_Commands (void)
168
{
169
	// done in X event handler
170
}
171
 
172
//
173
// IN_Move - process mouse moves
174
//
175
 
176
void
177
IN_Move (usercmd_t *cmd)
178
{
179
	static int last_dx, last_dy;
180
	static long long last_movement;
181
	long long now, gethrtime();
182
 
183
	int dx, dy;
184
 
185
	CheckMouseState();
186
 
187
 
188
	if (!x_grabbed)
189
		return; // no mouse movement
190
 
191
 
192
	now = gethrtime();
193
 
194
	dx = global_dx;
195
	global_dx = 0;
196
 
197
	dy = global_dy;
198
	global_dy = 0;
199
 
200
//	printf("GOT: dx %d dy %d\n", dx, dy);
201
 
202
	dx *= sensitivity.value;
203
	dy *= sensitivity.value;
204
 
205
//
206
//	implement low pass filter to smooth motion a bit
207
//
208
	if (now - last_movement > 100000000) {
209
		dx = .6 * dx;
210
		dy = .6 * dy;
211
	}
212
	last_movement = now;
213
 
214
	dx = .6 * dx + .4 * last_dx;
215
	dy = .6 * dy + .4 * last_dy;
216
 
217
 
218
	last_dx = dx;
219
	last_dy = dy;
220
 
221
	if (!dx && !dy) {
222
		if (in_mlook.state & 1)
223
			V_StopPitchDrift ();
224
		return;
225
	}
226
 
227
	// add mouse X/Y movement to cmd
228
	if ((in_strafe.state & 1) || (lookstrafe.value && (in_mlook.state & 1)))
229
		cmd->sidemove += m_side.value * dx;
230
	else
231
		cl.viewangles[YAW] -= m_yaw.value * dx;
232
 
233
	if (in_mlook.state & 1)
234
		V_StopPitchDrift ();
235
 
236
	if ((in_mlook.state & 1) && !(in_strafe.state & 1)) {
237
		cl.viewangles[PITCH] += m_pitch.value * dy;
238
		if (cl.viewangles[PITCH] > 80) cl.viewangles[PITCH] = 80;
239
		if (cl.viewangles[PITCH] < -70) cl.viewangles[PITCH] = -70;
240
	}
241
	else {
242
		if ((in_strafe.state & 1) && noclip_anglehack) cmd->upmove -= m_forward.value * dy;
243
		else cmd->forwardmove -= m_forward.value * dy;
244
	}
245
}