//---------------------------------------------------------------------------- static pascal OSStatus ProcessMouseDragged (EventHandlerCallRef, EventRef evt, void*) { Point mouseLoc; GetEventParameter(evt, kEventParamMouseLocation, typeQDPoint, 0, sizeof(mouseLoc), 0, &mouseLoc); EventMouseButton mouseButton; GetEventParameter(evt, kEventParamMouseButton, typeMouseButton, 0, sizeof(mouseButton), 0, &mouseButton); UInt32 modifiers; GetEventParameter(evt, kEventParamKeyModifiers, typeUInt32, 0, sizeof(modifiers), 0, &modifiers); WindowApplication* theApp = (WindowApplication*)Application::TheApplication; CGrafPtr currPort; GetPort(&currPort); SetPortWindowPort((WindowRef)(theApp->GetWindowID())); GlobalToLocal(&mouseLoc); SetPort(currPort); theApp->OnMotion(mouseButton, mouseLoc.h, mouseLoc.v, modifiers); // Allow standard handler to run. return eventNotHandledErr; }
//---------------------------------------------------------------------------- static pascal OSStatus ProcessKeyModifierChanged (EventHandlerCallRef, EventRef evt, void*) { static UInt32 sLastState = 0; UInt32 currState; GetEventParameter(evt, kEventParamKeyModifiers, typeUInt32, 0, sizeof(currState), 0, &currState); currState &= 0x0000FFFF; if (currState != sLastState) { WindowApplication* theApp = (WindowApplication*)Application::TheApplication; CGrafPtr currPort; GetPort(&currPort); SetPortWindowPort((WindowRef)(theApp->GetWindowID())); Point mouseLoc; GetMouse(&mouseLoc); SetPort(currPort); ProcessModifier(theApp, shiftKey, mouseLoc, currState, sLastState); ProcessModifier(theApp, controlKey, mouseLoc, currState, sLastState); ProcessModifier(theApp, optionKey, mouseLoc, currState, sLastState); ProcessModifier(theApp, cmdKey, mouseLoc, currState, sLastState); sLastState = currState; } // Allow standard handler to run. return eventNotHandledErr; }
//---------------------------------------------------------------------------- static void Terminate () { WindowApplication* theApp = (WindowApplication*)Application::TheApplication; if (theApp) { theApp->OnTerminate(); glutDestroyWindow(theApp->GetWindowID()); Renderer* renderer = (Renderer*)theApp->GetRenderer(); delete0(renderer); } }
//---------------------------------------------------------------------------- void WindowApplication::GetMousePosition (int& x, int& y) const { WindowApplication* theApp = (WindowApplication*)Application::TheApplication; CGrafPtr currPort; GetPort(&currPort); SetPortWindowPort((WindowRef)(theApp->GetWindowID())); Point mouseLoc; GetMouse(&mouseLoc); SetPort(currPort); x = (int)mouseLoc.h; y = (int)mouseLoc.v; }
//---------------------------------------------------------------------------- static pascal OSStatus ProcessKeyDown (EventHandlerCallRef, EventRef evt, void*) { char charCode; GetEventParameter(evt, kEventParamKeyMacCharCodes, typeChar, 0, sizeof(charCode), 0, &charCode); WindowApplication* theApp = (WindowApplication*)Application::TheApplication; CGrafPtr currPort; GetPort(&currPort); SetPortWindowPort((WindowRef)(theApp->GetWindowID())); Point mouseLoc; GetMouse(&mouseLoc); SetPort(currPort); if (charCode == kEscapeCharCode) { // Quit the application when 'esc' is pressed. QuitApplicationEventLoop(); return eventNotHandledErr; } if (isalnum(charCode) || isprint(charCode)) { theApp->OnKeyDown(charCode, mouseLoc.h, mouseLoc.v); } else { if (charCode == kFunctionKeyCharCode) { // Function key - get key identity. UInt32 keyCode; GetEventParameter(evt, kEventParamKeyCode, typeUInt32, 0, sizeof(keyCode), 0, &keyCode); charCode = keyCode & 0x000000FF; } // Do not filter for specific keys. This allows for keys such as tab, // delete, enter. theApp->OnSpecialKeyDown(charCode, mouseLoc.h, mouseLoc.v); } // Allow standard handler to run. return eventNotHandledErr; }
//---------------------------------------------------------------------------- void WindowApplication::SetMousePosition (int x, int y) { WindowApplication* theApp = (WindowApplication*)Application::TheApplication; CGrafPtr currPort; GetPort(&currPort); SetPortWindowPort((WindowRef)(theApp->GetWindowID())); Point mouseLoc; mouseLoc.h = (short)x; mouseLoc.v = (short)y; LocalToGlobal(&mouseLoc); SetPort(currPort); CGPoint point = CGPointMake((float)mouseLoc.h, (float)mouseLoc.v); CGPostMouseEvent(point, true, 1, false, 0); }
//---------------------------------------------------------------------------- static pascal OSStatus ProcessMouseMoved (EventHandlerCallRef, EventRef evt, void*) { Point mouseLoc; GetEventParameter(evt,kEventParamMouseLocation, typeQDPoint, 0, sizeof(mouseLoc), 0, &mouseLoc); WindowApplication* theApp = (WindowApplication*)Application::TheApplication; CGrafPtr currPort; GetPort(&currPort); SetPortWindowPort((WindowRef)(theApp->GetWindowID())); GlobalToLocal(&mouseLoc); SetPort(currPort); theApp->OnPassiveMotion(mouseLoc.h, mouseLoc.v); // Allow standard handler to run. return eventNotHandledErr; }
//---------------------------------------------------------------------------- LRESULT CALLBACK MsWindowEventHandler (HWND handle, UINT message, WPARAM wParam, LPARAM lParam) { WindowApplication* theApp = (WindowApplication*)Application::TheApplication; if (!theApp || !theApp->GetWindowID()) { return DefWindowProc(handle, message, wParam, lParam); } switch (message) { case WM_PAINT: { PAINTSTRUCT ps; BeginPaint(handle, &ps); theApp->OnDisplay(); EndPaint(handle, &ps); return 0; } case WM_ERASEBKGND: { // This tells Windows not to erase the background (and that the // application is doing so). return 1; } case WM_MOVE: { int xPos = (int)(LOWORD(lParam)); int yPos = (int)(HIWORD(lParam)); theApp->OnMove(xPos, yPos); return 0; } case WM_SIZE: { int width = (int)(LOWORD(lParam)); int height = (int)(HIWORD(lParam)); theApp->OnResize(width, height); return 0; } case WM_CHAR: { unsigned char key = (unsigned char)(char)wParam; // Quit the application if the KEY_TERMINATE key is pressed. if (key == theApp->KEY_TERMINATE) { PostQuitMessage(0); return 0; } // Get the cursor position in client coordinates. POINT point; GetCursorPos(&point); ScreenToClient(handle, &point); int xPos = (int)point.x; int yPos = (int)point.y; theApp->OnKeyDown(key, xPos, yPos); return 0; } case WM_KEYDOWN: { int virtKey = (int)wParam; // Get cursor position client coordinates. POINT point; GetCursorPos(&point); ScreenToClient(handle, &point); int xPos = (int)point.x; int yPos = (int)point.y; if ((VK_F1 <= virtKey && virtKey <= VK_F12) || (VK_PRIOR <= virtKey && virtKey <= VK_DOWN) || (virtKey == VK_INSERT) || (virtKey == VK_DELETE) || (virtKey == VK_SHIFT) || (virtKey == VK_CONTROL)) { theApp->OnSpecialKeyDown(virtKey, xPos, yPos); } return 0; } case WM_KEYUP: { int virtKey = (int)wParam; // get the cursor position in client coordinates POINT point; GetCursorPos(&point); ScreenToClient(handle, &point); int xPos = (int)point.x; int yPos = (int)point.y; if ((VK_F1 <= virtKey && virtKey <= VK_F12) || (VK_PRIOR <= virtKey && virtKey <= VK_DOWN) || (virtKey == VK_INSERT) || (virtKey == VK_DELETE) || (virtKey == VK_SHIFT) || (virtKey == VK_CONTROL)) { theApp->OnSpecialKeyUp(virtKey, xPos, yPos); } else { theApp->OnKeyUp((unsigned char)virtKey, xPos, yPos); } return 0; } case WM_LBUTTONDOWN: { int xPos = (int)(LOWORD(lParam)); int yPos = (int)(HIWORD(lParam)); theApp->OnMouseClick(WindowApplication::MOUSE_LEFT_BUTTON, WindowApplication::MOUSE_DOWN, xPos, yPos, PtrToUint(wParam)); return 0; } case WM_LBUTTONUP: { int xPos = (int)(LOWORD(lParam)); int yPos = (int)(HIWORD(lParam)); theApp->OnMouseClick(WindowApplication::MOUSE_LEFT_BUTTON, WindowApplication::MOUSE_UP, xPos, yPos, PtrToUint(wParam)); return 0; } case WM_MBUTTONDOWN: { int xPos = (int)(LOWORD(lParam)); int yPos = (int)(HIWORD(lParam)); theApp->OnMouseClick(WindowApplication::MOUSE_MIDDLE_BUTTON, WindowApplication::MOUSE_DOWN, xPos, yPos, PtrToUint(wParam)); return 0; } case WM_MBUTTONUP: { int xPos = (int)(LOWORD(lParam)); int yPos = (int)(HIWORD(lParam)); theApp->OnMouseClick(WindowApplication::MOUSE_MIDDLE_BUTTON, WindowApplication::MOUSE_UP, xPos, yPos, PtrToUint(wParam)); return 0; } case WM_RBUTTONDOWN: { int xPos = (int)(LOWORD(lParam)); int yPos = (int)(HIWORD(lParam)); theApp->OnMouseClick(WindowApplication::MOUSE_RIGHT_BUTTON, WindowApplication::MOUSE_DOWN, xPos, yPos, PtrToUint(wParam)); return 0; } case WM_RBUTTONUP: { int xPos = (int)(LOWORD(lParam)); int yPos = (int)(HIWORD(lParam)); theApp->OnMouseClick(WindowApplication::MOUSE_RIGHT_BUTTON, WindowApplication::MOUSE_UP, xPos, yPos, PtrToUint(wParam)); return 0; } case WM_MOUSEMOVE: { int xPos = (int)(LOWORD(lParam)); int yPos = (int)(HIWORD(lParam)); int button = -1; if (wParam & MK_LBUTTON) { button = WindowApplication::MOUSE_LEFT_BUTTON; } else if (wParam & MK_MBUTTON) { button = WindowApplication::MOUSE_MIDDLE_BUTTON; } else if (wParam & MK_RBUTTON) { button = WindowApplication::MOUSE_RIGHT_BUTTON; } if (button >= 0) { theApp->OnMotion(button, xPos, yPos, PtrToUint(wParam)); } else { theApp->OnPassiveMotion(xPos, yPos); } return 0; } case WM_MOUSEWHEEL: { short sWParam = (short)(HIWORD(wParam)); int delta = ((int)sWParam)/WHEEL_DELTA; int xPos = (int)(LOWORD(lParam)); int yPos = (int)(HIWORD(lParam)); unsigned int modifiers = (unsigned int)(LOWORD(wParam)); theApp->OnMouseWheel(delta, xPos, yPos, modifiers); return 0; } case WM_DESTROY: { // The DestroyWindow call when recreating the window for // multisampling causes the application to terminate. It is // not clear why the same problem did not occur in WM4. if (!gsIgnoreWindowDestroy) { PostQuitMessage(0); } gsIgnoreWindowDestroy = false; return 0; } } return DefWindowProc(handle, message, wParam, lParam); }