diff options
author | das <das> | 2005-08-09 07:39:48 (GMT) |
---|---|---|
committer | das <das> | 2005-08-09 07:39:48 (GMT) |
commit | b8c4ee9a5df85da2ac51dfea85177ffa458c2a50 (patch) | |
tree | b77a27b7d580d802ccbfcb5442bba1206c3ff248 /macosx/tkMacOSXMouseEvent.c | |
parent | ce8d7d22d0f5eb10e00df422dffb587c95481678 (diff) | |
download | tk-b8c4ee9a5df85da2ac51dfea85177ffa458c2a50.zip tk-b8c4ee9a5df85da2ac51dfea85177ffa458c2a50.tar.gz tk-b8c4ee9a5df85da2ac51dfea85177ffa458c2a50.tar.bz2 |
* macosx/tkMacOSXCarbonEvents.c (new): moved carbon events code into
* macosx/tkMacOSXHLEvents.c: new file like on HEAD,
* macosx/tkMacOSXInit.c (TkpInit): initialize carbon event handlers
* macosx/tkMacOSXInt.h: in TkpInit(), add new source
* unix/Makefile.in: file to Makefile.in.
* macosx/tkMacOSXCarbonEvents.c (AppEventHandlerProc): handle carbon
events sent directly to application event target via the general
TkMacOSXProcessEvent() in the same way as events posted to the event
loop. Moved existing app event handlers to tkMacOSXWindowEvent.c.
(TkMacOSXInitCarbonEvents): register our application event handler for
kEventWindowExpanded events to deal with uncollapsing from the dock.
* macosx/tkMacOSXEvent.h: made TkMacOSXProcessEvent() non-static, added
* macosx/tkMacOSXEvent.c: new interp field to TkMacOSXEvent struct for
use by app event handler.
* macosx/tkMacOSXMouseEvent.c (TkMacOSXProcessMouseEvent): retrieve
current window, partCode, modifiers and local cursor position from
carbon mouse event if possible. Use new static GenerateButtonEvent()
taking a MouseEventData struct instead of TkGenerateButtonEvent() to
avoid recomputing already known values. Move process activation on
MouseDown into BringWindowForward() to allow clicking on window titlebar
widgets without activating process. Move code dealing with clicks in
window titelbar into separate function HandleWindowTitlebarMouseDown()
to avoid code duplication. Avoid repeated calls to TkMacOSXGetXWindow()
by storing result in MouseEventData struct.
(TkMacOSXButtonKeyState, XQueryPointer): try to get button and modifier
state from currently processed carbon event (to avoid unnecessary IPC
with the window server), otherwise use modern carbon API to get this
info instead of Button() and GetKeys(); only retrieve info caller asks
for (via non-NULL ptr passed to XQueryPointer).
(ButtonModifiers2State): new static function converting carbon button
and modifier state into tk state, allows detection of more than 3 mouse
buttons (tk supports up to 5) and of NumLock and Fn modifier keys
(NumLock is mapped to Mod3 and Fn to Mod4).
* macosx/tkMacOSXWindowEvent.c (TkMacOSXProcessApplicationEvent): handle
kEventWindowExpanded event to deal with window uncollapsing from the
dock by generating tk Map event, handle kEventAppHidden and
kEventAppShown events (moved here from tkMacOSXCarbonEvents.c).
* macosx/tkMacOSXSubwindows.c (XUnmapWindow): only hide window when
it is not iconified to avoid window flashing on collapse.
* macosx/tkMacOSXWm.c: replaced Tk_DoWhenIdle() by Tcl_DoWhenIdle().
(TkMacOSXZoomToplevel): remove call to TrackBox(), now done in
HandleWindowTitlebarMouseDown() in tkMacOSXMouseEvent.c.
(TkpWmSetState): avoid window flashing on collapse by unmapping after
calling CollapseWindow(); only uncollapse window if it is collapsed.
* generic/tkInt.decls: changed TkMacOSXZoomToplevel() signature.
* generic/tkIntPlatDecls.h:
* macosx/tkMacOSXKeyEvent.c (TkMacOSXProcessKeyboardEvent): only call
GetMenuItemCommandID() on KeyDown or KeyRepeat events.
* macosx/tkMacOSXMenu.c (ReconfigureMacintoshMenu): remove call to
obsolete AppendResMenu() API.
* macosx/tkMacOSXKeyEvent.c: replaced all direct uses of expensive
* macosx/tkMacOSXMenu.c: GetMouse() and TkMacOSXButtonKeyState()
* macosx/tkMacOSXMenus.c: APIs by calls to XQueryPointer()
* macosx/tkMacOSXMouseEvent.c:
* macosx/tkMacOSXScale.c:
* macosx/tkMacOSXScrlbr.c:
* macosx/tkMacOSXWm.c:
* macosx/tkMacOSXDialog.c: replaced use of FrontNonFloatingWindow()
* macosx/tkMacOSXKeyEvent.c: by ActiveNonFloatingWindow() as
* macosx/tkMacOSXMenu.c: recommended by Carbon docs.
* macosx/tkMacOSXMenus.c:
* macosx/tkMacOSXSubwindows.c:
* macosx/tkMacOSXWm.c:
* macosx/tkMacOSXDialog.c: fixed warnings
* macosx/tkMacOSXTest.c:
* macosx/tkMacOSXCarbonEvents.c: added CVS Id line to file header.
* macosx/tkMacOSXDebug.c:
* macosx/tkMacOSXDebug.h:
* macosx/tkMacOSXEntry.c:
* macosx/tkMacOSXEvent.h:
* macosx/tkMacOSXKeyEvent.c:
* macosx/tkMacOSXMouseEvent.c:
* macosx/tkMacOSXWindowEvent.c:
* macosx/tkMacOSXWm.h:
* macosx/tkMacOSXEmbed.c: replaced all uses of panic() with Tcl_Panic()
* macosx/tkMacOSXFont.c: (sync with HEAD).
* macosx/tkMacOSXMenus.c:
* macosx/tkMacOSXSubwindows.c:
* macosx/tkMacOSXWm.c:
* macosx/tkMacOSXXStubs.c:
* macosx/tkMacOSXInt.h: sync with HEAD changes of 2005-03-14.
* macosx/tkMacOSXSubwindows.c:
* macosx/tclets.r (removed): sync with HEAD.
* macosx/tkMacOSXScale.c:
* macosx/tkMacOSXPort.h:
* library/demos/menu.tcl: removed errant '}'.
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"); |