Ejemplo n.º 1
0
//----------------------------------------------------------------------------
static void KeyUpCallback (unsigned char key, int x, int y)
{
    WindowApplication* theApp =
        (WindowApplication*)Application::TheApplication;

    if (theApp)
    {
        theApp->OnKeyUp(key, x, y);
    }
}
Ejemplo n.º 2
0
//----------------------------------------------------------------------------
static pascal OSStatus ProcessKeyUp (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 (isalnum(charCode) || isprint(charCode))
	{
		theApp->OnKeyUp(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->OnSpecialKeyUp(charCode, mouseLoc.h, mouseLoc.v);
	}

	// Allow standard handler to run.
	return eventNotHandledErr;
}
Ejemplo n.º 3
0
//----------------------------------------------------------------------------
int WindowApplication::Main (int numArguments, char** arguments)
{
    // Initialize the extra data.  TODO:  Port the extra-data system of WM4
    // to WM5.
    memset(gsExtraData, 0, APP_EXTRA_DATA_QUANTITY*sizeof(char));

    WindowApplication* theApp = (WindowApplication*)TheApplication;
    theApp->KEY_TERMINATE = KEY_ESCAPE;

    // OpenGL uses a projection matrix for depth in [-1,1].
    Camera::SetDefaultDepthType(Camera::PM_DEPTH_MINUS_ONE_TO_ONE);

    // Allow work to be done before the window is created.
    if (!theApp->OnPrecreate())
    {
        return -1;
    }

    // Connect to the X server.
    const char* displayName = 0;
    Display* display = XOpenDisplay(displayName);
    if (!display)
    {
        return -2;
    }

    // Make sure the X server has OpenGL GLX extensions.
    int errorBase, eventBase;
    Bool success = glXQueryExtension(display, &errorBase, &eventBase);
    assertion(success == True, "GLX extensions not found.\n");
    if (!success)
    {
        return -3;
    }

    // Partial construction of a GLX renderer.  The window for the renderer
    // is not yet constructed.  When it is, the window identifier is supplied
    // to the renderer to complete its construction.
    RendererInput input;
    input.mDisplay = display;
    input.mVisual = 0;
    input.mContext = 0;
    mRenderer = new0 Renderer(input, theApp->GetWidth(), theApp->GetHeight(),
        mColorFormat, mDepthStencilFormat, mNumMultisamples);
    if (!input.mVisual || !input.mContext)
    {
        return -4;
    }

    // Create an X Window with the visual information created by the renderer
    // constructor.  The visual information might not be the default, so
    // create an X colormap to use.
    Window rootWindow = RootWindow(display, input.mVisual->screen);
    Colormap cMap = XCreateColormap(display, rootWindow,
        input.mVisual->visual, AllocNone);

    // Set the event mask to include exposure (paint), button presses (mouse),
    // and key presses (keyboard).
    XSetWindowAttributes windowAttributes;
    windowAttributes.colormap = cMap;
    windowAttributes.border_pixel = 0;
    windowAttributes.event_mask =
        ButtonPressMask |
        ButtonReleaseMask |
        PointerMotionMask |
        Button1MotionMask |
        Button2MotionMask |
        Button3MotionMask |
        KeyPressMask |
        KeyReleaseMask |
        ExposureMask |
        StructureNotifyMask;

    int xPos = theApp->GetXPosition();
    int yPos = theApp->GetYPosition();
    unsigned int width = (unsigned int)theApp->GetWidth();
    unsigned int height = (unsigned int)theApp->GetHeight();
    unsigned int borderWidth = 0;
    unsigned long valueMask = CWBorderPixel | CWColormap | CWEventMask;
    Window window = XCreateWindow(display, rootWindow, xPos, yPos, width,
        height, borderWidth, input.mVisual->depth, InputOutput,
        input.mVisual->visual, valueMask, &windowAttributes);

    XSizeHints hints;
    hints.flags = PPosition | PSize;
    hints.x = xPos;
    hints.y = yPos;
    hints.width = width;
    hints.height = height;
    XSetNormalHints(display, window, &hints);

    const char* iconName = theApp->GetWindowTitle();
    Pixmap iconPixmap = None;
    XSetStandardProperties(display, window, theApp->GetWindowTitle(),
        iconName, iconPixmap, arguments, numArguments, &hints);

    // Intercept the close-window event when the user selects the
    // window close button.  The event is a "client message".
    Atom wmDelete = XInternAtom(display, "WM_DELETE_WINDOW", False);
    XSetWMProtocols(display, window, &wmDelete, 1);

    // Finish the construction of the renderer.
    GlxRendererData* data = (GlxRendererData*)mRenderer->mData;
    if (!data->FinishConstruction(window, mRenderer))
    {
        return -5;
    }

    if (theApp->OnInitialize())
    {
        // The default OnPreidle() clears the buffers. Allow the application
        // to fill them before the window is shown and before the event loop
        // starts.
        theApp->OnPreidle();

        // Display the window.
        XMapWindow(display, window);

        // Start the message pump.
        bool applicationRunning = true;
        while (applicationRunning)
        {
            if (!XPending(display))
            {
                theApp->OnIdle();
                continue;
            }

            XEvent evt;
            XNextEvent(display, &evt);
            int index;
            bool state;

            if (evt.type == ButtonPress || evt.type == ButtonRelease)
            {
                theApp->OnMouseClick(evt.xbutton.button, evt.xbutton.type,
                    evt.xbutton.x, evt.xbutton.y, evt.xbutton.state);

                if (evt.type == ButtonPress)
                {
                    index = GLXAPP_BUTTONDOWN + evt.xbutton.button;
                    state = true;
                    SetExtraData(index, sizeof(bool), &state);
                }
                else
                {
                    index = GLXAPP_BUTTONDOWN + evt.xbutton.button;
                    state = false;
                    SetExtraData(index, sizeof(bool), &state);
                }

                continue;
            }

            if (evt.type == MotionNotify)
            {
                int button = 0;

                index = GLXAPP_BUTTONDOWN + 1;
                GetExtraData(index, sizeof(bool), &state);
                if (state)
                {
                    button = MOUSE_LEFT_BUTTON;
                }
                else
                {
                    index = GLXAPP_BUTTONDOWN + 2;
                    GetExtraData(index, sizeof(bool), &state);
                    if (state)
                    {
                        button = MOUSE_MIDDLE_BUTTON;
                    }
                    else
                    {
                        index = GLXAPP_BUTTONDOWN + 3;
                        GetExtraData(index, sizeof(bool), &state);
                        if (state)
                        {
                            button = MOUSE_RIGHT_BUTTON;
                        }
                    }
                }

                if (button > 0)
                {
                    theApp->OnMotion(button, evt.xmotion.x, evt.xmotion.y,
                        evt.xmotion.state);
                }
                else
                {
                    theApp->OnPassiveMotion(evt.xmotion.x, evt.xmotion.y);
                }
                continue;
            }

            if (evt.type == KeyPress || evt.type == KeyRelease)
            {
                KeySym keySym = XKeycodeToKeysym(display,
                    evt.xkey.keycode, 0);

                int key = (keySym & 0x00FF);

                // Quit application if the KEY_TERMINATE key is pressed.
                if (key == theApp->KEY_TERMINATE)
                {
                    XDestroyWindow(display, window);
                    applicationRunning = false;
                    continue;
                }

                // Adjust for special keys that exist on the key pad and on
                // the number pad.
                if ((keySym & 0xFF00) != 0)
                {
                    if (0x50 <= key && key <= 0x57)
                    {
                        // keypad Home, {L,U,R,D}Arrow, Pg{Up,Dn}, End
                        key += 0x45;
                    }
                    else if (key == 0x63)
                    {
                        // keypad Insert
                        key = 0x9e;
                    }
                    else if (key == 0xFF)
                    {
                        // keypad Delete
                        key = 0x9f;
                    }
                    else if (key == 0xE1 || key == 0xE2)
                    {
                        // L-shift or R-shift
                        key = KEY_SHIFT;
                        state = (evt.type == KeyPress);
                        SetExtraData(GLXAPP_SHIFTDOWN, sizeof(bool), &state);
                    }
                    else if (key == 0xE3 || key == 0xE4)
                    {
                        // L-ctrl or R-ctrl
                        key = KEY_CONTROL;
                    }
                    else if (key == 0xE9 || key == 0xEA)
                    {
                        // L-alt or R-alt
                        key = KEY_ALT;
                    }
                    else if (key == 0xEB || key == 0xEC)
                    {
                        key = KEY_COMMAND;
                    }
                }

                if ((KEY_HOME <= key &&  key <= KEY_END)
                ||  (KEY_F1 <= key   &&  key <= KEY_F12)
                ||  (KEY_SHIFT <= key && key <= KEY_COMMAND))
                {
                    if (evt.type == KeyPress)
                    {
                        theApp->OnSpecialKeyDown(key, evt.xbutton.x,
                            evt.xbutton.y);
                    }
                    else
                    {
                        theApp->OnSpecialKeyUp(key, evt.xbutton.x,
                            evt.xbutton.y);
                    }
                }
                else
                {
                    // Get key-modifier state.  Adjust for shift state.
                    unsigned char ucKey = (unsigned char)key;
                    GetExtraData(GLXAPP_SHIFTDOWN, sizeof(bool), &state);
                    if (state && 'a' <= ucKey && ucKey <= 'z')
                    {
                        ucKey = (unsigned char)(key - 32);
                    }

                    if (evt.type == KeyPress)
                    {
                        theApp->OnKeyDown(ucKey, evt.xbutton.x,
                            evt.xbutton.y);
                    }
                    else
                    {
                        theApp->OnKeyUp(ucKey, evt.xbutton.x,
                            evt.xbutton.y);
                    }
                }
                continue;
            }

            if (evt.type == Expose)
            {
                theApp->OnDisplay();
                continue;
            }

            if (evt.type == ConfigureNotify)
            {
                theApp->OnMove(evt.xconfigure.x, evt.xconfigure.y);
                theApp->OnResize(evt.xconfigure.width,
                    evt.xconfigure.height);
                continue;
            }

            if (evt.type == ClientMessage
            &&  evt.xclient.data.l[0] == wmDelete)
            {
                XDestroyWindow(display, window);
                applicationRunning = false;
                continue;
            }
        }
    }

    theApp->OnTerminate();
    XCloseDisplay(display);
    return 0;
}
Ejemplo n.º 4
0
//----------------------------------------------------------------------------
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);
}