summaryrefslogtreecommitdiffstats
path: root/macosx/tkMacOSXMouseEvent.c
diff options
context:
space:
mode:
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;
}