diff options
Diffstat (limited to 'macosx/tkMacOSXMouseEvent.c')
-rw-r--r-- | macosx/tkMacOSXMouseEvent.c | 770 |
1 files changed, 395 insertions, 375 deletions
diff --git a/macosx/tkMacOSXMouseEvent.c b/macosx/tkMacOSXMouseEvent.c index a542091..3f911d7 100644 --- a/macosx/tkMacOSXMouseEvent.c +++ b/macosx/tkMacOSXMouseEvent.c @@ -2,7 +2,7 @@ * tkMacOSXMouseEvent.c -- * * This file implements functions that decode & handle mouse events - * on MacOS X. + * on MacOS X. * * Copyright 2001, Apple Computer, Inc. * @@ -49,6 +49,8 @@ * acting in its behalf permission to use and distribute the * software in accordance with the terms specified in this * license. + * + * RCS: @(#) $Id: tkMacOSXMouseEvent.c,v 1.6.2.7 2005/08/09 07:40:01 das Exp $ */ #include "tkInt.h" @@ -60,20 +62,21 @@ #include "tkMacOSXDebug.h" typedef struct { - WindowRef whichWin; - WindowRef activeNonFloating; + WindowRef whichWin; + WindowRef activeNonFloating; WindowPartCode windowPart; - Point global; - Point local; + Point global; + Point local; unsigned int state; - long delta; + long delta; + Window window; } MouseEventData; /* * Declarations of static variables used in this file. */ -static int gEatButtonUp = 0; /* 1 if we need to eat the next * up event */ +static int gEatButtonUp = 0; /* 1 if we need to eat the next * up event */ /* * Declarations of functions used only in this file. @@ -82,8 +85,10 @@ static int gEatButtonUp = 0; /* 1 if we need to eat the next * up event */ static void BringWindowForward _ANSI_ARGS_((WindowRef wRef)); static int GeneratePollingEvents(MouseEventData * medPtr); static int GenerateMouseWheelEvent(MouseEventData * medPtr); -static int HandleInGoAway(Tk_Window tkwin, WindowRef winPtr, Point where); -static int TkMacOSXToolarbuttonEvent(MouseEventData * medPtr, Point where); +static int GenerateButtonEvent(MouseEventData * medPtr); +static int GenerateToolbarButtonEvent(MouseEventData * medPtr); +static int HandleWindowTitlebarMouseDown(MouseEventData * medPtr, Tk_Window tkwin); +static unsigned int ButtonModifiers2State(UInt32 buttonState, UInt32 keyModifiers); extern int TkMacOSXGetEatButtonUp(); extern void TkMacOSXSetEatButtonUp(int f); @@ -93,14 +98,14 @@ extern void TkMacOSXSetEatButtonUp(int f); * * TkMacOSXProcessMouseEvent -- * - * This routine processes the event in eventPtr, and - * generates the appropriate Tk events from it. + * This routine processes the event in eventPtr, and + * generates the appropriate Tk events from it. * * Results: - * True if event(s) are generated - false otherwise. + * True if event(s) are generated - false otherwise. * * Side effects: - * Additional events may be place on the Tk event queue. + * Additional events may be place on the Tk event queue. * *---------------------------------------------------------------------- */ @@ -108,78 +113,73 @@ extern void TkMacOSXSetEatButtonUp(int f); int TkMacOSXProcessMouseEvent(TkMacOSXEvent *eventPtr, MacEventStatus * statusPtr) { - WindowRef frontWindow; - Tk_Window tkwin; - Point where, where2; - int xOffset, yOffset; - TkDisplay * dispPtr; - Window window; - int status,err; + Tk_Window tkwin; + Point where, where2; + int xOffset, yOffset, result; + TkDisplay * dispPtr; + OSStatus status; MouseEventData mouseEventData, * medPtr = &mouseEventData; - KeyMap keyMap; - long modif; switch (eventPtr->eKind) { - case kEventMouseUp: - case kEventMouseDown: - case kEventMouseMoved: - case kEventMouseDragged: - case kEventMouseWheelMoved: - break; - default: - return 0; - break; + case kEventMouseUp: + case kEventMouseDown: + case kEventMouseMoved: + case kEventMouseDragged: + case kEventMouseWheelMoved: + break; + default: + return 0; + break; } status = GetEventParameter(eventPtr->eventRef, - kEventParamMouseLocation, - typeQDPoint, NULL, - sizeof(where), NULL, - &where); + kEventParamMouseLocation, + typeQDPoint, NULL, + sizeof(where), NULL, + &where); if (status != noErr) { - fprintf (stderr, "Failed to retrieve mouse location,%d\n", status); - return 0; - } - medPtr->state = 0; - GetKeys(keyMap); - modif = EndianS32_BtoN(*(long*)(&keyMap[1])); - - if (modif & 2) { - medPtr->state |= LockMask; + GetGlobalMouse(&where); } - if (modif & 1) { - medPtr->state |= ShiftMask; - } - if (modif & 8) { - medPtr->state |= ControlMask; - } - if (modif & 32768) { - medPtr->state |= Mod1Mask; /* command key */ + status = GetEventParameter(eventPtr->eventRef, + kEventParamWindowRef, + typeWindowRef, NULL, + sizeof(WindowRef), NULL, + &medPtr->whichWin); + if (status == noErr) { + status = GetEventParameter(eventPtr->eventRef, + kEventParamWindowPartCode, + typeWindowPartCode, NULL, + sizeof(WindowPartCode), NULL, + &medPtr->windowPart); } - if (modif & 4) { - medPtr->state |= Mod2Mask; /* option key */ + if (status != noErr) { + medPtr->windowPart = FindWindow(where, &medPtr->whichWin); } - if (eventPtr->eKind == kEventMouseDown - || eventPtr->eKind == kEventMouseDragged ) { - EventMouseButton mouseButton; - status = GetEventParameter(eventPtr->eventRef, - kEventParamMouseButton, - typeMouseButton, NULL, - sizeof(mouseButton), NULL,&mouseButton); - if (status != noErr ) { - fprintf (stderr, "Failed to retrieve mouse button, %d\n", status); - statusPtr->err = 1; - return 0; - } - medPtr->state |= 1 << ((mouseButton-1)+8); + medPtr->window = TkMacOSXGetXWindow(medPtr->whichWin); + if (medPtr->whichWin != NULL && medPtr->window == None) { + return 0; } - - medPtr->windowPart = FindWindow(where, &medPtr->whichWin); - window = TkMacOSXGetXWindow(medPtr->whichWin); - if (medPtr->whichWin != NULL && window == None) { - return 0; + medPtr->state = ButtonModifiers2State(GetCurrentEventButtonState(), + GetCurrentEventKeyModifiers()); + medPtr->global = where; + status = GetEventParameter(eventPtr->eventRef, + kEventParamWindowMouseLocation, + typeQDPoint, NULL, + sizeof(Point), NULL, + &medPtr->local); + if (status == noErr) { + if (medPtr->whichWin) { + Rect widths; + GetWindowStructureWidths(medPtr->whichWin, &widths); + medPtr->local.h -= widths.left; + medPtr->local.v -= widths.top; + } + } else { + medPtr->local = where; + if (medPtr->whichWin) { + QDGlobalToLocalPoint(GetWindowPort(medPtr->whichWin), + &medPtr->local); + } } - - frontWindow = FrontWindow(); medPtr->activeNonFloating = ActiveNonFloatingWindow(); /* @@ -189,48 +189,33 @@ TkMacOSXProcessMouseEvent(TkMacOSXEvent *eventPtr, MacEventStatus * statusPtr) */ if (eventPtr->eKind == kEventMouseUp) { - if (TkMacOSXGetEatButtonUp()) { - TkMacOSXSetEatButtonUp(false); - return false; - } - return TkGenerateButtonEvent(where.h, where.v, - window, medPtr->state); + if (TkMacOSXGetEatButtonUp()) { + TkMacOSXSetEatButtonUp(false); + return false; + } + return GenerateButtonEvent(medPtr); } if (eventPtr->eKind == kEventMouseWheelMoved) { - status = GetEventParameter(eventPtr->eventRef, - kEventParamMouseWheelDelta, - typeLongInteger, NULL, - sizeof(medPtr->delta), NULL,&medPtr->delta); - if (status != noErr ) { - fprintf (stderr, - "Failed to retrieve mouse wheel delta, %d\n", status); - statusPtr->err = 1; - return false; - } + status = GetEventParameter(eventPtr->eventRef, + kEventParamMouseWheelDelta, + typeLongInteger, NULL, + sizeof(long), NULL, &medPtr->delta); + if (status != noErr ) { + fprintf (stderr, + "Failed to retrieve mouse wheel delta, %d\n", (int)status); + statusPtr->err = 1; + return false; + } } dispPtr = TkGetDisplayList(); - tkwin = Tk_IdToWindow(dispPtr->display, window); + tkwin = Tk_IdToWindow(dispPtr->display, medPtr->window); if (eventPtr->eKind != kEventMouseDown) { /* * MouseMoved, MouseDragged or kEventMouseWheelMoved */ - medPtr->global = where; - medPtr->local = where; - /* - * We must set the port to the right window -- the one - * we are actually going to use -- before finding - * the local coordinates, otherwise we will have completely - * wrong local x,y! - * - * I'm pretty sure this window is medPtr->whichWin, unless - * perhaps there is a grab. Certainly 'frontWindow' or - * 'medPtr->activeNonFloating' are wrong. - */ - SetPortWindowPort(medPtr->whichWin); - GlobalToLocal(&medPtr->local); if (eventPtr->eKind == kEventMouseWheelMoved) { return GenerateMouseWheelEvent(medPtr); } else { @@ -238,44 +223,15 @@ TkMacOSXProcessMouseEvent(TkMacOSXEvent *eventPtr, MacEventStatus * statusPtr) } } - if (medPtr->whichWin && eventPtr->eKind == kEventMouseDown) { - ProcessSerialNumber frontPsn, ourPsn; - Boolean flag; - err = GetFrontProcess(&frontPsn); - if (err != noErr) { - fprintf(stderr, "GetFrontProcess failed, %d\n", err); - statusPtr->err = 1; - return 1; - } - - GetCurrentProcess(&ourPsn); - err = SameProcess(&frontPsn, &ourPsn, &flag); - if (err != noErr) { - fprintf(stderr, "SameProcess failed, %d\n", err); - statusPtr->err = 1; - return 1; - } else { - if (!flag) { - err = SetFrontProcess(&ourPsn); - if (err != noErr) { - fprintf(stderr,"SetFrontProcess failed,%d\n", err); - statusPtr->err = 1; - return 1; - } - } - } - - } - if (medPtr->whichWin) { /* * We got a mouse down in a window * See if this is the activate click - * This click moves the window forward. We don't want + * This click moves the window forward. We don't want * the corresponding mouse-up to be reported to the application * or else it will mess up some Tk scripts. */ - + if (!(TkpIsWindowFloating(medPtr->whichWin)) && (medPtr->whichWin != medPtr->activeNonFloating)) { Tk_Window grabWin = TkMacOSXGetCapture(); @@ -305,42 +261,20 @@ TkMacOSXProcessMouseEvent(TkMacOSXEvent *eventPtr, MacEventStatus * statusPtr) * Clicks in the stoplights on a MacOS X title bar are processed * directly even for background windows. Do that here. */ - - switch (medPtr->windowPart) { - case inGoAway: - return HandleInGoAway(tkwin, medPtr->whichWin, where); - break; - case inCollapseBox: - /* - * The Appearance Manager handles collapsing for us, - * but we need to make sure we propagate the event in Tk. - */ - if (TrackBox(medPtr->whichWin, where, inCollapseBox)) { - TkpWmSetState((TkWindow *)tkwin, IconicState); - } - return false; - break; - case inZoomIn: - return false; - break; - case inZoomOut: - return false; - break; - case inToolbarButton: - BringWindowForward(medPtr->whichWin); - if (TrackBox(medPtr->whichWin, where, inToolbarButton)) { - return TkMacOSXToolarbuttonEvent(medPtr, where); - } - return false; - break; - default: - TkMacOSXSetEatButtonUp(true); - BringWindowForward(medPtr->whichWin); - return false; - } + if ((result = HandleWindowTitlebarMouseDown(medPtr, tkwin)) != -1) { + return result; + } else { + TkMacOSXSetEatButtonUp(true); + BringWindowForward(medPtr->whichWin); + return false; + } } } + + if ((result = HandleWindowTitlebarMouseDown(medPtr, tkwin)) != -1) { + return result; + } switch (medPtr->windowPart) { case inDrag: { CGrafPtr saveWorld; @@ -368,8 +302,7 @@ TkMacOSXProcessMouseEvent(TkMacOSXEvent *eventPtr, MacEventStatus * statusPtr) break; } case inContent: - return TkGenerateButtonEvent(where.h, where.v, - window, medPtr->state); + return GenerateButtonEvent(medPtr); break; case inGrow: /* @@ -382,18 +315,12 @@ TkMacOSXProcessMouseEvent(TkMacOSXEvent *eventPtr, MacEventStatus * statusPtr) if (TkMacOSXGrowToplevel(medPtr->whichWin, where) == true) { return true; } else { - return TkGenerateButtonEvent(where.h, - where.v, window, medPtr->state); + return GenerateButtonEvent(medPtr); } break; - case inGoAway: - return HandleInGoAway(tkwin, medPtr->whichWin, where); - break; case inMenuBar: { int oldMode; - KeyMap theKeys; - GetKeys(theKeys); oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL); TkMacOSXClearMenubarActive(); @@ -403,39 +330,11 @@ TkMacOSXProcessMouseEvent(TkMacOSXEvent *eventPtr, MacEventStatus * statusPtr) TkMacOSXPreprocessMenu(); TkMacOSXHandleMenuSelect(MenuSelect(where), - EndianS32_BtoN(*(long*)(&theKeys[1])) & 4); + medPtr->state & Mod2Mask); Tcl_SetServiceMode(oldMode); return true; /* TODO: may not be on event on queue. */ break; } - case inZoomIn: - case inZoomOut: - if (TkMacOSXZoomToplevel(medPtr->whichWin, where, - medPtr->windowPart) == true) { - return true; - } else { - return false; - } - break; - case inCollapseBox: - /* - * The Appearance Manager handles collapsing for us, - * but we need to make sure we propagate the event in Tk. - */ - if (TrackBox(medPtr->whichWin, where, inCollapseBox)) { - TkpWmSetState((TkWindow *)tkwin, IconicState); - } - return false; - break; - case inToolbarButton: - /* - * ToolbarButton attribute pressed while active - */ - if (TrackBox(medPtr->whichWin, where, inToolbarButton)) { - return TkMacOSXToolarbuttonEvent(medPtr, where); - } - return false; - break; default: return false; break; @@ -446,30 +345,59 @@ TkMacOSXProcessMouseEvent(TkMacOSXEvent *eventPtr, MacEventStatus * statusPtr) /* *---------------------------------------------------------------------- * - * HandleInGoAway -- + * HandleWindowTitlebarMouseDown -- * - * Tracks the cursor in the go away box and deletes the window - * if the button stays depressed on button up. + * Handle clicks in window titlebar. * * Results: - * True if no errors - false otherwise. + * 1 if event was handled, 0 if event was not handled, + * -1 if MouseDown was not in window titlebar. * * Side effects: - * The window tkwin may be destroyed. + * Additional events may be place on the Tk event queue. * *---------------------------------------------------------------------- */ + int -HandleInGoAway(Tk_Window tkwin, WindowRef win, Point where) +HandleWindowTitlebarMouseDown(MouseEventData * medPtr, Tk_Window tkwin) { - if (TrackGoAway(win, where)) { - if (tkwin == NULL) { - return false; - } - TkGenWMDestroyEvent(tkwin); - return true; - } - return false; + int result = 0; + + switch (medPtr->windowPart) { + case inGoAway: + if (TrackGoAway(medPtr->whichWin, medPtr->global)) { + if (tkwin) { + TkGenWMDestroyEvent(tkwin); + result = 1; + } + } + break; + case inCollapseBox: + if (TrackBox(medPtr->whichWin, medPtr->global, medPtr->windowPart)) { + if (tkwin) { + TkpWmSetState((TkWindow *)tkwin, IconicState);; + result = 1; + } + } + break; + case inZoomIn: + case inZoomOut: + if (TrackBox(medPtr->whichWin, medPtr->global, medPtr->windowPart)) { + result = TkMacOSXZoomToplevel(medPtr->whichWin, medPtr->windowPart); + } + break; + case inToolbarButton: + if (TrackBox(medPtr->whichWin, medPtr->global, medPtr->windowPart)) { + result = GenerateToolbarButtonEvent(medPtr); + } + break; + default: + result = -1; + break; + } + + return result; } /* @@ -477,16 +405,16 @@ HandleInGoAway(Tk_Window tkwin, WindowRef win, Point where) * * GeneratePollingEvents -- * - * This function polls the mouse position and generates X Motion, - * Enter & Leave events. The cursor is also updated at this - * time. + * This function polls the mouse position and generates X Motion, + * Enter & Leave events. The cursor is also updated at this + * time. * * Results: - * True if event(s) are generated - false otherwise. + * True if event(s) are generated - false otherwise. * * Side effects: - * Additional events may be place on the Tk event queue. - * The cursor may be changed. + * Additional events may be place on the Tk event queue. + * The cursor may be changed. * *---------------------------------------------------------------------- */ @@ -495,7 +423,6 @@ static int GeneratePollingEvents(MouseEventData * medPtr) { Tk_Window tkwin, rootwin, grabWin; - Window window; int local_x, local_y; TkDisplay *dispPtr; @@ -503,34 +430,33 @@ GeneratePollingEvents(MouseEventData * medPtr) grabWin = TkMacOSXGetCapture(); if ((!TkpIsWindowFloating(medPtr->whichWin) - && (medPtr->activeNonFloating != medPtr->whichWin))) { - /* - * If the window for this event is not floating, and is not the - * active non-floating window, don't generate polling events. - * We don't send events to backgrounded windows. So either send - * it to the grabWin, or NULL if there is no grabWin. - */ - - tkwin = grabWin; + && (medPtr->activeNonFloating != medPtr->whichWin))) { + /* + * If the window for this event is not floating, and is not the + * active non-floating window, don't generate polling events. + * We don't send events to backgrounded windows. So either send + * it to the grabWin, or NULL if there is no grabWin. + */ + + tkwin = grabWin; } else { - /* - * First check whether the toplevel containing this mouse - * event is the grab window. If not, then send the event - * to the grab window. Otherwise, set tkWin to the subwindow - * which most closely contains the mouse event. - */ + /* + * First check whether the toplevel containing this mouse + * event is the grab window. If not, then send the event + * to the grab window. Otherwise, set tkWin to the subwindow + * which most closely contains the mouse event. + */ - window = TkMacOSXGetXWindow(medPtr->whichWin); - dispPtr = TkGetDisplayList(); - rootwin = Tk_IdToWindow(dispPtr->display, window); - if ((rootwin == NULL) - || ((grabWin != NULL) && (rootwin != grabWin))) { - tkwin = grabWin; - } else { - tkwin = Tk_TopCoordsToWindow(rootwin, - medPtr->local.h, medPtr->local.v, - &local_x, &local_y); - } + dispPtr = TkGetDisplayList(); + rootwin = Tk_IdToWindow(dispPtr->display, medPtr->window); + if ((rootwin == NULL) + || ((grabWin != NULL) && (rootwin != grabWin))) { + tkwin = grabWin; + } else { + tkwin = Tk_TopCoordsToWindow(rootwin, + medPtr->local.h, medPtr->local.v, + &local_x, &local_y); + } } /* @@ -539,7 +465,7 @@ GeneratePollingEvents(MouseEventData * medPtr) */ Tk_UpdatePointer(tkwin, medPtr->global.h, medPtr->global.v, - medPtr->state); + medPtr->state); return true; } @@ -549,14 +475,14 @@ GeneratePollingEvents(MouseEventData * medPtr) * * BringWindowForward -- * - * Bring this background window to the front. We also set state - * so Tk thinks the button is currently up. + * Bring this background window to the front. We also set state + * so Tk thinks the button is currently up. * * Results: - * None. + * None. * * Side effects: - * The window is brought forward. + * The window is brought forward. * *---------------------------------------------------------------------- */ @@ -564,36 +490,75 @@ GeneratePollingEvents(MouseEventData * medPtr) static void BringWindowForward(WindowRef wRef) { + do { + ProcessSerialNumber frontPsn, ourPsn = {0, kCurrentProcess}; + Boolean flag; + int err; + + err = GetFrontProcess(&frontPsn); + if (err != noErr) { + fprintf(stderr, "GetFrontProcess failed, %d\n", err); + break; + } + err = SameProcess(&frontPsn, &ourPsn, &flag); + if (err != noErr) { + fprintf(stderr, "SameProcess failed, %d\n", err); + break; + } else { + if (!flag) { + err = SetFrontProcess(&ourPsn); + if (err != noErr) { + fprintf(stderr,"SetFrontProcess failed,%d\n", err); + break; + } + } + } + } while (0); + if (!TkpIsWindowFloating(wRef)) { - if (IsValidWindowPtr(wRef)) + if (IsValidWindowPtr(wRef)) SelectWindow(wRef); } } + +/* + *---------------------------------------------------------------------- + * + * GenerateMouseWheelEvent -- + * + * Generates a "MouseWheel" Tk event. + * + * Results: + * None. + * + * Side effects: + * Places a mousewheel event on the event queue. + * + *---------------------------------------------------------------------- + */ static int GenerateMouseWheelEvent(MouseEventData * medPtr) { Tk_Window tkwin, rootwin, grabWin; - Window window; int local_x, local_y; TkDisplay *dispPtr; TkWindow *winPtr; XEvent xEvent; if ((!TkpIsWindowFloating(medPtr->whichWin) - && (medPtr->activeNonFloating != medPtr->whichWin))) { - tkwin = NULL; + && (medPtr->activeNonFloating != medPtr->whichWin))) { + tkwin = NULL; } else { - window = TkMacOSXGetXWindow(medPtr->whichWin); - dispPtr = TkGetDisplayList(); - rootwin = Tk_IdToWindow(dispPtr->display, window); - if (rootwin == NULL) { - tkwin = NULL; - } else { - tkwin = Tk_TopCoordsToWindow(rootwin, - medPtr->local.h, medPtr->local.v, - &local_x, &local_y); - } + dispPtr = TkGetDisplayList(); + rootwin = Tk_IdToWindow(dispPtr->display, medPtr->window); + if (rootwin == NULL) { + tkwin = NULL; + } else { + tkwin = Tk_TopCoordsToWindow(rootwin, + medPtr->local.h, medPtr->local.v, + &local_x, &local_y); + } } /* @@ -604,7 +569,7 @@ GenerateMouseWheelEvent(MouseEventData * medPtr) grabWin = TkMacOSXGetCapture(); if ((tkwin == NULL) && (grabWin != NULL)) { - tkwin = grabWin; + tkwin = grabWin; } if (!tkwin) { return true; @@ -621,18 +586,18 @@ GenerateMouseWheelEvent(MouseEventData * medPtr) return true; } - + /* *---------------------------------------------------------------------- * * TkMacOSXGetEatButtonUp -- * * Results: - * Returns the flag indicating if we need to eat the - * next mouse up event + * Returns the flag indicating if we need to eat the + * next mouse up event * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ @@ -643,36 +608,39 @@ TkMacOSXGetEatButtonUp() } /* + *---------------------------------------------------------------------- + * * TkMacOSXSetEatButtonUp -- * * Results: - * None. + * None. * * Side effects: - * Sets the flag indicating if we need to eat the - * next mouse up event + * Sets the flag indicating if we need to eat the + * next mouse up event * + *---------------------------------------------------------------------- */ void TkMacOSXSetEatButtonUp(int f) { gEatButtonUp = f; } - + /* *---------------------------------------------------------------------- * * TkMacOSXButtonKeyState -- * - * Returns the current state of the button & modifier keys. + * Returns the current state of the button & modifier keys. * * Results: - * A bitwise inclusive OR of a subset of the following: - * Button1Mask, ShiftMask, LockMask, ControlMask, Mod?Mask, - * Mod?Mask. + * A bitwise inclusive OR of a subset of the following: + * Button1Mask, ShiftMask, LockMask, ControlMask, Mod?Mask, + * Mod?Mask. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ @@ -680,36 +648,62 @@ TkMacOSXSetEatButtonUp(int f) unsigned int TkMacOSXButtonKeyState() { - unsigned int state = 0; - KeyMap theKeys; - long modif; - - if (Button() & !gEatButtonUp) { - state |= Button1Mask; + UInt32 buttonState = 0, keyModifiers; + EventRef ev = GetCurrentEvent(); + + if (!gEatButtonUp) { + buttonState = ev ? GetCurrentEventButtonState() : GetCurrentButtonState(); } - - GetKeys(theKeys); + keyModifiers = ev ? GetCurrentEventKeyModifiers() : GetCurrentKeyModifiers(); - modif = EndianS32_BtoN(*(long*)(&theKeys[1])); + return ButtonModifiers2State(buttonState, keyModifiers); +} + +/* + *---------------------------------------------------------------------- + * + * ButtonModifiers2State -- + * + * Converts Carbon mouse button state and modifier values into a Tk + * button/modifier state. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ - if (modif & 2) { - state |= LockMask; +static unsigned int +ButtonModifiers2State(UInt32 buttonState, UInt32 keyModifiers) +{ + unsigned int state; + + /* Tk supports at most 5 buttons */ + state = (buttonState & ((1<<5) - 1)) << 8; + + if (keyModifiers & alphaLock) { + state |= LockMask; } - - if (modif & 1) { - state |= ShiftMask; + if (keyModifiers & shiftKey) { + state |= ShiftMask; } - - if (modif & 8) { - state |= ControlMask; + if (keyModifiers & controlKey) { + state |= ControlMask; } - - if (modif & 32768) { - state |= Mod1Mask; /* command key */ + if (keyModifiers & cmdKey) { + state |= Mod1Mask; /* command key */ } - - if (modif & 4) { - state |= Mod2Mask; /* option key */ + if (keyModifiers & optionKey) { + state |= Mod2Mask; /* option key */ + } + if (keyModifiers & kEventKeyModifierNumLockMask) { + state |= Mod3Mask; + } + if (keyModifiers & kEventKeyModifierFnMask) { + state |= Mod4Mask; } return state; @@ -720,16 +714,16 @@ TkMacOSXButtonKeyState() * * XQueryPointer -- * - * Check the current state of the mouse. This is not a complete - * implementation of this function. It only computes the root - * coordinates and the current mask. + * Check the current state of the mouse. This is not a complete + * implementation of this function. It only computes the root + * coordinates and the current mask. * * Results: - * Sets root_x_return, root_y_return, and mask_return. Returns - * true on success. + * Sets root_x_return, root_y_return, and mask_return. Returns + * true on success. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ @@ -746,83 +740,120 @@ XQueryPointer( int* win_y_return, unsigned int* mask_return) { - Point where; - CGrafPtr port; - GDHandle dev; - - GetGWorld(&port,&dev); - GetMouse(&where); - LocalToGlobal(&where); + if (root_x_return && root_y_return) { + Point where; + EventRef ev; + OSStatus status; + + if ((ev = GetCurrentEvent())) { + status = GetEventParameter(ev, + kEventParamMouseLocation, + typeQDPoint, NULL, + sizeof(where), NULL, + &where); + } + if (!ev || status != noErr) { + GetGlobalMouse(&where); + } - *root_x_return = where.h; - *root_y_return = where.v; - *mask_return = TkMacOSXButtonKeyState(); + *root_x_return = where.h; + *root_y_return = where.v; + } + if (mask_return) { + *mask_return = TkMacOSXButtonKeyState(); + } return True; } - - + /* *---------------------------------------------------------------------- * * TkGenerateButtonEvent -- * - * Given a global x & y position and the button key status this - * procedure generates the appropiate X button event. It also - * handles the state changes needed to implement implicit grabs. + * Given a global x & y position and the button key status this + * procedure generates the appropiate X button event. It also + * handles the state changes needed to implement implicit grabs. * * Results: - * True if event(s) are generated - false otherwise. + * True if event(s) are generated - false otherwise. * * Side effects: - * Additional events may be place on the Tk event queue. - * Grab state may also change. + * Additional events may be place on the Tk event queue. + * Grab state may also change. * *---------------------------------------------------------------------- */ int TkGenerateButtonEvent( - int x, /* X location of mouse */ - int y, /* Y location of mouse */ - Window window, /* X Window containing button event. */ - unsigned int state) /* Button Key state suitable for X event */ + int x, /* X location of mouse */ + int y, /* Y location of mouse */ + Window window, /* X Window containing button event. */ + unsigned int state) /* Button Key state suitable for X event */ +{ + MouseEventData med; + + bzero(&med, sizeof(MouseEventData)); + med.state = state; + med.window = window; + med.global.h = x; + med.global.v = y; + FindWindow(med.global, &med.whichWin); + med.activeNonFloating = ActiveNonFloatingWindow(); + med.local = med.global; + QDGlobalToLocalPoint(GetWindowPort(med.whichWin), &med.local); + + return GenerateButtonEvent(&med); +} + +/* + *---------------------------------------------------------------------- + * + * GenerateButtonEvent -- + * + * Generate an X button event from a MouseEventData structure. + * Handles the state changes needed to implement implicit grabs. + * + * Results: + * True if event(s) are generated - false otherwise. + * + * Side effects: + * Additional events may be place on the Tk event queue. + * Grab state may also change. + * + *---------------------------------------------------------------------- + */ + +static int +GenerateButtonEvent(MouseEventData * medPtr) { - WindowRef whichWin, frontWin; - Point where; Tk_Window tkwin; int dummy; TkDisplay *dispPtr; /* * ButtonDown events will always occur in the front - * window. ButtonUp events, however, may occur anywhere + * window. ButtonUp events, however, may occur anywhere * on the screen. ButtonUp events should only be sent * to Tk if in the front window or during an implicit grab. */ - - where.h = x; - where.v = y; - FindWindow(where, &whichWin); - frontWin = FrontNonFloatingWindow(); - - if (0 && ((frontWin == NULL) || ((!(TkpIsWindowFloating(whichWin)) - && (frontWin != whichWin)) - && TkMacOSXGetCapture() == NULL))) { - return false; + if (0 + && ((medPtr->activeNonFloating == NULL) + || ((!(TkpIsWindowFloating(medPtr->whichWin)) + && (medPtr->activeNonFloating != medPtr->whichWin)) + && TkMacOSXGetCapture() == NULL))) { + return false; } dispPtr = TkGetDisplayList(); - tkwin = Tk_IdToWindow(dispPtr->display, window); + tkwin = Tk_IdToWindow(dispPtr->display, medPtr->window); - /* SetPortWindowPort(ActiveNonFloatingWindow()); */ - SetPortWindowPort(whichWin); - GlobalToLocal(&where); if (tkwin != NULL) { - tkwin = Tk_TopCoordsToWindow(tkwin, where.h, where.v, - &dummy, &dummy); + tkwin = Tk_TopCoordsToWindow(tkwin, medPtr->local.h, medPtr->local.v, + &dummy, &dummy); } - Tk_UpdatePointer(tkwin, x, y, state); + Tk_UpdatePointer(tkwin, medPtr->global.h, medPtr->global.v, medPtr->state); return true; } @@ -830,7 +861,7 @@ TkGenerateButtonEvent( /* *---------------------------------------------------------------------- * - * TkMacOSXToolarbuttonEvent -- + * GenerateToolbarButtonEvent -- * * Generates a "ToolbarButton" virtual event. * This can be used to manage disappearing toolbars. @@ -845,23 +876,18 @@ TkGenerateButtonEvent( */ static int -TkMacOSXToolarbuttonEvent(MouseEventData * medPtr, Point where) +GenerateToolbarButtonEvent(MouseEventData * medPtr) { Tk_Window rootwin, tkwin = NULL; - Window window; TkDisplay *dispPtr; TkWindow *winPtr; XVirtualEvent event; - CGrafPtr port; - Rect bounds; - window = TkMacOSXGetXWindow(medPtr->whichWin); dispPtr = TkGetDisplayList(); - rootwin = Tk_IdToWindow(dispPtr->display, window); + rootwin = Tk_IdToWindow(dispPtr->display, medPtr->window); if (rootwin) { - int local_x, local_y; tkwin = Tk_TopCoordsToWindow(rootwin, - medPtr->local.h, medPtr->local.v, &local_x, &local_y); + medPtr->local.h, medPtr->local.v, &event.x, &event.y); } if (!tkwin) { return true; @@ -877,14 +903,8 @@ TkMacOSXToolarbuttonEvent(MouseEventData * medPtr, Point where) event.subwindow = None; event.time = TkpGetMS(); - event.x = where.h; - event.y = where.v; - - GetMouse(&where); - GetPort(&port); - GetPortBounds(port, &bounds); - event.x_root = where.h + bounds.left; - event.y_root = where.v + bounds.top; + event.x_root = medPtr->global.h; + event.y_root = medPtr->global.v; event.state = medPtr->state; event.same_screen = true; event.name = Tk_GetUid("ToolbarButton"); |