void VID_Shutdown (void) { if (vid_initialized) { //if (modestate == MS_FULLDIB) // ChangeDisplaySettings (NULL, CDS_FULLSCREEN); PostMessage (HWND_BROADCAST, WM_PALETTECHANGED, (WPARAM)mainwindow, (LPARAM)0); PostMessage (HWND_BROADCAST, WM_SYSCOLORCHANGE, (WPARAM)0, (LPARAM)0); AppActivate(false, false); //DestroyDIBWindow (); //DestroyFullscreenWindow (); //DestroyFullDIBWindow (); if (hwnd_dialog) DestroyWindow (hwnd_dialog); if (mainwindow) DestroyWindow(mainwindow); //vid_testingmode = 0; vid_initialized = 0; } }
void CheckActive (HWND hWnd) // jit - for some reason, we sometimes don't get events for the window becaming active/inactive, so just check the forground window all the time... { HWND foreground = GetForegroundWindow(); static qboolean newwindow = true; static qboolean lastactive = false; qboolean active = false; qboolean minimized = false; // foreground should be null when minimized? if (!hWnd) return; if (foreground == hWnd) { active = true; } if (lastactive != active) { AppActivate(active, minimized, newwindow); if (reflib_active) re.AppActivate(active); newwindow = false; lastactive = active; } }
void VID_Shutdown (void) { #ifdef _WIN32 extern void AppActivate(BOOL fActive, BOOL minimize); AppActivate(false, false); #endif #ifdef GLSL SHD_Shutdown(); #endif RE_Shutdown( true ); }
// Searchs and activates a window given its title or class name //##ModelId=474D3026011A bool CSendKeys::AppActivate(LPCTSTR WindowTitle, LPCTSTR WindowClass) { HWND w; w = ::FindWindow(WindowClass, WindowTitle); if (w == NULL) { // Must specify at least a criteria if (WindowTitle == NULL && WindowClass == NULL) return false; // << Code to serialize the windowtitle/windowclass in order to send to EnumWindowProc() size_t l1(0), l2(0); if (WindowTitle) l1 = _tcslen(WindowTitle); if (WindowClass) l2 = _tcslen(WindowClass); LPTSTR titleclass = new TCHAR [l1 + l2 + 5]; memset(titleclass, '\0', l1+l2+5); if (WindowTitle) _tcscpy(titleclass, WindowTitle); titleclass[l1] = 0; if (WindowClass) _tcscpy(titleclass+l1+1, WindowClass); // >> enumwindow_t t; t.hwnd = NULL; t.str = titleclass; ::EnumWindows(enumwindowsProc, (LPARAM) & t); w = t.hwnd; delete [] titleclass; } if (w == NULL) return false; return AppActivate(w); }
/* ==================== MainWndProc main window procedure ==================== */ LONG WINAPI MainWndProc ( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { LONG lRet = 0; if ( uMsg == MSH_MOUSEWHEEL ) { if ( ( ( int ) wParam ) > 0 ) { Key_Event( K_MWHEELUP, true, sys_msg_time ); Key_Event( K_MWHEELUP, false, sys_msg_time ); } else { Key_Event( K_MWHEELDOWN, true, sys_msg_time ); Key_Event( K_MWHEELDOWN, false, sys_msg_time ); } return DefWindowProc (hWnd, uMsg, wParam, lParam); } switch (uMsg) { case WM_MOUSEWHEEL: /* ** this chunk of code theoretically only works under NT4 and Win98 ** since this message doesn't exist under Win95 */ if ( ( short ) HIWORD( wParam ) > 0 ) { Key_Event( K_MWHEELUP, true, sys_msg_time ); Key_Event( K_MWHEELUP, false, sys_msg_time ); } else { Key_Event( K_MWHEELDOWN, true, sys_msg_time ); Key_Event( K_MWHEELDOWN, false, sys_msg_time ); } break; case WM_HOTKEY: return 0; case WM_CREATE: cl_hwnd = hWnd; MSH_MOUSEWHEEL = RegisterWindowMessage("MSWHEEL_ROLLMSG"); return DefWindowProc (hWnd, uMsg, wParam, lParam); case WM_PAINT: SCR_DirtyScreen (); // force entire screen to update next frame return DefWindowProc (hWnd, uMsg, wParam, lParam); case WM_DESTROY: // let sound and input know about this? cl_hwnd = NULL; return DefWindowProc (hWnd, uMsg, wParam, lParam); case WM_ACTIVATE: { int fActive, fMinimized; // KJB: Watch this for problems in fullscreen modes with Alt-tabbing. fActive = LOWORD(wParam); fMinimized = (BOOL) HIWORD(wParam); AppActivate( fActive != WA_INACTIVE, fMinimized); if ( reflib_active ) GLimp_AppActivate( !( fActive == WA_INACTIVE ) ); } return DefWindowProc (hWnd, uMsg, wParam, lParam); case WM_MOVE: { int xPos, yPos; RECT r; int style; if (!vid_fullscreen->value) { xPos = (short) LOWORD(lParam); // horizontal position yPos = (short) HIWORD(lParam); // vertical position r.left = 0; r.top = 0; r.right = 1; r.bottom = 1; style = GetWindowLong( hWnd, GWL_STYLE ); AdjustWindowRect( &r, style, FALSE ); Cvar_SetValue( "vid_xpos", xPos + r.left); Cvar_SetValue( "vid_ypos", yPos + r.top); vid_xpos->modified = false; vid_ypos->modified = false; if (ActiveApp) IN_Activate (true); } } return DefWindowProc (hWnd, uMsg, wParam, lParam); // this is complicated because Win32 seems to pack multiple mouse events into // one update sometimes, so we always check all states and look for events case WM_LBUTTONDOWN: case WM_LBUTTONUP: case WM_RBUTTONDOWN: case WM_RBUTTONUP: case WM_MBUTTONDOWN: case WM_MBUTTONUP: #ifdef ENABLE_MOUSE4_MOUSE5 // mattx86: mouse4_mouse5 case WM_XBUTTONDOWN: case WM_XBUTTONUP: #endif case WM_MOUSEMOVE: { int temp; temp = 0; if (wParam & MK_LBUTTON) temp |= 1; if (wParam & MK_RBUTTON) temp |= 2; if (wParam & MK_MBUTTON) temp |= 4; #ifdef ENABLE_MOUSE4_MOUSE5 // mattx86: mouse4_mouse5 if (wParam & MK_XBUTTON1) temp |= 8; if (wParam & MK_XBUTTON2) temp |= 16; #endif IN_MouseEvent (temp); } break; case WM_SYSCOMMAND: if ( wParam == SC_SCREENSAVE ) return 0; return DefWindowProc (hWnd, uMsg, wParam, lParam); case WM_SYSKEYDOWN: if ( wParam == 13 ) { if ( vid_fullscreen ) { Cvar_SetValue( "vid_fullscreen", !vid_fullscreen->value ); } return 0; } // fall through case WM_KEYDOWN: Key_Event( MapKey( lParam ), true, sys_msg_time); break; case WM_SYSKEYUP: case WM_KEYUP: Key_Event( MapKey( lParam ), false, sys_msg_time); break; case MM_MCINOTIFY: { LONG CDAudio_MessageHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); lRet = CDAudio_MessageHandler (hWnd, uMsg, wParam, lParam); } break; default: // pass all unhandled messages to DefWindowProc return DefWindowProc (hWnd, uMsg, wParam, lParam); } /* return 0 if handled message, 1 if not */ return DefWindowProc( hWnd, uMsg, wParam, lParam ); }
// Sends a key string //##ModelId=474D302600AD bool CSendKeys::SendKeys(LPCTSTR KeysString, bool Wait) { WORD MKey, NumTimes; TCHAR KeyString[300] = {0}; bool retval = false; int keyIdx; LPTSTR pKey = (LPTSTR) KeysString; TCHAR ch; m_bWait = Wait; m_bWinDown = m_bShiftDown = m_bControlDown = m_bAltDown = m_bUsingParens = false; while (ch = *pKey) { switch (ch) { // begin modifier group case _TXCHAR('('): m_bUsingParens = true; break; // end modifier group case _TXCHAR(')'): m_bUsingParens = false; PopUpShiftKeys(); // pop all shift keys when we finish a modifier group close break; // ALT key case _TXCHAR('%'): m_bAltDown = true; SendKeyDown(VK_MENU, 1, false); break; // SHIFT key case _TXCHAR('+'): m_bShiftDown = true; SendKeyDown(VK_SHIFT, 1, false); break; // CTRL key case _TXCHAR('^'): m_bControlDown = true; SendKeyDown(VK_CONTROL, 1, false); break; // WINKEY (Left-WinKey) case '@': m_bWinDown = true; SendKeyDown(VK_LWIN, 1, false); break; // enter case _TXCHAR('~'): SendKeyDown(VK_RETURN, 1, true); PopUpShiftKeys(); break; // begin special keys case _TXCHAR('{'): { LPTSTR p = pKey+1; // skip past the beginning '{' size_t t; // find end of close while (*p && *p != _TXCHAR('}')) p++; t = p - pKey; // special key definition too big? if (t > sizeof(KeyString)) return false; // Take this KeyString into local buffer _tcsncpy(KeyString, pKey+1, t); KeyString[t-1] = _TXCHAR('\0'); keyIdx = -1; pKey += t; // skip to next keystring // Invalidate key MKey = INVALIDKEY; // sending arbitrary vkeys? if (_tcsnicmp(KeyString, _T("VKEY"), 4) == 0) { p = KeyString + 4; MKey = _ttoi(p); } else if (_tcsnicmp(KeyString, _T("BEEP"), 4) == 0) { p = KeyString + 4 + 1; LPTSTR p1 = p; DWORD frequency, delay; if ((p1 = _tcsstr(p, _T(" "))) != NULL) { *p1++ = _TXCHAR('\0'); frequency = _ttoi(p); delay = _ttoi(p1); ::Beep(frequency, delay); } } // Should activate a window? else if (_tcsnicmp(KeyString, _T("APPACTIVATE"), 11) == 0) { p = KeyString + 11 + 1; AppActivate(p); } // want to send/set delay? else if (_tcsnicmp(KeyString, _T("DELAY"), 5) == 0) { // Advance to parameters p = KeyString + 5; // set "sleep factor" if (*p == _TXCHAR('=')) m_nDelayAlways = _ttoi(p + 1); // Take number after the '=' character else // set "sleep now" m_nDelayNow = _ttoi(p); } // not command special keys, then process as keystring to VKey else { MKey = StringToVKey(KeyString, keyIdx); // Key found in table if (keyIdx != -1) { NumTimes = 1; // Does the key string have also count specifier? t = _tcslen(KeyNames[keyIdx].keyName); if (_tcslen(KeyString) > t) { p = KeyString + t; // Take the specified number of times NumTimes = _ttoi(p); } if (KeyNames[keyIdx].normalkey) MKey = ::VkKeyScan(KeyNames[keyIdx].VKey); } } // A valid key to send? if (MKey != INVALIDKEY) { SendKey(MKey, NumTimes, true); PopUpShiftKeys(); } } break; // a normal key was pressed default: // Get the VKey from the key MKey = ::VkKeyScan(ch); SendKey(MKey, 1, true); PopUpShiftKeys(); } pKey++; } m_bUsingParens = false; PopUpShiftKeys(); return true; }
// main window procedure static LRESULT WINAPI MainWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { switch ( uMsg ) { case WM_CREATE: GMainWindow = hWnd; if ( r_fullscreen->integer ) { WIN_DisableAltTab(); } else { WIN_EnableAltTab(); } break; case WM_DESTROY: // let sound and input know about this? GMainWindow = NULL; if ( r_fullscreen->integer ) { WIN_EnableAltTab(); } break; case WM_CLOSE: Cbuf_ExecuteText( EXEC_APPEND, "quit" ); break; case WM_ACTIVATE: AppActivate( LOWORD( wParam ) != WA_INACTIVE, !!HIWORD( wParam ) ); break; case WM_MOVE: if ( !r_fullscreen->integer ) { int xPos = ( short )LOWORD( lParam ); // horizontal position int yPos = ( short )HIWORD( lParam ); // vertical position RECT r; r.left = 0; r.top = 0; r.right = 1; r.bottom = 1; int style = GetWindowLong( hWnd, GWL_STYLE ); AdjustWindowRect( &r, style, FALSE ); Cvar_SetValue( "vid_xpos", xPos + r.left ); Cvar_SetValue( "vid_ypos", yPos + r.top ); vid_xpos->modified = false; vid_ypos->modified = false; if ( ActiveApp ) { IN_Activate( true ); } } break; case WM_SYSCOMMAND: if ( wParam == SC_SCREENSAVE ) { return 0; } break; case WM_SYSKEYDOWN: if ( wParam == 13 ) { if ( r_fullscreen ) { Cvar_SetValue( "r_fullscreen", !r_fullscreen->integer ); Cbuf_AddText( "vid_restart\n" ); } return 0; } // fall through break; case MM_MCINOTIFY: if ( CDAudio_MessageHandler( hWnd, uMsg, wParam, lParam ) == 0 ) { return 0; } break; } if ( IN_HandleInputMessage( uMsg, wParam, lParam ) ) { return 0; } return DefWindowProc( hWnd, uMsg, wParam, lParam ); }
LONG WINAPI MainWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { int fActive, fMinimized; int temp; LONG lRet = 0; PAINTSTRUCT ps; HDC hdc; switch (uMsg) { case WM_CREATE: break; case WM_MOVE: window_x = (int) LOWORD(lParam); window_y = (int) HIWORD(lParam); VID_UpdateWindowStatus (); //if ((modestate == MS_WINDOWED) && !in_mode_set && !Minimized) // VID_RememberWindowPos (); break; case WM_CLOSE: // this causes Close in the right-click task bar menu not to work, but right // now bad things happen if Close is handled in that case (garbage and a // crash on Win95) //if (!in_mode_set) { if (MessageBox (mainwindow, "Are you sure you want to quit?", "Confirm Exit", MB_YESNO | MB_SETFOREGROUND | MB_ICONQUESTION) == IDYES) { Host_Quit (); } } break; case WM_ACTIVATE: fActive = LOWORD(wParam); fMinimized = (BOOL) HIWORD(wParam); AppActivate(!(fActive == WA_INACTIVE), fMinimized); // fix the leftover Alt from any Alt-Tab or the like that switched us away ClearAllStates (); /*if (!in_mode_set) { if (windc) MGL_activatePalette(windc,true); VID_SetPalette(vid_curpal); }*/ break; case WM_PAINT: hdc = GetDC (mainwindow); // FIXME hdc = BeginPaint(hWnd, &ps); //Com_Printf ("WM_PAINT\n"); // TESTING /* if (!in_mode_set && host_initialized) { SCR_InvalidateScreen (); SCR_UpdateScreen (); } */ EndPaint(hWnd, &ps); break; case WM_KEYDOWN: case WM_SYSKEYDOWN: if (!in_mode_set) IN_TranslateKeyEvent (lParam, true); break; case WM_KEYUP: case WM_SYSKEYUP: if (!in_mode_set) IN_TranslateKeyEvent (lParam, true); break; // this is complicated because Win32 seems to pack multiple mouse events into // one update sometimes, so we always check all states and look for events case WM_LBUTTONDOWN: case WM_LBUTTONUP: case WM_RBUTTONDOWN: case WM_RBUTTONUP: case WM_MBUTTONDOWN: case WM_MBUTTONUP: case WM_XBUTTONDOWN: case WM_XBUTTONUP: case WM_MOUSEMOVE: if (!in_mode_set) { temp = 0; if (wParam & MK_LBUTTON) temp |= 1; if (wParam & MK_RBUTTON) temp |= 2; if (wParam & MK_MBUTTON) temp |= 4; // Win2k/XP let us bind button4 and button5 if (wParam & MK_XBUTTON1) temp |= 8; if (wParam & MK_XBUTTON2) temp |= 16; IN_MouseEvent (temp); } break; // JACK: This is the mouse wheel with the Intellimouse // Its delta is either positive or neg, and we generate the proper // Event. case WM_MOUSEWHEEL: if (in_mwheeltype != MWHEEL_DINPUT) { in_mwheeltype = MWHEEL_WINDOWMSG; if ((short) HIWORD(wParam) > 0) { Key_Event(K_MWHEELUP, true); Key_Event(K_MWHEELUP, false); } else { Key_Event(K_MWHEELDOWN, true); Key_Event(K_MWHEELDOWN, false); } } break; default: /* pass all unhandled messages to DefWindowProc */ lRet = DefWindowProc (hWnd, uMsg, wParam, lParam); break; } /* return 0 if handled message, 1 if not */ return lRet; }
/* main window procedure */ LONG WINAPI MainWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { extern void VID_UpdateWindowStatus (void); LONG lRet = 1; int fActive, fMinimized, temp; extern unsigned int uiWheelMessage; // VVD: didn't restore gamma after ALT+TAB on some ATI video cards (or drivers?...) // HACK!!! FIXME { extern int restore_gamma; static time_t time_old; static float old_gamma; if (restore_gamma == 2) { if (time(NULL) - time_old > 0) { Cvar_SetValue(&v_gamma, old_gamma); restore_gamma = 0; } } // } if (uMsg == uiWheelMessage) { uMsg = WM_MOUSEWHEEL; wParam <<= 16; } switch (uMsg) { #ifdef USINGRAWINPUT case WM_INPUT: // raw input handling IN_RawInput_MouseRead((HANDLE)lParam); break; #endif case WM_KILLFOCUS: break; case WM_SIZE: break; case WM_CREATE: mainwindow = hWnd; break; case WM_DESTROY: // let sound and input know about this? mainwindow = NULL; // PostQuitMessage (0); break; case WM_MOVE: { int xPos, yPos; RECT r; int style; if ( !r_fullscreen.integer ) { xPos = (short) LOWORD(lParam); // horizontal position yPos = (short) HIWORD(lParam); // vertical position r.left = 0; r.top = 0; r.right = 1; r.bottom = 1; style = GetWindowLong( hWnd, GWL_STYLE ); AdjustWindowRect( &r, style, FALSE ); Cvar_SetValue( &vid_xpos, xPos + r.left ); Cvar_SetValue( &vid_ypos, yPos + r.top ); vid_xpos.modified = false; vid_ypos.modified = false; } VID_UpdateWindowStatus(); } break; case WM_CLOSE: if (MessageBox (mainwindow, "Are you sure you want to quit?", "ezQuake : Confirm Exit", MB_YESNO | MB_SETFOREGROUND | MB_ICONQUESTION) == IDYES) { Host_Quit (); } break; case WM_ACTIVATE: fActive = LOWORD(wParam); fMinimized = (BOOL) HIWORD(wParam); AppActivate(!(fActive == WA_INACTIVE), fMinimized); // VVD: didn't restore gamma after ALT+TAB on some ATI video cards (or drivers?...) // HACK!!! FIXME { if (restore_gamma == 1) { time_old = time(NULL); restore_gamma = 2; old_gamma = v_gamma.value; Cvar_SetValue(&v_gamma, old_gamma + 0.01); } // } // fix the leftover Alt from any Alt-Tab or the like that switched us away ClearAllStates (); break; case WM_SYSKEYDOWN: if ( wParam == 13 ) { if ( glw_state.vid_canalttab ) { Cvar_LatchedSetValue( &r_fullscreen, !r_fullscreen.integer ); Cbuf_AddText( "vid_restart\n" ); } return 0; } // fall through case WM_KEYDOWN: #ifdef WITH_KEYMAP IN_TranslateKeyEvent (lParam, wParam, true); #else // WITH_KEYMAP Key_Event (IN_MapKey(lParam), true); #endif // WITH_KEYMAP else break; case WM_KEYUP: case WM_SYSKEYUP: #ifdef WITH_KEYMAP IN_TranslateKeyEvent (lParam, wParam, false); #else // WITH_KEYMAP Key_Event (IN_MapKey(lParam), false); #endif // WITH_KEYMAP else break; case WM_SYSCHAR: // keep Alt-Space from happening break; // this is complicated because Win32 seems to pack multiple mouse events into // one update sometimes, so we always check all states and look for events case WM_LBUTTONDOWN: case WM_LBUTTONUP: case WM_RBUTTONDOWN: case WM_RBUTTONUP: case WM_MBUTTONDOWN: case WM_MBUTTONUP: case WM_XBUTTONDOWN: case WM_XBUTTONUP: #ifdef MM_CODE case WM_LBUTTONDBLCLK: case WM_RBUTTONDBLCLK: case WM_MBUTTONDBLCLK: case WM_XBUTTONDBLCLK: #endif // MM_CODE temp = 0; if (wParam & MK_LBUTTON) temp |= 1; if (wParam & MK_RBUTTON) temp |= 2; if (wParam & MK_MBUTTON) temp |= 4; if (wParam & MK_XBUTTON1) temp |= 8; if (wParam & MK_XBUTTON2) temp |= 16; IN_MouseEvent (temp); break; // JACK: This is the mouse wheel with the Intellimouse // Its delta is either positive or neg, and we generate the proper Event. case WM_MOUSEWHEEL: if (in_mwheeltype != MWHEEL_DINPUT) { in_mwheeltype = MWHEEL_WINDOWMSG; if ((short) HIWORD(wParam) > 0) { Key_Event(K_MWHEELUP, true); Key_Event(K_MWHEELUP, false); } else { Key_Event(K_MWHEELDOWN, true); Key_Event(K_MWHEELDOWN, false); } // when an application processes the WM_MOUSEWHEEL message, it must return zero lRet = 0; } break; case WM_MWHOOK: MW_Hook_Message (lParam); break; case MM_MCINOTIFY: lRet = CDAudio_MessageHandler (hWnd, uMsg, wParam, lParam); break; default: /* pass all unhandled messages to DefWindowProc */ lRet = DefWindowProc (hWnd, uMsg, wParam, lParam); break; } /* return 1 if handled message, 0 if not */ return lRet; }
int CGame::WindowProc ( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { LONG lRet = 0; int temp = 0; HDC hdc; PAINTSTRUCT ps; // static int recursiveflag; bool fAltDown; g_pVCR->TrapWindowProc( uMsg, wParam, lParam ); if ( !engine ) { return DefWindowProc( hWnd, uMsg, wParam, lParam ); } #ifndef USE_DI_MOUSE if ( uMsg == m_uiMouseWheel ) { eng->TrapKey_Event( ( ( int ) wParam ) > 0 ? K_MWHEELUP : K_MWHEELDOWN, true ); eng->TrapKey_Event( ( ( int ) wParam ) > 0 ? K_MWHEELUP : K_MWHEELDOWN, false ); return lRet; } #endif switch (uMsg) { case WM_SETFOCUS: if ( launcherui->IsActive() ) { launcherui->RequestFocus(); } break; case WM_CREATE: ::SetForegroundWindow(hWnd); break; #ifndef USE_DI_MOUSE case WM_MOUSEWHEEL: eng->TrapKey_Event( ( short ) HIWORD( wParam ) > 0 ? K_MWHEELUP : K_MWHEELDOWN, true ); eng->TrapKey_Event( ( short ) HIWORD( wParam ) > 0 ? K_MWHEELUP : K_MWHEELDOWN, false ); break; #endif case WM_SYSCOMMAND: if ( ( wParam == SC_SCREENSAVE ) || ( wParam == SC_CLOSE ) ) { return lRet; } if ( !videomode->GetInModeChange() ) { engine->S_BlockSound (); engine->S_ClearBuffer (); } lRet = DefWindowProc (hWnd, uMsg, wParam, lParam); if ( !videomode->GetInModeChange() ) { engine->S_UnblockSound (); } break; case WM_SIZE: if (wParam == SIZE_MINIMIZED) { MoveWindow( hWnd, 0, -20, 0, 20, FALSE ); } break; case WM_MOVE: game->SetWindowXY( (int)LOWORD( lParam ), (int)HIWORD( lParam ) ); videomode->UpdateWindowPosition(); break; case WM_SYSCHAR: // keep Alt-Space from happening break; case WM_ACTIVATEAPP: AppActivate( wParam ? true : false ); break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); EndPaint(hWnd, &ps); break; #ifndef USE_DI_KEYBOARD case WM_KEYDOWN: case WM_SYSKEYDOWN: if ( !videomode->GetInModeChange() ) { eng->TrapKey_Event (MapKey(lParam), true ); } break; #endif case WM_SYSKEYUP: fAltDown = ( HIWORD(lParam) & KF_ALTDOWN ) ? true : false; // Check for ALT-TAB and ALT-ESC if (fAltDown && (wParam == VK_TAB || wParam == VK_ESCAPE)) { if (!videomode->IsWindowedMode()) { ShowWindow(hWnd, SW_MINIMIZE); break; } } #ifndef USE_DI_KEYBOARD case WM_KEYUP: if ( !videomode->GetInModeChange() ) { eng->TrapKey_Event (MapKey(lParam), false ); } break; #endif #ifndef USE_DI_MOUSE // this is complicated because Win32 seems to pack multiple mouse events into // one update sometimes, so we always check all states and look for events case WM_MOUSEMOVE: if ( !videomode->GetInModeChange() ) { temp |= FieldsFromMouseWParam( wParam ); eng->TrapMouse_Event ( temp, true ); } break; case WM_LBUTTONDOWN: case WM_RBUTTONDOWN: case WM_MBUTTONDOWN: case MS_WM_XBUTTONDOWN: if ( !videomode->GetInModeChange() ) { temp |= FieldsFromMouseWParam( wParam ); eng->TrapMouse_Event ( temp, true ); } break; case WM_LBUTTONUP: case WM_RBUTTONUP: case WM_MBUTTONUP: case MS_WM_XBUTTONUP: if ( !videomode->GetInModeChange() ) { temp = FieldsFromMouseUpMsgAndWParam( uMsg, wParam ) | FieldsFromMouseWParam( wParam ); eng->TrapMouse_Event ( temp, false ); } break; #endif case WM_CLOSE: if ( !videomode->GetInModeChange() ) { if ( eng->GetState() == DLL_ACTIVE ) { eng->Unload(); gui->SetQuitting(); } } lRet = 0; break; default: /* pass all unhandled messages to DefWindowProc */ lRet = DefWindowProc (hWnd, uMsg, wParam, lParam); break; } /* return 0 if handled message, 1 if not */ return lRet; }
static void IN_HandleEvents( void ) { Uint16 *wtext = NULL; SDL_PumpEvents(); SDL_Event event; while( SDL_PollEvent( &event ) ) { switch( event.type ) { case SDL_KEYDOWN: key_event( &event.key, true ); // Emulate copy/paste #if defined( __APPLE__ ) #define KEYBOARD_COPY_PASTE_MODIFIER KMOD_GUI #else #define KEYBOARD_COPY_PASTE_MODIFIER KMOD_CTRL #endif if( event.key.keysym.sym == SDLK_c ) { if( event.key.keysym.mod & KEYBOARD_COPY_PASTE_MODIFIER ) { Key_CharEvent( KC_CTRLC, KC_CTRLC ); } } else if( event.key.keysym.sym == SDLK_v ) { if( event.key.keysym.mod & KEYBOARD_COPY_PASTE_MODIFIER ) { Key_CharEvent( KC_CTRLV, KC_CTRLV ); } } break; case SDL_KEYUP: key_event( &event.key, false ); break; case SDL_TEXTINPUT: // SDL_iconv_utf8_ucs2 uses "UCS-2-INTERNAL" as tocode and fails to convert text on Linux // where SDL_iconv uses system iconv. So we force needed encoding directly #if SDL_BYTEORDER == SDL_LIL_ENDIAN #define UCS_2_INTERNAL "UCS-2LE" #else #define UCS_2_INTERNAL "UCS-2BE" #endif wtext = (Uint16 *)SDL_iconv_string( UCS_2_INTERNAL, "UTF-8", event.text.text, SDL_strlen( event.text.text ) + 1 ); if( wtext ) { wchar_t charkey = wtext[0]; int key = ( charkey <= 255 ) ? charkey : 0; Key_CharEvent( key, charkey ); SDL_free( wtext ); } break; case SDL_MOUSEMOTION: mouse_motion_event( &event.motion ); break; case SDL_MOUSEBUTTONDOWN: mouse_button_event( &event.button, true ); break; case SDL_MOUSEBUTTONUP: mouse_button_event( &event.button, false ); break; case SDL_MOUSEWHEEL: mouse_wheel_event( &event.wheel ); break; case SDL_QUIT: Cbuf_ExecuteText( EXEC_NOW, "quit" ); break; case SDL_WINDOWEVENT: switch( event.window.event ) { case SDL_WINDOWEVENT_SHOWN: AppActivate( true ); break; case SDL_WINDOWEVENT_HIDDEN: AppActivate( false ); break; case SDL_WINDOWEVENT_CLOSE: break; case SDL_WINDOWEVENT_FOCUS_GAINED: input_focus = true; break; case SDL_WINDOWEVENT_FOCUS_LOST: input_focus = false; break; case SDL_WINDOWEVENT_MOVED: // FIXME: move this somewhere else Cvar_SetValue( "vid_xpos", event.window.data1 ); Cvar_SetValue( "vid_ypos", event.window.data2 ); vid_xpos->modified = false; vid_ypos->modified = false; break; } break; } } }
///////////////////////////////////////////////////////////////////////////// // AppWndProc( hwnd, uiMessage, wParam, lParam ) // // The window proc for the app's main (tiled) window. This processes all // of the parent window's messages. // LONG FAR PASCAL _export AppWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam) { PAINTSTRUCT ps; HDC hdc; BOOL f; //is it the registered message? (this proc is called after the creation //of the msgApp). if (msg == msgApp) { if (bShowRendering) { HDC hdc = GetDC(hwndApp); AppPaint(hwndApp, hdc); ReleaseDC(hwndApp, hdc); bShowRendering = (int)wParam; //sent a 0 to turn off bShowRendering. } return 0L; } //well, how about standard Windows messages? switch (msg) { case WM_CREATE: //let WM_SIZE do all the work. break; case WM_ACTIVATEAPP: bAppActive = (BOOL)wParam; wt_reset_input(); // *** Remap the system colors and deal with the palette AppActivate(bAppActive); if (hpalApp) { HDC hdc = GetDC(hwnd); UnrealizeObject(hpalApp); SelectPalette(hdc, hpalApp, FALSE); RealizePalette(hdc); ReleaseDC(hwnd, hdc); } break; case WM_SIZE: wt_reset_input(); nBitmapW = LOWORD(lParam); //new size. nBitmapH = HIWORD(lParam); nBitmapW /= StretchFactor; nBitmapH /= StretchFactor; //Windows DIBs, including WinG bitmaps, are always a multiple of //32-bits wide. For us, using the typical 8-bit per pixel bitmap, //that means we need to ensure the width is a multiple of 4. This //is important because the WT engine treats a bitmap's width and //pitch as one - there is no way for WT to draw into a bitmap //using a width different than the pitch. So we force the bitmap's //width to be a multiple of 4, to be both Windows and WT compatible. //Note we could have patched WT to deal with the concept of a //bitmap pitch, but that's too much change. nBitmapW = ((nBitmapW+3)/4)*4; if(Buffer) { //resizing, minimizing, maximizing. HBITMAP hbm; int Counter; //Create a new 8-bit WinGBitmap with the new size BufferHeader.Header.biWidth = nBitmapW; BufferHeader.Header.biHeight = nBitmapH * Orientation; //probably don't need to do this, but do it anyway. for(Counter = 0;Counter < 256;Counter++) { BufferHeader.aColors[Counter].rgbRed = ColorTable[Counter].rgbRed; BufferHeader.aColors[Counter].rgbGreen = ColorTable[Counter].rgbGreen; BufferHeader.aColors[Counter].rgbBlue = ColorTable[Counter].rgbBlue; BufferHeader.aColors[Counter].rgbReserved = 0; } hbm = WinG.pCreateBitmap(Buffer, (BITMAPINFO *)&BufferHeader, &pBuffer); // Select it in and delete the old one hbm = (HBITMAP)SelectObject(Buffer, hbm); DeleteObject(hbm); PatBlt(Buffer, 0,0,nBitmapW,nBitmapH, BLACKNESS); wt_set_fb_mem(pBuffer); //tell WT about new bitmap address. wt_reinit(nBitmapW,nBitmapH); //and about new bitmap size. wt_render(); //and have WT render a frame. } else //first time. { // Create a new WinGDC and 8-bit WinGBitmap HBITMAP hbm; int Counter; // Get WinG to recommend the fastest DIB format if(WinG.pRecommendDIBFormat((BITMAPINFO *)&BufferHeader)) { // make sure it's 8bpp and remember the orientation BufferHeader.Header.biBitCount = 8; BufferHeader.Header.biCompression = BI_RGB; Orientation = BufferHeader.Header.biHeight; if (Orientation > 0) { DebugMsg("WT requires a top-down bitmap!\nYou are about to hit a brick wall at 90 MPH!"); PostQuitMessage(1); //works but slams palette. bummer. } } else { // set it up ourselves BufferHeader.Header.biSize = sizeof(BITMAPINFOHEADER); BufferHeader.Header.biPlanes = 1; BufferHeader.Header.biBitCount = 8; BufferHeader.Header.biCompression = BI_RGB; BufferHeader.Header.biSizeImage = 0; BufferHeader.Header.biClrUsed = 0; BufferHeader.Header.biClrImportant = 0; } BufferHeader.Header.biWidth = nBitmapW; BufferHeader.Header.biHeight = nBitmapH * Orientation; //#define BAD_PALETTE_CODE #ifdef BAD_PALETTE_CODE //This code sets an incorrect palette, but at least you can still use //regular windows tools. Good for debugging. HDC Screen; RGBQUAD *pColorTable; // create an identity palette from the DIB's color table // get the 20 system colors as PALETTEENTRIES Screen = GetDC(0); GetSystemPaletteEntries(Screen,0,10,LogicalPalette.aEntries); GetSystemPaletteEntries(Screen,246,10, LogicalPalette.aEntries + 246); ReleaseDC(0,Screen); // initialize the logical palette and DIB color table for(Counter = 0;Counter < 10;Counter++) { // copy the system colors into the DIB header // WinG will do this in WinGRecommendDIBFormat, // but it may have failed above so do it here anyway BufferHeader.aColors[Counter].rgbRed = LogicalPalette.aEntries[Counter].peRed; BufferHeader.aColors[Counter].rgbGreen = LogicalPalette.aEntries[Counter].peGreen; BufferHeader.aColors[Counter].rgbBlue = LogicalPalette.aEntries[Counter].peBlue; BufferHeader.aColors[Counter].rgbReserved = 0; LogicalPalette.aEntries[Counter].peFlags = 0; BufferHeader.aColors[Counter + 246].rgbRed = LogicalPalette.aEntries[Counter + 246].peRed; BufferHeader.aColors[Counter + 246].rgbGreen = LogicalPalette.aEntries[Counter + 246].peGreen; BufferHeader.aColors[Counter + 246].rgbBlue = LogicalPalette.aEntries[Counter + 246].peBlue; BufferHeader.aColors[Counter + 246].rgbReserved = 0; LogicalPalette.aEntries[Counter + 246].peFlags = 0; } for (i=0; i<256; i++) { ColorTable[i].rgbRed = 0; ColorTable[i].rgbGreen = 0; ColorTable[i].rgbBlue = 0; } nColors = wt_load_palette(); for (i=0; i<nColors; i++) { int r,g,b; wt_get_palette_entry(i,&r,&g,&b); ColorTable[i].rgbRed = r; ColorTable[i].rgbGreen = g; ColorTable[i].rgbBlue = b; } pColorTable = &ColorTable[0]; for(Counter = 10;Counter < 246;Counter++) { // copy from the original color table to the WinGBitmap's // color table and the logical palette BufferHeader.aColors[Counter].rgbRed = LogicalPalette.aEntries[Counter].peRed = pColorTable[Counter].rgbRed; BufferHeader.aColors[Counter].rgbGreen = LogicalPalette.aEntries[Counter].peGreen = pColorTable[Counter].rgbGreen; BufferHeader.aColors[Counter].rgbBlue = LogicalPalette.aEntries[Counter].peBlue = pColorTable[Counter].rgbBlue; BufferHeader.aColors[Counter].rgbReserved = 0; LogicalPalette.aEntries[Counter].peFlags = PC_NOCOLLAPSE; } hpalApp = CreatePalette((LOGPALETTE *)&LogicalPalette); #else //GOOD_PALETTE_CODE //Working palette code. Has correct colors. And identity. Same frame //rate as bad palette code. This really hoses Windows colors, so //a GUI debugger's windows are really hard to read. I couldn't read the //Symantec IDDE's windows - so I #ifdef'd the bad palette code in for //debugging. //Anyway, this code works. Need 3 things for identity, as far as I can tell: //1. you have to be writing to your bitmap using a specific palette, //2. this palette has to be made into a Windows palette, and selected. //3. this palette has to be copied into the BitmapInfo header of the WinG // bitmap, before creating it (actually as a parameter to creating it). // ClearSystemPalette(); CreateWTPalette(); for(Counter = 0;Counter < 256;Counter++) { BufferHeader.aColors[Counter].rgbRed = ColorTable[Counter].rgbRed; BufferHeader.aColors[Counter].rgbGreen = ColorTable[Counter].rgbGreen; BufferHeader.aColors[Counter].rgbBlue = ColorTable[Counter].rgbBlue; BufferHeader.aColors[Counter].rgbReserved = 0; } #endif // Create a WinGDC and Bitmap, then select away Buffer = WinG.pCreateDC(); hbm = WinG.pCreateBitmap(Buffer, (BITMAPINFO *)&BufferHeader, &pBuffer); // Store the old hbitmap to select back in before deleting gbmOldMonoBitmap = (HBITMAP)SelectObject(Buffer, hbm); PatBlt(Buffer, 0,0,nBitmapW,nBitmapH, BLACKNESS); wt_set_fb_mem(pBuffer); //hack to get around WT's code. strcpy(szDefaultWorldFileName, szModulePath); strcat(szDefaultWorldFileName, DEFAULT_WORLD_FILEPATH); wt_init(szDefaultWorldFileName, nBitmapW,nBitmapH); AppSetCaption(DEFAULT_WORLD_FILETITLE); wt_render(); } bWTinitialized = TRUE; break; case WM_KEYDOWN: //set WT's keyboard array, then do a WT cycle. switch (wParam) { case VK_UP: kbPressed[kbUpArrow] = 1; break; case VK_DOWN: kbPressed[kbDownArrow] = 1; break; case VK_LEFT: kbPressed[kbLeftArrow] = 1; break; case VK_RIGHT: kbPressed[kbRightArrow] = 1; break; case VK_CONTROL: kbPressed[kbCtrl] = 1; break; case VK_ESCAPE: kbPressed[kbEsc] = 1; //DestroyWindow() here? let's check to ensure that func // will send the proper msgs to close stuff. break; case VK_SPACE: kbPressed[kbSpace] = 1; break; case VK_SHIFT: kbPressed[kbLeftShift] = 1; break; case VK_TAB: kbPressed[kbAlt] = 1; break; } //tried using wt_input/wt_render/InvalidateRect sequence //here, but was sometimes jerky (missed frames, actually), //if there was too much keyboard activity. //I think windows was collapsing queued/pending //WM_PAINT messages, so that the app got one instead of a //sudden stream. Anyhow now I draw immediately, and it works //great. Note that AppIdle() processing is required to //have acceleration/deceleration/monsters/events occur without //keyboard input. I guess a timer could also be used. //So I ended up using this helper routine to repaint. AppDoCycle(); break; case WM_KEYUP: //set WT's keyboard array, then do a WT cycle. switch (wParam) { case VK_UP: kbPressed[kbUpArrow] = 0; break; case VK_DOWN: kbPressed[kbDownArrow] = 0; break; case VK_LEFT: kbPressed[kbLeftArrow] = 0; break; case VK_RIGHT: kbPressed[kbRightArrow] = 0; break; case VK_CONTROL: kbPressed[kbCtrl] = 0; break; case VK_ESCAPE: kbPressed[kbEsc] = 0; break; case VK_SPACE: kbPressed[kbSpace] = 0; break; case VK_SHIFT: kbPressed[kbLeftShift] = 0; break; case VK_TAB: kbPressed[kbAlt] = 0; break; } AppDoCycle(); break; case WM_LBUTTONDOWN: break; case WM_RBUTTONDOWN: break; case WM_MOUSEMOVE: break; case WM_COMMAND: return AppCommand(hwnd,msg,wParam,lParam); case WM_DESTROY: PostQuitMessage(0); break; case WM_CLOSE: break; case WM_PALETTECHANGED: if ((HWND)wParam == hwnd) break; // fall through to WM_QUERYNEWPALETTE case WM_QUERYNEWPALETTE: hdc = GetDC(hwnd); if (hpalApp) SelectPalette(hdc, hpalApp, FALSE); f = RealizePalette(hdc); ReleaseDC(hwnd,hdc); if (f) InvalidateRect(hwnd,NULL,TRUE); return f; case WM_PAINT: hdc = BeginPaint(hwnd,&ps); SelectPalette(hdc, hpalApp, FALSE); RealizePalette(hdc); AppPaint (hwnd,hdc); EndPaint(hwnd,&ps); return 0L; } return DefWindowProc(hwnd,msg,wParam,lParam); }
LONG CALLBACK AppWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam) /**************************************************************************** * * Function: AppWndProc * * Description: Main window proc for application. * ****************************************************************************/ { PAINTSTRUCT ps; HDC hdc; switch (msg) { case WM_ACTIVATEAPP: fAppActive = (BOOL)wParam; if (!includeStatic) { AppActivate(fAppActive); } break; case WM_COMMAND: switch (wParam) { case MENU_OPEN: OpenBitmapFile(hwnd); break; case MENU_ABOUT: DialogBox(hInstApp,"AppAbout",hwnd,(DLGPROC)AppAbout); break; case MENU_EXIT: PostMessage(hwnd,WM_CLOSE,0,0L); break; case MENU_STRETCH_TOWINDOW: stretchBlt = !stretchBlt; CheckMenuItems(hwnd); InvalidateRect(hwnd, NULL, FALSE); break; case MENU_STATIC_COLORS: if (includeStatic) { /* Enable use of static colors */ includeStatic = false; AppActivate(true); } else { /* Remap the system colors to normal */ includeStatic = true; AppActivate(false); } CheckMenuItems(hwnd); /* Rebuild the MGL device context to re-build the * palette for the loaded bitmap. */ CreateMGLDeviceContexts(hwnd); InvalidateRect(hwnd, NULL, FALSE); break; case MENU_ANIMATE_PALETTE: animatePalette = !animatePalette; CheckMenuItems(hwnd); break; } return 0; case WM_CREATE: CreateMGLDeviceContexts(hwnd); break; case WM_DESTROY: PostQuitMessage(0); break; case WM_PALETTECHANGED: if ((HWND)wParam == hwnd) break; /* Fall through to WM_QUERYNEWPALETTE */ case WM_QUERYNEWPALETTE: if (winDC && memDC) { LoadBitmapPalette(winDC,memDC); InvalidateRect(hwnd,NULL,TRUE); return 1; } return 0; case WM_PAINT: if (!winDC) break; hdc = BeginPaint(hwnd,&ps); PatBlt(hdc,0,0,MGL_sizex(winDC)+1,MGL_sizey(winDC)+1,WHITENESS); if (memDC) { if (stretchBlt) { MGL_stretchBltCoord(winDC,memDC, 0,0,MGL_sizex(memDC)+1,MGL_sizey(memDC)+1, 0,0,MGL_sizex(winDC)+1,MGL_sizey(winDC)+1,MGL_REPLACE_MODE); } else { MGL_bitBltCoord(winDC,memDC, 0,0,MGL_sizex(memDC)+1,MGL_sizey(memDC)+1, 0,0,MGL_REPLACE_MODE); } } EndPaint(hwnd,&ps); return 0; } return DefWindowProc(hwnd,msg,wParam,lParam); }