~ubuntu-branches/ubuntu/precise/openarena/precise

« back to all changes in this revision

Viewing changes to code/win32/win_wndproc.c

  • Committer: Bazaar Package Importer
  • Author(s): Bruno "Fuddl" Kleinert
  • Date: 2007-01-20 12:28:09 UTC
  • Revision ID: james.westby@ubuntu.com-20070120122809-2yza5ojt7nqiyiam
Tags: upstream-0.6.0
ImportĀ upstreamĀ versionĀ 0.6.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
===========================================================================
 
3
Copyright (C) 1999-2005 Id Software, Inc.
 
4
 
 
5
This file is part of Quake III Arena source code.
 
6
 
 
7
Quake III Arena source code is free software; you can redistribute it
 
8
and/or modify it under the terms of the GNU General Public License as
 
9
published by the Free Software Foundation; either version 2 of the License,
 
10
or (at your option) any later version.
 
11
 
 
12
Quake III Arena source code is distributed in the hope that it will be
 
13
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
GNU General Public License for more details.
 
16
 
 
17
You should have received a copy of the GNU General Public License
 
18
along with Quake III Arena source code; if not, write to the Free Software
 
19
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
20
===========================================================================
 
21
*/
 
22
 
 
23
#include "../client/client.h"
 
24
#include "win_local.h"
 
25
 
 
26
WinVars_t       g_wv;
 
27
 
 
28
#ifndef WM_MOUSEWHEEL
 
29
#define WM_MOUSEWHEEL (WM_MOUSELAST+1)  // message that will be supported by the OS 
 
30
#endif
 
31
 
 
32
static UINT MSH_MOUSEWHEEL;
 
33
 
 
34
// Console variables that we need to access from this module
 
35
cvar_t          *vid_xpos;                      // X coordinate of window position
 
36
cvar_t          *vid_ypos;                      // Y coordinate of window position
 
37
cvar_t          *r_fullscreen;
 
38
 
 
39
#define VID_NUM_MODES ( sizeof( vid_modes ) / sizeof( vid_modes[0] ) )
 
40
 
 
41
LONG WINAPI MainWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
 
42
 
 
43
static qboolean s_alttab_disabled;
 
44
 
 
45
static void WIN_DisableAltTab( void )
 
46
{
 
47
        if ( s_alttab_disabled )
 
48
                return;
 
49
 
 
50
        if ( !Q_stricmp( Cvar_VariableString( "arch" ), "winnt" ) )
 
51
        {
 
52
                RegisterHotKey( 0, 0, MOD_ALT, VK_TAB );
 
53
        }
 
54
        else
 
55
        {
 
56
                BOOL old;
 
57
 
 
58
                SystemParametersInfo( SPI_SCREENSAVERRUNNING, 1, &old, 0 );
 
59
        }
 
60
        s_alttab_disabled = qtrue;
 
61
}
 
62
 
 
63
static void WIN_EnableAltTab( void )
 
64
{
 
65
        if ( s_alttab_disabled )
 
66
        {
 
67
                if ( !Q_stricmp( Cvar_VariableString( "arch" ), "winnt" ) )
 
68
                {
 
69
                        UnregisterHotKey( 0, 0 );
 
70
                }
 
71
                else
 
72
                {
 
73
                        BOOL old;
 
74
 
 
75
                        SystemParametersInfo( SPI_SCREENSAVERRUNNING, 0, &old, 0 );
 
76
                }
 
77
 
 
78
                s_alttab_disabled = qfalse;
 
79
        }
 
80
}
 
81
 
 
82
/*
 
83
==================
 
84
VID_AppActivate
 
85
==================
 
86
*/
 
87
static void VID_AppActivate(BOOL fActive, BOOL minimize)
 
88
{
 
89
        g_wv.isMinimized = minimize;
 
90
 
 
91
        Com_DPrintf("VID_AppActivate: %i\n", fActive );
 
92
 
 
93
        Key_ClearStates();      // FIXME!!!
 
94
 
 
95
        // we don't want to act like we're active if we're minimized
 
96
        if (fActive && !g_wv.isMinimized )
 
97
        {
 
98
                g_wv.activeApp = qtrue;
 
99
        }
 
100
        else
 
101
        {
 
102
                g_wv.activeApp = qfalse;
 
103
        }
 
104
 
 
105
        // minimize/restore mouse-capture on demand
 
106
        if (!g_wv.activeApp )
 
107
        {
 
108
                IN_Activate (qfalse);
 
109
        }
 
110
        else
 
111
        {
 
112
                IN_Activate (qtrue);
 
113
        }
 
114
}
 
115
 
 
116
//==========================================================================
 
117
 
 
118
static byte s_scantokey[128] = 
 
119
                                        { 
 
120
//  0           1       2       3       4       5       6       7 
 
121
//  8           9       A       B       C       D       E       F 
 
122
        0  ,    27,     '1',    '2',    '3',    '4',    '5',    '6', 
 
123
        '7',    '8',    '9',    '0',    '-',    '=',    K_BACKSPACE, 9, // 0 
 
124
        'q',    'w',    'e',    'r',    't',    'y',    'u',    'i', 
 
125
        'o',    'p',    '[',    ']',    13 ,    K_CTRL,'a',  's',      // 1 
 
126
        'd',    'f',    'g',    'h',    'j',    'k',    'l',    ';', 
 
127
        '\'' ,    '`',    K_SHIFT,'\\',  'z',    'x',    'c',    'v',      // 2 
 
128
        'b',    'n',    'm',    ',',    '.',    '/',    K_SHIFT,'*', 
 
129
        K_ALT,' ',   K_CAPSLOCK  ,    K_F1, K_F2, K_F3, K_F4, K_F5,   // 3 
 
130
        K_F6, K_F7, K_F8, K_F9, K_F10,  K_PAUSE,    0  , K_HOME, 
 
131
        K_UPARROW,K_PGUP,K_KP_MINUS,K_LEFTARROW,K_KP_5,K_RIGHTARROW, K_KP_PLUS,K_END, //4 
 
132
        K_DOWNARROW,K_PGDN,K_INS,K_DEL,0,0,             0,              K_F11, 
 
133
        K_F12,0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0,        // 5
 
134
        0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0, 
 
135
        0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0,        // 6 
 
136
        0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0, 
 
137
        0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0         // 7 
 
138
}; 
 
139
 
 
140
/*
 
141
=======
 
142
MapKey
 
143
 
 
144
Map from windows to quake keynums
 
145
=======
 
146
*/
 
147
static int MapKey (int key)
 
148
{
 
149
        int result;
 
150
        int modified;
 
151
        qboolean is_extended;
 
152
 
 
153
//      Com_Printf( "0x%x\n", key);
 
154
 
 
155
        modified = ( key >> 16 ) & 255;
 
156
 
 
157
        if ( modified > 127 )
 
158
                return 0;
 
159
 
 
160
        if ( key & ( 1 << 24 ) )
 
161
        {
 
162
                is_extended = qtrue;
 
163
        }
 
164
        else
 
165
        {
 
166
                is_extended = qfalse;
 
167
        }
 
168
 
 
169
        result = s_scantokey[modified];
 
170
 
 
171
        if ( !is_extended )
 
172
        {
 
173
                switch ( result )
 
174
                {
 
175
                case K_HOME:
 
176
                        return K_KP_HOME;
 
177
                case K_UPARROW:
 
178
                        return K_KP_UPARROW;
 
179
                case K_PGUP:
 
180
                        return K_KP_PGUP;
 
181
                case K_LEFTARROW:
 
182
                        return K_KP_LEFTARROW;
 
183
                case K_RIGHTARROW:
 
184
                        return K_KP_RIGHTARROW;
 
185
                case K_END:
 
186
                        return K_KP_END;
 
187
                case K_DOWNARROW:
 
188
                        return K_KP_DOWNARROW;
 
189
                case K_PGDN:
 
190
                        return K_KP_PGDN;
 
191
                case K_INS:
 
192
                        return K_KP_INS;
 
193
                case K_DEL:
 
194
                        return K_KP_DEL;
 
195
                default:
 
196
                        return result;
 
197
                }
 
198
        }
 
199
        else
 
200
        {
 
201
                switch ( result )
 
202
                {
 
203
                case K_PAUSE:
 
204
                        return K_KP_NUMLOCK;
 
205
                case 0x0D:
 
206
                        return K_KP_ENTER;
 
207
                case 0x2F:
 
208
                        return K_KP_SLASH;
 
209
                case 0xAF:
 
210
                        return K_KP_PLUS;
 
211
                }
 
212
                return result;
 
213
        }
 
214
}
 
215
 
 
216
 
 
217
/*
 
218
====================
 
219
MainWndProc
 
220
 
 
221
main window procedure
 
222
====================
 
223
*/
 
224
extern cvar_t *in_mouse;
 
225
extern cvar_t *in_logitechbug;
 
226
LONG WINAPI MainWndProc (
 
227
    HWND    hWnd,
 
228
    UINT    uMsg,
 
229
    WPARAM  wParam,
 
230
    LPARAM  lParam)
 
231
{
 
232
        static qboolean flip = qtrue;
 
233
        int zDelta, i;
 
234
 
 
235
        // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/userinput/mouseinput/aboutmouseinput.asp
 
236
        // Windows 95, Windows NT 3.51 - uses MSH_MOUSEWHEEL
 
237
        // only relevant for non-DI input
 
238
        //
 
239
        // NOTE: not sure how reliable this is anymore, might trigger double wheel events
 
240
        if (in_mouse->integer != 1)
 
241
        {
 
242
                if ( uMsg == MSH_MOUSEWHEEL )
 
243
                {
 
244
                        if ( ( ( int ) wParam ) > 0 )
 
245
                        {
 
246
                                Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, K_MWHEELUP, qtrue, 0, NULL );
 
247
                                Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, K_MWHEELUP, qfalse, 0, NULL );
 
248
                        }
 
249
                        else
 
250
                        {
 
251
                                Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, K_MWHEELDOWN, qtrue, 0, NULL );
 
252
                                Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, K_MWHEELDOWN, qfalse, 0, NULL );
 
253
                        }
 
254
                        return DefWindowProc (hWnd, uMsg, wParam, lParam);
 
255
                }
 
256
        }
 
257
 
 
258
        switch (uMsg)
 
259
        {
 
260
        case WM_MOUSEWHEEL:
 
261
                // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/userinput/mouseinput/aboutmouseinput.asp
 
262
                // Windows 98/Me, Windows NT 4.0 and later - uses WM_MOUSEWHEEL
 
263
                // only relevant for non-DI input and when console is toggled in window mode
 
264
                //   if console is toggled in window mode (KEYCATCH_CONSOLE) then mouse is released and DI doesn't see any mouse wheel
 
265
                if (in_mouse->integer != 1 || (!r_fullscreen->integer && (cls.keyCatchers & KEYCATCH_CONSOLE)))
 
266
                {
 
267
                        // 120 increments, might be 240 and multiples if wheel goes too fast
 
268
                        // NOTE Logitech: logitech drivers are screwed and send the message twice?
 
269
                        //   could add a cvar to interpret the message as successive press/release events
 
270
                        zDelta = ( short ) HIWORD( wParam ) / 120;
 
271
                        if ( zDelta > 0 )
 
272
                        {
 
273
                                for(i=0; i<zDelta; i++)
 
274
                                {
 
275
                                        if (!in_logitechbug->integer)
 
276
                                        {
 
277
                                                Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, K_MWHEELUP, qtrue, 0, NULL );
 
278
                                                Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, K_MWHEELUP, qfalse, 0, NULL );
 
279
                                        }
 
280
                                        else
 
281
                                        {
 
282
                                                Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, K_MWHEELUP, flip, 0, NULL );
 
283
                                                flip = !flip;
 
284
                                        }
 
285
                                }
 
286
                        }
 
287
                        else
 
288
                        {
 
289
                                for(i=0; i<-zDelta; i++)
 
290
                                {
 
291
                                        if (!in_logitechbug->integer)
 
292
                                        {
 
293
                                                Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, K_MWHEELDOWN, qtrue, 0, NULL );
 
294
                                                Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, K_MWHEELDOWN, qfalse, 0, NULL );
 
295
                                        }
 
296
                                        else
 
297
                                        {
 
298
                                                Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, K_MWHEELDOWN, flip, 0, NULL );
 
299
                                                flip = !flip;
 
300
                                        }
 
301
                                }
 
302
                        }
 
303
                        // when an application processes the WM_MOUSEWHEEL message, it must return zero
 
304
                        return 0;
 
305
                }
 
306
                break;
 
307
 
 
308
        case WM_CREATE:
 
309
 
 
310
                g_wv.hWnd = hWnd;
 
311
 
 
312
                vid_xpos = Cvar_Get ("vid_xpos", "3", CVAR_ARCHIVE);
 
313
                vid_ypos = Cvar_Get ("vid_ypos", "22", CVAR_ARCHIVE);
 
314
                r_fullscreen = Cvar_Get ("r_fullscreen", "1", CVAR_ARCHIVE | CVAR_LATCH );
 
315
 
 
316
                MSH_MOUSEWHEEL = RegisterWindowMessage("MSWHEEL_ROLLMSG"); 
 
317
                if ( r_fullscreen->integer )
 
318
                {
 
319
                        WIN_DisableAltTab();
 
320
                }
 
321
                else
 
322
                {
 
323
                        WIN_EnableAltTab();
 
324
                }
 
325
 
 
326
                break;
 
327
#if 0
 
328
        case WM_DISPLAYCHANGE:
 
329
                Com_DPrintf( "WM_DISPLAYCHANGE\n" );
 
330
                // we need to force a vid_restart if the user has changed
 
331
                // their desktop resolution while the game is running,
 
332
                // but don't do anything if the message is a result of
 
333
                // our own calling of ChangeDisplaySettings
 
334
                if ( com_insideVidInit ) {
 
335
                        break;          // we did this on purpose
 
336
                }
 
337
                // something else forced a mode change, so restart all our gl stuff
 
338
                Cbuf_AddText( "vid_restart\n" );
 
339
                break;
 
340
#endif
 
341
        case WM_DESTROY:
 
342
                // let sound and input know about this?
 
343
                g_wv.hWnd = NULL;
 
344
                if ( r_fullscreen->integer )
 
345
                {
 
346
                        WIN_EnableAltTab();
 
347
                }
 
348
                break;
 
349
 
 
350
        case WM_CLOSE:
 
351
                Cbuf_ExecuteText( EXEC_APPEND, "quit" );
 
352
                break;
 
353
 
 
354
        case WM_ACTIVATE:
 
355
                {
 
356
                        int     fActive, fMinimized;
 
357
 
 
358
                        fActive = LOWORD(wParam);
 
359
                        fMinimized = (BOOL) HIWORD(wParam);
 
360
 
 
361
                        VID_AppActivate( fActive != WA_INACTIVE, fMinimized);
 
362
                        SNDDMA_Activate();
 
363
                }
 
364
                break;
 
365
 
 
366
        case WM_MOVE:
 
367
                {
 
368
                        int             xPos, yPos;
 
369
                        RECT r;
 
370
                        int             style;
 
371
 
 
372
                        if (!r_fullscreen->integer )
 
373
                        {
 
374
                                xPos = (short) LOWORD(lParam);    // horizontal position 
 
375
                                yPos = (short) HIWORD(lParam);    // vertical position 
 
376
 
 
377
                                r.left   = 0;
 
378
                                r.top    = 0;
 
379
                                r.right  = 1;
 
380
                                r.bottom = 1;
 
381
 
 
382
                                style = GetWindowLong( hWnd, GWL_STYLE );
 
383
                                AdjustWindowRect( &r, style, FALSE );
 
384
 
 
385
                                Cvar_SetValue( "vid_xpos", xPos + r.left);
 
386
                                Cvar_SetValue( "vid_ypos", yPos + r.top);
 
387
                                vid_xpos->modified = qfalse;
 
388
                                vid_ypos->modified = qfalse;
 
389
                                if ( g_wv.activeApp )
 
390
                                {
 
391
                                        IN_Activate (qtrue);
 
392
                                }
 
393
                        }
 
394
                }
 
395
                break;
 
396
 
 
397
// this is complicated because Win32 seems to pack multiple mouse events into
 
398
// one update sometimes, so we always check all states and look for events
 
399
        case WM_LBUTTONDOWN:
 
400
        case WM_LBUTTONUP:
 
401
        case WM_RBUTTONDOWN:
 
402
        case WM_RBUTTONUP:
 
403
        case WM_MBUTTONDOWN:
 
404
        case WM_MBUTTONUP:
 
405
        case WM_MOUSEMOVE:
 
406
                {
 
407
                        int     temp;
 
408
 
 
409
                        temp = 0;
 
410
 
 
411
                        if (wParam & MK_LBUTTON)
 
412
                                temp |= 1;
 
413
 
 
414
                        if (wParam & MK_RBUTTON)
 
415
                                temp |= 2;
 
416
 
 
417
                        if (wParam & MK_MBUTTON)
 
418
                                temp |= 4;
 
419
 
 
420
                        IN_MouseEvent (temp);
 
421
                }
 
422
                break;
 
423
 
 
424
        case WM_SYSCOMMAND:
 
425
                if ( wParam == SC_SCREENSAVE )
 
426
                        return 0;
 
427
                break;
 
428
 
 
429
        case WM_SYSKEYDOWN:
 
430
                if ( wParam == 13 )
 
431
                {
 
432
                        if ( r_fullscreen )
 
433
                        {
 
434
                                Cvar_SetValue( "r_fullscreen", !r_fullscreen->integer );
 
435
                                Cbuf_AddText( "vid_restart\n" );
 
436
                        }
 
437
                        return 0;
 
438
                }
 
439
                // fall through
 
440
        case WM_KEYDOWN:
 
441
                Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, MapKey( lParam ), qtrue, 0, NULL );
 
442
                break;
 
443
 
 
444
        case WM_SYSKEYUP:
 
445
        case WM_KEYUP:
 
446
                Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, MapKey( lParam ), qfalse, 0, NULL );
 
447
                break;
 
448
 
 
449
        case WM_CHAR:
 
450
                Sys_QueEvent( g_wv.sysMsgTime, SE_CHAR, wParam, 0, 0, NULL );
 
451
                break;
 
452
   }
 
453
 
 
454
    return DefWindowProc( hWnd, uMsg, wParam, lParam );
 
455
}
 
456