summaryrefslogtreecommitdiffstats
path: root/macosx/tkMacOSXMouseEvent.c
diff options
context:
space:
mode:
authordas <das>2005-08-09 07:39:17 (GMT)
committerdas <das>2005-08-09 07:39:17 (GMT)
commit98ee99c4ea859910fb13d480bfb6d70fe49fc7ab (patch)
tree11ef5d94364dc21d07c4385f19dd7d1f05b2e847 /macosx/tkMacOSXMouseEvent.c
parenta33da75b8587cfad8d92ba670a716663fc557192 (diff)
downloadtk-98ee99c4ea859910fb13d480bfb6d70fe49fc7ab.zip
tk-98ee99c4ea859910fb13d480bfb6d70fe49fc7ab.tar.gz
tk-98ee99c4ea859910fb13d480bfb6d70fe49fc7ab.tar.bz2
* 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/tkMacOSXInt.h: declare macosx internal procs as MODULE_SCOPE. * macosx/tkMacOSXCarbonEvents.c: * macosx/tkMacOSXDraw.c: * macosx/tkMacOSXFont.c: * macosx/tkMacOSXHLEvents.c: * macosx/tkMacOSXInit.c: * macosx/tkMacOSXWindowEvent.c * library/bgerror.tcl: sync with core-8-4-branch changes of 2005-07-28. * macosx/tkMacOSXDraw.c: * macosx/tkMacOSXWm.c: * macosx/tkMacOSXMouseEvent.c: * generic/tkFrame.c: sync with core-8-4-branch changes of 2005-07-27. * generic/tkIntDecls.h: * generic/tkStubInit.c: * generic/tkFrame.c: * win/tkWinDraw.c: * unix/tkUnixDraw.c: * macosx/tkMacOSXDraw.c: * macosx/tkMacOSXInt.h: * macosx/tkMacOSXWm.c: * macosx/tkMacOSXSubwindows.c: * macosx/tkMacOSXButton.c: sync with core-8-4-branch. * macosx/tkMacOSXEntry.c: * macosx/tkMacOSXScale.c: * library/demos/menu.tcl: removed errant '}'.
Diffstat (limited to 'macosx/tkMacOSXMouseEvent.c')
-rw-r--r--macosx/tkMacOSXMouseEvent.c1053
1 files changed, 564 insertions, 489 deletions
diff --git a/macosx/tkMacOSXMouseEvent.c b/macosx/tkMacOSXMouseEvent.c
index 0346fbf..163e232 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.13 2005/08/09 07:39:21 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 OSErr HandleInCollapse(WindowRef win);
+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,93 +98,88 @@ 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.
*
*----------------------------------------------------------------------
*/
-
+
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,314 +189,232 @@ 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);
-
- 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 {
- return GeneratePollingEvents(medPtr);
- }
- }
-
- 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;
- }
- }
- }
+ dispPtr = TkGetDisplayList();
+ tkwin = Tk_IdToWindow(dispPtr->display, medPtr->window);
+
+ if (eventPtr->eKind != kEventMouseDown) {
+ /*
+ * MouseMoved, MouseDragged or kEventMouseWheelMoved
+ */
+
+ if (eventPtr->eKind == kEventMouseWheelMoved) {
+ return GenerateMouseWheelEvent(medPtr);
+ } else {
+ return GeneratePollingEvents(medPtr);
+ }
}
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
- * 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();
- if ((grabWin == NULL)) {
- int grabState = TkGrabState((TkWindow*)tkwin);
- if (grabState != TK_GRAB_NONE && grabState != TK_GRAB_IN_TREE) {
- /* Now we want to set the focus to the local grabWin */
- TkMacOSXSetEatButtonUp(true);
- grabWin = (Tk_Window) (((TkWindow*)tkwin)->dispPtr->grabWinPtr);
- BringWindowForward(GetWindowFromPort(TkMacOSXGetDrawablePort(((TkWindow*)grabWin)->window)));
- statusPtr->stopProcessing = 1;
- return false;
- }
- }
- if ((grabWin != NULL) && (grabWin != tkwin)) {
- TkWindow * tkw, * grb;
- tkw = (TkWindow *)tkwin;
- grb = (TkWindow *)grabWin;
- /* Now we want to set the focus to the global grabWin */
- TkMacOSXSetEatButtonUp(true);
- BringWindowForward(GetWindowFromPort(TkMacOSXGetDrawablePort(((TkWindow*)grabWin)->window)));
- statusPtr->stopProcessing = 1;
- return false;
- }
-
- /*
- * 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:
- err = HandleInCollapse(medPtr->whichWin);
- if (err == noErr) {
- statusPtr->err = 1;
- }
- statusPtr->stopProcessing = 1;
- return false;
- break;
- case inZoomIn:
- return false;
- break;
- case inZoomOut:
- return false;
- break;
- default:
- TkMacOSXSetEatButtonUp(true);
- BringWindowForward(medPtr->whichWin);
- return false;
- }
- }
- }
-
- switch (medPtr->windowPart) {
- case inDrag:
- {
- CGrafPtr saveWorld;
- GDHandle saveDevice;
- GWorldPtr dstPort;
-
- GetGWorld(&saveWorld, &saveDevice);
- dstPort = TkMacOSXGetDrawablePort(Tk_WindowId(tkwin));
- SetGWorld(dstPort, NULL);
-
- DragWindow(medPtr->whichWin, where, NULL);
- where2.h = where2.v = 0;
- LocalToGlobal(&where2);
- if (EqualPt(where, where2)) {
- SetGWorld (saveWorld, saveDevice);
- return false;
- }
- TkMacOSXWindowOffset(medPtr->whichWin, &xOffset, &yOffset);
- where2.h -= xOffset;
- where2.v -= yOffset;
- TkGenWMConfigureEvent(tkwin, where2.h, where2.v,
- -1, -1, TK_LOCATION_CHANGED);
- SetGWorld(saveWorld, saveDevice);
- return true;
- break;
- }
- case inContent:
- return TkGenerateButtonEvent(where.h, where.v,
- window, medPtr->state);
- break;
- case inGrow:
- /*
- * Generally the content region is the domain of Tk
- * sub-windows. However, one exception is the grow
- * region. A button down in this area will be handled
- * by the window manager. Note: this means that Tk
- * may not get button down events in this area!
- */
- if (TkMacOSXGrowToplevel(medPtr->whichWin, where) == true) {
- return true;
- } else {
- return TkGenerateButtonEvent(where.h,
- where.v, window, medPtr->state);
- }
- 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();
-
- /*
- * Handle -postcommand
- */
-
- TkMacOSXPreprocessMenu();
- TkMacOSXHandleMenuSelect(MenuSelect(where),
- EndianS32_BtoN(*(long*)(&theKeys[1])) & 4);
- 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;
+ /*
+ * 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
+ * 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();
+ if ((grabWin == NULL)) {
+ int grabState = TkGrabState((TkWindow*)tkwin);
+ if (grabState != TK_GRAB_NONE && grabState != TK_GRAB_IN_TREE) {
+ /* Now we want to set the focus to the local grabWin */
+ TkMacOSXSetEatButtonUp(true);
+ grabWin = (Tk_Window) (((TkWindow*)tkwin)->dispPtr->grabWinPtr);
+ BringWindowForward(GetWindowFromPort(TkMacOSXGetDrawablePort(((TkWindow*)grabWin)->window)));
+ statusPtr->stopProcessing = 1;
+ return false;
+ }
+ }
+ if ((grabWin != NULL) && (grabWin != tkwin)) {
+ TkWindow * tkw, * grb;
+ tkw = (TkWindow *)tkwin;
+ grb = (TkWindow *)grabWin;
+ /* Now we want to set the focus to the global grabWin */
+ TkMacOSXSetEatButtonUp(true);
+ BringWindowForward(GetWindowFromPort(TkMacOSXGetDrawablePort(((TkWindow*)grabWin)->window)));
+ statusPtr->stopProcessing = 1;
+ return false;
+ }
+
+ /*
+ * Clicks in the stoplights on a MacOS X title bar are processed
+ * directly even for background windows. Do that here.
+ */
+ if ((result = HandleWindowTitlebarMouseDown(medPtr, tkwin)) != -1) {
+ return result;
} else {
+ TkMacOSXSetEatButtonUp(true);
+ BringWindowForward(medPtr->whichWin);
return false;
}
- break;
- case inCollapseBox:
- err = HandleInCollapse(medPtr->whichWin);
- if (err == noErr) {
- statusPtr->err = 1;
- }
- statusPtr->stopProcessing = 1;
- break;
- default:
- return false;
- break;
+ }
+ }
+
+
+ if ((result = HandleWindowTitlebarMouseDown(medPtr, tkwin)) != -1) {
+ return result;
+ }
+ switch (medPtr->windowPart) {
+ case inDrag: {
+ CGrafPtr saveWorld;
+ GDHandle saveDevice;
+ GWorldPtr dstPort;
+
+ GetGWorld(&saveWorld, &saveDevice);
+ dstPort = TkMacOSXGetDrawablePort(Tk_WindowId(tkwin));
+ SetGWorld(dstPort, NULL);
+
+ DragWindow(medPtr->whichWin, where, NULL);
+ where2.h = where2.v = 0;
+ LocalToGlobal(&where2);
+ if (EqualPt(where, where2)) {
+ SetGWorld (saveWorld, saveDevice);
+ return false;
+ }
+ TkMacOSXWindowOffset(medPtr->whichWin, &xOffset, &yOffset);
+ where2.h -= xOffset;
+ where2.v -= yOffset;
+ TkGenWMConfigureEvent(tkwin, where2.h, where2.v,
+ -1, -1, TK_LOCATION_CHANGED);
+ SetGWorld(saveWorld, saveDevice);
+ return true;
+ break;
+ }
+ case inContent:
+ return GenerateButtonEvent(medPtr);
+ break;
+ case inGrow:
+ /*
+ * Generally the content region is the domain of Tk
+ * sub-windows. However, one exception is the grow
+ * region. A button down in this area will be handled
+ * by the window manager. Note: this means that Tk
+ * may not get button down events in this area!
+ */
+ if (TkMacOSXGrowToplevel(medPtr->whichWin, where) == true) {
+ return true;
+ } else {
+ return GenerateButtonEvent(medPtr);
+ }
+ break;
+ case inMenuBar: {
+ int oldMode;
+
+ oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL);
+ TkMacOSXClearMenubarActive();
+
+ /*
+ * Handle -postcommand
+ */
+
+ TkMacOSXPreprocessMenu();
+ TkMacOSXHandleMenuSelect(MenuSelect(where),
+ medPtr->state & Mod2Mask);
+ Tcl_SetServiceMode(oldMode);
+ return true; /* TODO: may not be on event on queue. */
+ break;
+ }
+ default:
+ return false;
+ break;
}
return 0;
}
-
+
/*
*----------------------------------------------------------------------
*
- * 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)
-{
- if (TrackGoAway(win, where)) {
- if (tkwin == NULL) {
- return false;
- }
- TkGenWMDestroyEvent(tkwin);
- return true;
- }
- return false;
-}
-/*
- *----------------------------------------------------------------------
- *
- * HandleInCollapse --
- *
- * Tracks the cursor in the collapse box and colapses the window
- * if the button stays depressed on button up.
- *
- * Results:
- * Error return from CollapseWindow
- *
- * Side effects:
- * The window win may be collapsed.
- *
- *----------------------------------------------------------------------
- */
-OSErr
-HandleInCollapse(WindowRef win)
+int
+HandleWindowTitlebarMouseDown(MouseEventData * medPtr, Tk_Window tkwin)
{
- OSErr err;
+ int result = 0;
- err = CollapseWindow(win,
- !IsWindowCollapsed(win));
- if (err != noErr) {
- fprintf(stderr,"CollapseWindow failed,%d\n", err);
+ 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 err;
-}
+ return result;
+}
+
/*
*----------------------------------------------------------------------
*
* 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.
*
*----------------------------------------------------------------------
*/
@@ -505,7 +423,6 @@ static int
GeneratePollingEvents(MouseEventData * medPtr)
{
Tk_Window tkwin, rootwin, grabWin;
- Window window;
int local_x, local_y;
TkDisplay *dispPtr;
@@ -513,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);
+ }
}
/*
@@ -549,62 +465,100 @@ GeneratePollingEvents(MouseEventData * medPtr)
*/
Tk_UpdatePointer(tkwin, medPtr->global.h, medPtr->global.v,
- medPtr->state);
+ medPtr->state);
return true;
}
-
-/*
+/*
*----------------------------------------------------------------------
*
* 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.
+ *
*----------------------------------------------------------------------
- */
-
-static void
+ */
+
+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))
- SelectWindow(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);
+ }
}
/*
@@ -615,12 +569,12 @@ GenerateMouseWheelEvent(MouseEventData * medPtr)
grabWin = TkMacOSXGetCapture();
if ((tkwin == NULL) && (grabWin != NULL)) {
- tkwin = grabWin;
+ tkwin = grabWin;
}
if (!tkwin) {
return true;
}
- winPtr = ( TkWindow *)tkwin;
+ winPtr = (TkWindow *) tkwin;
xEvent.type = MouseWheelEvent;
xEvent.xkey.keycode = medPtr->delta;
xEvent.xbutton.state = TkMacOSXButtonKeyState();
@@ -632,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.
*
*----------------------------------------------------------------------
*/
@@ -654,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.
*
*----------------------------------------------------------------------
*/
@@ -691,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;
@@ -731,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.
*
*----------------------------------------------------------------------
*/
@@ -757,83 +740,175 @@ XQueryPointer(
int* win_y_return,
unsigned int* mask_return)
{
- Point where;
- CGrafPtr port;
- GDHandle dev;
-
- GetGWorld(&port,&dev);
- GetMouse(&where);
- LocalToGlobal(&where);
-
- *root_x_return = where.h;
- *root_y_return = where.v;
- *mask_return = TkMacOSXButtonKeyState();
+ 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;
+ }
+ 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);
-
- /* SetPortWindowPort(ActiveNonFloatingWindow()); */
- SetPortWindowPort(whichWin);
- GlobalToLocal(&where);
+ tkwin = Tk_IdToWindow(dispPtr->display, medPtr->window);
+
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, medPtr->global.h, medPtr->global.v, medPtr->state);
+
+ return true;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GenerateToolbarButtonEvent --
+ *
+ * Generates a "ToolbarButton" virtual event.
+ * This can be used to manage disappearing toolbars.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Places a virtual event on the event queue.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+GenerateToolbarButtonEvent(MouseEventData * medPtr)
+{
+ Tk_Window rootwin, tkwin = NULL;
+ TkDisplay *dispPtr;
+ TkWindow *winPtr;
+ XVirtualEvent event;
+
+ dispPtr = TkGetDisplayList();
+ rootwin = Tk_IdToWindow(dispPtr->display, medPtr->window);
+ if (rootwin) {
+ tkwin = Tk_TopCoordsToWindow(rootwin,
+ medPtr->local.h, medPtr->local.v, &event.x, &event.y);
+ }
+ if (!tkwin) {
+ return true;
}
- Tk_UpdatePointer(tkwin, x, y, state);
+ winPtr = (TkWindow *)tkwin;
+ event.type = VirtualEvent;
+ event.serial = LastKnownRequestProcessed(winPtr->display);
+ event.send_event = false;
+ event.display = winPtr->display;
+ event.event = winPtr->window;
+ event.root = XRootWindow(winPtr->display, 0);
+ event.subwindow = None;
+ event.time = TkpGetMS();
+
+ 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");
+ Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL);
return true;
}