Beispiel #1
0
static void
DisplaySetupProc(
    ClientData clientData,	/* Not used. */
    int flags)
{
    TkDisplay *dispPtr;
    static Tcl_Time blockTime = { 0, 0 };

    if (!(flags & TCL_WINDOW_EVENTS)) {
	return;
    }

    for (dispPtr = TkGetDisplayList(); dispPtr != NULL;
	    dispPtr = dispPtr->nextPtr) {
	/*
	 * Flush the display. If data is pending on the X queue, set the block
	 * time to zero. This ensures that we won't block in the notifier if
	 * there is data in the X queue, but not on the server socket.
	 */

	XFlush(dispPtr->display);
	if (QLength(dispPtr->display) > 0) {
	    Tcl_SetMaxBlockTime(&blockTime);
	}
    }
}
Beispiel #2
0
static int
GenerateButtonEvent(MouseEventData * medPtr)
{
    Tk_Window tkwin;
    int dummy;
    TkDisplay *dispPtr;

#if UNUSED
    /*
     * ButtonDown events will always occur in the front
     * 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.
     */
    if ((medPtr->activeNonFloating == NULL)
	    || ((!(TkpIsWindowFloating(medPtr->whichWin))
	    && (medPtr->activeNonFloating != medPtr->whichWin))
	    && TkMacOSXGetCapture() == NULL)) {
	return false;
    }
#endif

    dispPtr = TkGetDisplayList();
    tkwin = Tk_IdToWindow(dispPtr->display, medPtr->window);

    if (tkwin != NULL) {
	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;
}
Beispiel #3
0
static void 
GenerateEditEvent(
    int flag)
{
    XVirtualEvent event;
    Point where;
    Tk_Window tkwin;
    Window window;
    TkDisplay *dispPtr;

    if (TkMacHaveAppearance() >= 0x110) {
        window = TkMacGetXWindow(FrontNonFloatingWindow());
    } else {
        window = TkMacGetXWindow(FrontWindow());
    }
    dispPtr = TkGetDisplayList();
    tkwin = Tk_IdToWindow(dispPtr->display, window);
    tkwin = (Tk_Window) ((TkWindow *) tkwin)->dispPtr->focusPtr;
    if (tkwin == NULL) {
	return;
    }

    event.type = VirtualEvent;
    event.serial = Tk_Display(tkwin)->request;
    event.send_event = false;
    event.display = Tk_Display(tkwin);
    event.event = Tk_WindowId(tkwin);
    event.root = XRootWindow(Tk_Display(tkwin), 0);
    event.subwindow = None;
    event.time = TkpGetMS();
    
    GetMouse(&where);
    tkwin = Tk_TopCoordsToWindow(tkwin, where.h, where.v, 
	    &event.x, &event.y);
    LocalToGlobal(&where);
    event.x_root = where.h;
    event.y_root = where.v;
    event.state = TkMacButtonKeyState();
    event.same_screen = true;
    
    switch (flag) {
	case EDIT_CUT:
	    event.name = Tk_GetUid("Cut");
	    break;
	    
	case EDIT_COPY:
	    event.name = Tk_GetUid("Copy");
	    break;
	    
	case EDIT_PASTE:
	    event.name = Tk_GetUid("Paste");
	    break;
	    
	case EDIT_CLEAR:
	    event.name = Tk_GetUid("Clear");
	    break;
    }
    Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL);
}
Beispiel #4
0
static int
GeneratePollingEvents(MouseEventData * medPtr)
{
    Tk_Window tkwin, rootwin, grabWin;
    int local_x, local_y;
    TkDisplay *dispPtr;


    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;
    } 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.
	 */

	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);
	}
    }

    /*
     * The following call will generate the appropiate X events and
     * adjust any state that Tk must remember.
     */

    Tk_UpdatePointer(tkwin, medPtr->global.h, medPtr->global.v,
	    medPtr->state);

    return true;
}
Beispiel #5
0
void
TkMacOSXBringWindowForward(
    WindowRef wRef)
{
    TkDisplay *dispPtr = TkGetDisplayList();
    Tk_Window tkwin = Tk_IdToWindow(dispPtr->display,TkMacOSXGetXWindow(wRef));
    Tk_Window grabWin = GetGrabWindowForWindow(tkwin);

    if (grabWin && grabWin != tkwin) {
	wRef = TkMacOSXDrawableWindow(((TkWindow*)grabWin)->window);
    }
    TkMacOSXSetEatButtonUp(true);
    BringWindowForward(wRef, Tk_MacOSXIsAppInFront(), !grabWin);
}
Beispiel #6
0
static void
GenerateEditEvent(
    int flag)
{
    XVirtualEvent event;
    int x, y;
    Tk_Window tkwin;
    Window window;
    TkDisplay *dispPtr;

    window = TkMacOSXGetXWindow(ActiveNonFloatingWindow());
    dispPtr = TkGetDisplayList();
    tkwin = Tk_IdToWindow(dispPtr->display, window);
    tkwin = (Tk_Window) ((TkWindow *) tkwin)->dispPtr->focusPtr;
    if (tkwin == NULL) {
	return;
    }

    bzero(&event, sizeof(XVirtualEvent));
    event.type = VirtualEvent;
    event.serial = Tk_Display(tkwin)->request;
    event.send_event = false;
    event.display = Tk_Display(tkwin);
    event.event = Tk_WindowId(tkwin);
    event.root = XRootWindow(Tk_Display(tkwin), 0);
    event.subwindow = None;
    event.time = TkpGetMS();

    XQueryPointer(NULL, None, NULL, NULL,
	    &event.x_root, &event.y_root, &x, &y, &event.state);
    Tk_TopCoordsToWindow(tkwin, x, y, &event.x, &event.y);
    event.same_screen = true;

    switch (flag) {
    case EDIT_CUT:
	event.name = Tk_GetUid("Cut");
	break;
    case EDIT_COPY:
	event.name = Tk_GetUid("Copy");
	break;
    case EDIT_PASTE:
	event.name = Tk_GetUid("Paste");
	break;
    case EDIT_CLEAR:
	event.name = Tk_GetUid("Clear");
	break;
    }
    Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL);
}
Beispiel #7
0
static void
BringWindowForward(
    WindowRef wRef,
    int isFrontProcess,
    int frontWindowOnly)
{
    if (wRef && !TkpIsWindowFloating(wRef) && IsValidWindowPtr(wRef)) {
	WindowRef frontWindow = FrontNonFloatingWindow();
	WindowModality frontWindowModality = kWindowModalityNone;
	
	if (frontWindow && frontWindow != wRef) {
	    ChkErr(GetWindowModality, frontWindow, &frontWindowModality, NULL);
	}
	if (frontWindowModality != kWindowModalityAppModal) {
	    Window window = TkMacOSXGetXWindow(wRef);

	    if (window != None) {
		TkDisplay *dispPtr = TkGetDisplayList();
		TkWindow * winPtr = (TkWindow *)Tk_IdToWindow(dispPtr->display,
			window);

		if (winPtr && winPtr->wmInfoPtr &&
			winPtr->wmInfoPtr->master != None) {
		    TkWindow *masterWinPtr = (TkWindow *)Tk_IdToWindow(
			    dispPtr->display, winPtr->wmInfoPtr->master);

		    if (masterWinPtr && masterWinPtr->window != None &&
			    TkMacOSXHostToplevelExists(masterWinPtr)) {
			WindowRef masterMacWin =
				TkMacOSXDrawableWindow(masterWinPtr->window);

			if (masterMacWin) {
			    BringToFront(masterMacWin);
			}
		    }
		}
	    }
	    SelectWindow(wRef);
	} else {
	    frontWindowOnly = 0;
	}
    }
    if (!isFrontProcess) {
	ProcessSerialNumber ourPsn = {0, kCurrentProcess};

	ChkErr(SetFrontProcessWithOptions, &ourPsn, frontWindowOnly ?
	    kSetFrontProcessFrontWindowOnly : 0);
    }
}
Beispiel #8
0
static void
DisplayCheckProc(
    ClientData clientData,	/* Not used. */
    int flags)
{
    TkDisplay *dispPtr;

    if (!(flags & TCL_WINDOW_EVENTS)) {
	return;
    }

    for (dispPtr = TkGetDisplayList(); dispPtr != NULL;
	    dispPtr = dispPtr->nextPtr) {
	XFlush(dispPtr->display);
	TransferXEventsToTcl(dispPtr->display);
    }
}
Beispiel #9
0
static int
GenerateMouseWheelEvent(MouseEventData * medPtr)
{
    Tk_Window tkwin, rootwin;
    TkDisplay *dispPtr;
    TkWindow  *winPtr;
    XEvent xEvent;

    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,
		&xEvent.xbutton.x, &xEvent.xbutton.y);
    }

    /*
     * The following call will generate the appropiate X events and
     * adjust any state that Tk must remember.
     */

    if (!tkwin) {
	tkwin = TkMacOSXGetCapture();
    }
    if (!tkwin) {
	return false;
    }
    winPtr = (TkWindow *) tkwin;
    xEvent.type = MouseWheelEvent;
    xEvent.xkey.keycode = medPtr->delta;
    xEvent.xbutton.x_root = medPtr->global.h;
    xEvent.xbutton.y_root = medPtr->global.v;
    xEvent.xbutton.state = medPtr->state;
    xEvent.xany.serial = LastKnownRequestProcessed(winPtr->display);
    xEvent.xany.send_event = false;
    xEvent.xany.display = winPtr->display;
    xEvent.xany.window = Tk_WindowId(winPtr);
    Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);

    return true;
}
Beispiel #10
0
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;
    }
    winPtr = (TkWindow *) tkwin;

    bzero(&event, sizeof(XVirtualEvent));
    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;
}
Beispiel #11
0
int
TkUnixDoOneXEvent(
    Tcl_Time *timePtr)		/* Specifies the absolute time when the call
				 * should time out. */
{
    TkDisplay *dispPtr;
    static fd_mask readMask[MASK_SIZE];
    struct timeval blockTime, *timeoutPtr;
    Tcl_Time now;
    int fd, index, numFound, numFdBits = 0;
    fd_mask bit, *readMaskPtr = readMask;

    /*
     * Look for queued events first.
     */

    if (Tcl_ServiceEvent(TCL_WINDOW_EVENTS)) {
	return 1;
    }

    /*
     * Compute the next block time and check to see if we have timed out. Note
     * that HP-UX defines tv_sec to be unsigned so we have to be careful in
     * our arithmetic.
     */

    if (timePtr) {
	Tcl_GetTime(&now);
	blockTime.tv_sec = timePtr->sec;
	blockTime.tv_usec = timePtr->usec - now.usec;
	if (blockTime.tv_usec < 0) {
	    now.sec += 1;
	    blockTime.tv_usec += 1000000;
	}
	if (blockTime.tv_sec < now.sec) {
	    blockTime.tv_sec = 0;
	    blockTime.tv_usec = 0;
	} else {
	    blockTime.tv_sec -= now.sec;
	}
	timeoutPtr = &blockTime;
    } else {
	timeoutPtr = NULL;
    }

    /*
     * Set up the select mask for all of the displays. If a display has data
     * pending, then we want to poll instead of blocking.
     */

    memset(readMask, 0, MASK_SIZE*sizeof(fd_mask));
    for (dispPtr = TkGetDisplayList(); dispPtr != NULL;
	    dispPtr = dispPtr->nextPtr) {
	XFlush(dispPtr->display);
	if (QLength(dispPtr->display) > 0) {
	    blockTime.tv_sec = 0;
	    blockTime.tv_usec = 0;
	}
	fd = ConnectionNumber(dispPtr->display);
	index = fd/(NBBY*sizeof(fd_mask));
	bit = ((fd_mask)1) << (fd%(NBBY*sizeof(fd_mask)));
	readMask[index] |= bit;
	if (numFdBits <= fd) {
	    numFdBits = fd+1;
	}
    }

    numFound = select(numFdBits, (SELECT_MASK *) readMaskPtr, NULL, NULL,
	    timeoutPtr);
    if (numFound <= 0) {
	/*
	 * Some systems don't clear the masks after an error, so we have to do
	 * it here.
	 */

	memset(readMask, 0, MASK_SIZE*sizeof(fd_mask));
    }

    /*
     * Process any new events on the display connections.
     */

    for (dispPtr = TkGetDisplayList(); dispPtr != NULL;
	    dispPtr = dispPtr->nextPtr) {
	fd = ConnectionNumber(dispPtr->display);
	index = fd/(NBBY*sizeof(fd_mask));
	bit = ((fd_mask)1) << (fd%(NBBY*sizeof(fd_mask)));
	if ((readMask[index] & bit) || (QLength(dispPtr->display) > 0)) {
	    DisplayFileProc((ClientData)dispPtr, TCL_READABLE);
	}
    }
    if (Tcl_ServiceEvent(TCL_WINDOW_EVENTS)) {
	return 1;
    }

    /*
     * Check to see if we timed out.
     */

    if (timePtr) {
	Tcl_GetTime(&now);
	if ((now.sec > timePtr->sec) || ((now.sec == timePtr->sec)
		&& (now.usec > timePtr->usec))) {
	    return 0;
	}
    }

    /*
     * We had an event but we did not generate a Tcl event from it. Behave as
     * though we dealt with it. (JYL&SS)
     */

    return 1;
}
Beispiel #12
0
void
TkSuspendClipboard()
{
    TkClipboardTarget *targetPtr;
    TkClipboardBuffer *cbPtr;
    TkDisplay *dispPtr;
    char *buffer, *p, *endPtr, *buffPtr;
    long length;

    dispPtr = TkGetDisplayList();
    if ((dispPtr == NULL) || !dispPtr->clipboardActive) {
	return;
    }

    for (targetPtr = dispPtr->clipTargetPtr; targetPtr != NULL;
	    targetPtr = targetPtr->nextPtr) {
	if (targetPtr->type == XA_STRING)
	    break;
    }
    if (targetPtr != NULL) {
	Tcl_DString encodedText;

	length = 0;
	for (cbPtr = targetPtr->firstBufferPtr; cbPtr != NULL;
		cbPtr = cbPtr->nextPtr) {
	    length += cbPtr->length;
	}

	buffer = ckalloc(length);
	buffPtr = buffer;
	for (cbPtr = targetPtr->firstBufferPtr; cbPtr != NULL;
		cbPtr = cbPtr->nextPtr) {
	    for (p = cbPtr->buffer, endPtr = p + cbPtr->length;
		    p < endPtr; p++) {
		if (*p == '\n') {
		    *buffPtr++ = '\r';
		} else {
		    *buffPtr++ = *p;
		}
	    }
	}

	ZeroScrap();
	Tcl_UtfToExternalDString(NULL, buffer, length, &encodedText);
	PutScrap(Tcl_DStringLength(&encodedText), 'TEXT',
		Tcl_DStringValue(&encodedText));
	Tcl_DStringFree(&encodedText);
	ckfree(buffer);
    }

    /*
     * The system now owns the scrap.  We tell Tk that it has
     * lost the selection so that it will look for it the next time
     * it needs it.  (Window list NULL if quiting.)
     */

    if (TkGetMainInfoList() != NULL) {
	Tk_ClearSelection((Tk_Window) TkGetMainInfoList()->winPtr, 
		Tk_InternAtom((Tk_Window) TkGetMainInfoList()->winPtr,
			"CLIPBOARD"));
    }

    return;
}
Beispiel #13
0
static void
TransferXEventsToTcl(
    Display *display)
{
    union {
	int type;
	XEvent x;
	TkKeyEvent k;
    } event;
    Window w;
    TkDisplay *dispPtr = NULL;

    /*
     * Transfer events from the X event queue to the Tk event queue after XIM
     * event filtering. KeyPress and KeyRelease events need special treatment
     * so that they get directed according to Tk's focus rules during XIM
     * handling. Theoretically they can go to the wrong place still (if
     * there's a focus change in the queue) but if we push the handling off
     * until Tk_HandleEvent then many input methods actually cease to work
     * correctly. Most of the time, Tk processes its event queue fast enough
     * for this to not be an issue anyway. [Bug 1924761]
     */

    while (QLength(display) > 0) {
	XNextEvent(display, &event.x);
	w = None;
	if (event.type == KeyPress || event.type == KeyRelease) {
	    for (dispPtr = TkGetDisplayList(); ; dispPtr = dispPtr->nextPtr) {
		if (dispPtr == NULL) {
		    break;
		} else if (dispPtr->display == event.x.xany.display) {
		    if (dispPtr->focusPtr != NULL) {
			w = dispPtr->focusPtr->window;
		    }
		    break;
		}
	    }
	}
	if (XFilterEvent(&event.x, w)) {
	    continue;
	}
	if (event.type == KeyPress || event.type == KeyRelease) {
	    event.k.charValuePtr = NULL;
	    event.k.charValueLen = 0;
	    event.k.keysym = NoSymbol;

	    /*
	     * Force the calling of the input method engine now. The results
	     * from it will be cached in the event so that they don't get lost
	     * (to a race condition with other XIM-handled key events) between
	     * entering the event queue and getting serviced. [Bug 1924761]
	     */

#ifdef TK_USE_INPUT_METHODS
	    if (event.type == KeyPress && dispPtr &&
		    (dispPtr->flags & TK_DISPLAY_USE_IM)) {
		if (dispPtr->focusPtr && dispPtr->focusPtr->inputContext) {
		    Tcl_DString ds;

		    Tcl_DStringInit(&ds);
		    (void) TkpGetString(dispPtr->focusPtr, &event.x, &ds);
		    Tcl_DStringFree(&ds);
		}
	    }
#endif
	}
	Tk_QueueWindowEvent(&event.x, TCL_QUEUE_TAIL);
    }
}
Beispiel #14
0
void
TkMacOSXHandleMenuSelect(
    MenuID theMenu,
    MenuItemIndex theItem,
    int optionKeyPressed)
{
    Tk_Window tkwin;
    Window window;
    TkDisplay *dispPtr;
    Tcl_CmdInfo dummy;
    int code;

    if (theItem == 0) {
	TkMacOSXClearMenubarActive();
	return;
    }

    switch (theMenu) {
    case kAppleMenu:
	switch (theItem) {
	case kAppleAboutItem:
	    if (optionKeyPressed || gInterp == NULL ||
		Tcl_GetCommandInfo(gInterp, "tkAboutDialog", &dummy) == 0) {
		TkAboutDlg();
	    } else {
		code = Tcl_EvalEx(gInterp, "tkAboutDialog", -1,
			TCL_EVAL_GLOBAL);
		if (code != TCL_OK) {
		    Tcl_BackgroundException(gInterp, code);
		}
		Tcl_ResetResult(gInterp);
	    }
	    break;
	}
	break;
    case kFileMenu:
	switch (theItem) {
	case kSourceItem:
	    if (gInterp) {
		if (Tcl_EvalEx(gInterp, "tk_getOpenFile -filetypes {"
			"{{TCL Scripts} {.tcl} TEXT} {{Text Files} {} TEXT}}",
			-1, TCL_EVAL_GLOBAL) == TCL_OK) {
		    Tcl_Obj *path = Tcl_GetObjResult(gInterp);
		    int len;

		    Tcl_GetStringFromObj(path, &len);
		    if (len) {
			Tcl_IncrRefCount(path);
			code = Tcl_FSEvalFile(gInterp, path);
			if (code != TCL_OK) {
			    Tcl_BackgroundException(gInterp, code);
			}
			Tcl_DecrRefCount(path);
		    }
		}
		Tcl_ResetResult(gInterp);
	    }
	    break;
	case kDemoItem:
	    if (gInterp) {
		Tcl_Obj *path = GetWidgetDemoPath(gInterp);

		if (path) {
		    Tcl_IncrRefCount(path);
		    code = Tcl_FSEvalFile(gInterp, path);
		    if (code != TCL_OK) {
			Tcl_BackgroundException(gInterp, code);
		    }
		    Tcl_DecrRefCount(path);
		    Tcl_ResetResult(gInterp);
		}
	    }
	    break;
	case kCloseItem:
	    /* Send close event */
	    window = TkMacOSXGetXWindow(ActiveNonFloatingWindow());
	    dispPtr = TkGetDisplayList();
	    tkwin = Tk_IdToWindow(dispPtr->display, window);
	    TkGenWMDestroyEvent(tkwin);
	    break;
	}
	break;
    case kEditMenu:
	/*
	 * This implementation just send the keysyms Tk thinks are associated
	 * with function keys that do Cut, Copy & Paste on a Sun keyboard.
	 */

	GenerateEditEvent(theItem);
	break;
    default:
	TkMacOSXDispatchMenuEvent(theMenu, theItem);
	break;
    }

    /*
     * Finally we unhighlight the menu.
     */

    HiliteMenu(0);
}
Beispiel #15
0
	global.y = tkMacOSXZeroScreenHeight - global.y;
    } else { /* local will be in screen coordinates. */
	if (_windowWithMouse ) {
	    win = _windowWithMouse;
	    global = local;
	    local = [nswindow convertPointFromScreen: local];
	    local.y = [win frame].size.height - local.y;
	    global.y = tkMacOSXZeroScreenHeight - global.y;
	} else { /* We have no window. Use the screen???*/
	    local.y = tkMacOSXZeroScreenHeight - local.y;
	    global = local;
	}
    }

    Window window = TkMacOSXGetXWindow(win);
    Tk_Window tkwin = window ? Tk_IdToWindow(TkGetDisplayList()->display,
	    window) : NULL;
    if (!tkwin) {
	tkwin = TkMacOSXGetCapture();
    }
    if (!tkwin) {
	return theEvent; /* Give up.  No window for this event. */
    }

    TkWindow  *winPtr = (TkWindow *) tkwin;
    local.x -= winPtr->wmInfoPtr->xInParent;
    local.y -= winPtr->wmInfoPtr->yInParent;

    int win_x, win_y;
    tkwin = Tk_TopCoordsToWindow(tkwin, local.x, local.y,
		&win_x, &win_y);
Beispiel #16
0
	/* ARGSUSED */
int
Tk_GrabObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    int globalGrab;
    Tk_Window tkwin;
    TkDisplay *dispPtr;
    const char *arg;
    int index;
    int len;
    static const char *const optionStrings[] = {
	"current", "release", "set", "status", NULL
    };
    static const char *const flagStrings[] = {
	"-global", NULL
    };
    enum options {
	GRABCMD_CURRENT, GRABCMD_RELEASE, GRABCMD_SET, GRABCMD_STATUS
    };

    if (objc < 2) {
	/*
	 * Can't use Tcl_WrongNumArgs here because we want the message to
	 * read:
	 * wrong # args: should be "cmd ?-global? window" or "cmd option
	 *    ?arg ...?"
	 * We can fake it with Tcl_WrongNumArgs if we assume the command name
	 * is "grab", but if it has been aliased, the message will be
	 * incorrect.
	 */
	Tcl_ResetResult(interp);
	Tcl_AppendResult(interp, "wrong # args: should be \"",
		Tcl_GetString(objv[0]), " ?-global? window\" or \"",
		Tcl_GetString(objv[0]), " option ?arg ...?\"", NULL);
	return TCL_ERROR;
    }

    /*
     * First check for a window name or "-global" as the first argument.
     */

    arg = Tcl_GetStringFromObj(objv[1], &len);
    if (arg[0] == '.') {
	/* [grab window] */
	if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 1, objv, "?-global? window");
	    return TCL_ERROR;
	}
	tkwin = Tk_NameToWindow(interp, arg, clientData);
	if (tkwin == NULL) {
	    return TCL_ERROR;
	}
	return Tk_Grab(interp, tkwin, 0);
    } else if (arg[0] == '-' && len > 1) {
	if (Tcl_GetIndexFromObj(interp, objv[1], flagStrings, "option", 0,
		&index) != TCL_OK) {
	    return TCL_ERROR;
	}

	/* [grab -global window] */
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 1, objv, "?-global? window");
	    return TCL_ERROR;
	}
	tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), clientData);
	if (tkwin == NULL) {
	    return TCL_ERROR;
	}
	return Tk_Grab(interp, tkwin, 1);
    }

    /*
     * First argument is not a window name and not "-global", find out which
     * option it is.
     */

    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
	    &index) != TCL_OK) {
	return TCL_ERROR;
    }

    switch ((enum options) index) {
    case GRABCMD_CURRENT:
	/* [grab current ?window?] */
	if (objc > 3) {
	    Tcl_WrongNumArgs(interp, 1, objv, "current ?window?");
	    return TCL_ERROR;
	}
	if (objc == 3) {
	    tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[2]),
		    clientData);
	    if (tkwin == NULL) {
		return TCL_ERROR;
	    }
	    dispPtr = ((TkWindow *) tkwin)->dispPtr;
	    if (dispPtr->eventualGrabWinPtr != NULL) {
		Tcl_SetResult(interp, dispPtr->eventualGrabWinPtr->pathName,
			TCL_STATIC);
	    }
	} else {
	    for (dispPtr = TkGetDisplayList(); dispPtr != NULL;
		    dispPtr = dispPtr->nextPtr) {
		if (dispPtr->eventualGrabWinPtr != NULL) {
		    Tcl_AppendElement(interp,
			    dispPtr->eventualGrabWinPtr->pathName);
		}
	    }
	}
	return TCL_OK;

    case GRABCMD_RELEASE:
	/* [grab release window] */
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 1, objv, "release window");
	    return TCL_ERROR;
	}
	tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), clientData);
	if (tkwin == NULL) {
	    Tcl_ResetResult(interp);
	} else {
	    Tk_Ungrab(tkwin);
	}
	break;

    case GRABCMD_SET:
	/* [grab set ?-global? window] */
	if ((objc != 3) && (objc != 4)) {
	    Tcl_WrongNumArgs(interp, 1, objv, "set ?-global? window");
	    return TCL_ERROR;
	}
	if (objc == 3) {
	    globalGrab = 0;
	    tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[2]),
		    clientData);
	} else {
	    globalGrab = 1;

	    /*
	     * We could just test the argument by hand instead of using
	     * Tcl_GetIndexFromObj; the benefit of using the function is that
	     * it sets up the error message for us, so we are certain to be
	     * consistant with the rest of Tcl.
	     */

	    if (Tcl_GetIndexFromObj(interp, objv[2], flagStrings, "option",
		    0, &index) != TCL_OK) {
		return TCL_ERROR;
	    }
	    tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[3]),
		    clientData);
	}
	if (tkwin == NULL) {
	    return TCL_ERROR;
	}
	return Tk_Grab(interp, tkwin, globalGrab);

    case GRABCMD_STATUS: {
	/* [grab status window] */
	TkWindow *winPtr;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 1, objv, "status window");
	    return TCL_ERROR;
	}
	winPtr = (TkWindow *) Tk_NameToWindow(interp, Tcl_GetString(objv[2]),
		clientData);
	if (winPtr == NULL) {
	    return TCL_ERROR;
	}
	dispPtr = winPtr->dispPtr;
	if (dispPtr->eventualGrabWinPtr != winPtr) {
	    Tcl_SetResult(interp, "none", TCL_STATIC);
	} else if (dispPtr->grabFlags & GRAB_GLOBAL) {
	    Tcl_SetResult(interp, "global", TCL_STATIC);
	} else {
	    Tcl_SetResult(interp, "local", TCL_STATIC);
	}
	break;
    }
    }

    return TCL_OK;
}
Beispiel #17
0
void
XDestroyWindow(
    Display *display,		/* Display. */
    Window window)		/* Window. */
{
    MacDrawable *macWin = (MacDrawable *) window;
    WindowRef winRef;

    /*
     * Remove any dangling pointers that may exist if the window we are
     * deleting is being tracked by the grab code.
     */

    TkPointerDeadWindow(macWin->winPtr);
    macWin->toplevel->referenceCount--;

    if (!Tk_IsTopLevel(macWin->winPtr)) {
	TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
	if (macWin->winPtr->parentPtr != NULL) {
	    TkMacOSXInvalClipRgns((Tk_Window) macWin->winPtr->parentPtr);
	}
	if (macWin->visRgn) {
	    CFRelease(macWin->visRgn);
	}
	if (macWin->aboveVisRgn) {
	    CFRelease(macWin->aboveVisRgn);
	}

	if (macWin->toplevel->referenceCount == 0) {
	    ckfree((char *) macWin->toplevel);
	}
	ckfree((char *) macWin);
	return;
    }

    /*
     * We are relying on the Activate Mac OS event to pass the focus away from
     * a window that is getting Destroyed to the Front non-floating window. BUT
     * we don't get activate events when a floating window is destroyed, since
     * the front non-floating window doesn't in fact get activated... So maybe
     * we can check here and if we are destroying a floating window, we can
     * pass the focus back to the front non-floating window...
     */

    if (macWin->grafPtr != NULL) {
	TkWindow *focusPtr = TkGetFocusWin(macWin->winPtr);

	if (focusPtr == NULL
		|| (focusPtr->mainPtr->winPtr == macWin->winPtr)) {
	    winRef = TkMacOSXDrawableWindow(window);
	    if (TkpIsWindowFloating (winRef)) {
		Window window = TkMacOSXGetXWindow(ActiveNonFloatingWindow());

		if (window != None) {
		    TkMacOSXGenerateFocusEvent(window, 1);
		}
	    }
	}
    }
    if (macWin->visRgn) {
	CFRelease(macWin->visRgn);
    }
    if (macWin->aboveVisRgn) {
	CFRelease(macWin->aboveVisRgn);
    }

    /*
     * Delete the Mac window and remove it from the windowTable. The window
     * could be NULL if the window was never mapped. However, we don't do this
     * for embedded windows, they don't go in the window list, and they do not
     * own their portPtr's.
     */

    if (!Tk_IsEmbedded(macWin->winPtr)) {
	WindowRef winRef = TkMacOSXDrawableWindow(window);

	if (winRef) {
	    TkMacOSXWindowList *listPtr, *prevPtr;
	    WindowGroupRef group;

	    if (GetWindowProperty(winRef, 'Tk  ', 'TsGp', sizeof(group), NULL,
		    &group) == noErr) {
		TkDisplay *dispPtr = TkGetDisplayList();
		ItemCount i = CountWindowGroupContents(group,
			kWindowGroupContentsReturnWindows);
		WindowRef macWin;
		WindowGroupRef newGroup;
		Window window;

		while (i > 0) {
		    ChkErr(GetIndexedWindow, group, i--, 0, &macWin);
		    if (!macWin) {
			continue;
		    }

		    window = TkMacOSXGetXWindow(macWin);
		    newGroup = NULL;
		    if (window != None) {
			TkWindow *winPtr = (TkWindow *)
				Tk_IdToWindow(dispPtr->display, window);

			if (winPtr && winPtr->wmInfoPtr) {
			    newGroup = GetWindowGroupOfClass(
				    winPtr->wmInfoPtr->macClass);
			}
		    }
		    if (!newGroup) {
			newGroup =
				GetWindowGroupOfClass(kDocumentWindowClass);
		    }
		    ChkErr(SetWindowGroup, macWin, newGroup);
		}
		ChkErr(SetWindowGroupOwner, group, NULL);
		ChkErr(ReleaseWindowGroup, group);
	    }
	    TkMacOSXUnregisterMacWindow(winRef);
	    DisposeWindow(winRef);

	    for (listPtr=tkMacOSXWindowListPtr, prevPtr=NULL;
		    tkMacOSXWindowListPtr != NULL;
		    prevPtr=listPtr, listPtr=listPtr->nextPtr) {
		if (listPtr->winPtr == macWin->winPtr) {
		    if (prevPtr == NULL) {
			tkMacOSXWindowListPtr = listPtr->nextPtr;
		    } else {
			prevPtr->nextPtr = listPtr->nextPtr;
		    }
		    ckfree((char *) listPtr);
		    break;
		}
	    }
	}
    }

    macWin->grafPtr = NULL;

    /*
     * Delay deletion of a toplevel data structure untill all children have
     * been deleted.
     */

    if (macWin->toplevel->referenceCount == 0) {
	ckfree((char *) macWin->toplevel);
    }
}
Beispiel #18
0
void 
TkMacHandleMenuSelect(
    long mResult,
    int optionKeyPressed)
{
    short theItem = LoWord(mResult);
    short theMenu = HiWord(mResult);
    Str255 name;
    Tk_Window tkwin;
    Window window;
    TkDisplay *dispPtr;

    if (mResult == 0) {
    	TkMacHandleTearoffMenu();
	TkMacClearMenubarActive();
	return;
    }

    switch (theMenu) {
	
	case kAppleMenu:
	    switch (theItem) {
		case kAppleAboutItem:
		    {
			Tcl_CmdInfo dummy;
			
			if (optionKeyPressed || gInterp == NULL ||
			    Tcl_GetCommandInfo(gInterp,
				    "tkAboutDialog", &dummy) == 0) {
			    TkAboutDlg();
			} else {
			    Tcl_Eval(gInterp, "tkAboutDialog");
			}
			break;
		    }
		default:
		    GetMenuItemText(tkAppleMenu, theItem, name);
		    HiliteMenu(0);
		    OpenDeskAcc(name);
		    return;
	    }
	    break;
	case kFileMenu:
	    switch (theItem) {
		case kSourceItem:
		    /* TODO: source script */
		    SourceDialog();
		    break;
		case kCloseItem:
		    /* Send close event */
		    if (TkMacHaveAppearance() >= 0x110) {
		        window = TkMacGetXWindow(FrontNonFloatingWindow());
		    } else {
		        window = TkMacGetXWindow(FrontWindow());
		    }
		    dispPtr = TkGetDisplayList();
		    tkwin = Tk_IdToWindow(dispPtr->display, window);
		    TkGenWMDestroyEvent(tkwin);
		    break;
		case kQuitItem:
		    /* Exit */
		    if (optionKeyPressed || gInterp == NULL) {
			Tcl_Exit(0);
		    } else {
			Tcl_Eval(gInterp, "exit");
		    }
		    break;
	    }
	    break;
	case kEditMenu:
	    /*
	     * This implementation just send keysyms
	     * the Tk thinks are associated with function keys that
	     * do Cut, Copy & Paste on a Sun keyboard.
	     */
	    GenerateEditEvent(theItem);
	    break;
	default:
	    TkMacDispatchMenuEvent(theMenu, theItem);
	    TkMacClearMenubarActive();
	    break;
    }

    /*
     * Finally we unhighlight the menu.
     */
    HiliteMenu(0);
} /* TkMacHandleMenuSelect */
Beispiel #19
0
MODULE_SCOPE int
TkMacOSXProcessMouseEvent(TkMacOSXEvent *eventPtr, MacEventStatus * statusPtr)
{
    Tk_Window tkwin;
    Point where, where2;
    int result;
    TkDisplay * dispPtr;
    OSStatus err;
    MouseEventData mouseEventData, * medPtr = &mouseEventData;
    int isFrontProcess;

    switch (eventPtr->eKind) {
	case kEventMouseDown:
	case kEventMouseUp:
	case kEventMouseMoved:
	case kEventMouseDragged:
	case kEventMouseWheelMoved:
	    break;
	default:
	    return false;
	    break;
    }
    err = ChkErr(GetEventParameter, eventPtr->eventRef,
	    kEventParamMouseLocation,
	    typeQDPoint, NULL,
	    sizeof(where), NULL,
	    &where);
    if (err != noErr) {
	GetGlobalMouse(&where);
    }
    err = ChkErr(GetEventParameter, eventPtr->eventRef,
	    kEventParamWindowRef,
	    typeWindowRef, NULL,
	    sizeof(WindowRef), NULL,
	    &medPtr->whichWin);
    if (err == noErr) {
	err = ChkErr(GetEventParameter, eventPtr->eventRef,
		kEventParamWindowPartCode,
		typeWindowPartCode, NULL,
		sizeof(WindowPartCode), NULL,
		&medPtr->windowPart);
    }
    if (err != noErr) {
	medPtr->windowPart = FindWindow(where, &medPtr->whichWin);
    }
    medPtr->window = TkMacOSXGetXWindow(medPtr->whichWin);
    if (medPtr->whichWin != NULL && medPtr->window == None) {
	return false;
    }
    if (eventPtr->eKind == kEventMouseDown) {
	if (IsWindowActive(medPtr->whichWin) && IsWindowPathSelectEvent(
		medPtr->whichWin, eventPtr->eventRef)) {
	    ChkErr(WindowPathSelect, medPtr->whichWin, NULL, NULL);
	    return false;
	}
	if (medPtr->windowPart == inProxyIcon) {
	    TkMacOSXTrackingLoop(1);
	    err = ChkErr(TrackWindowProxyDrag, medPtr->whichWin, where);
	    TkMacOSXTrackingLoop(0);
	    if (err == errUserWantsToDragWindow) {
		medPtr->windowPart = inDrag;
	    } else {
		return false;
	    }
	}
    }
    isFrontProcess = Tk_MacOSXIsAppInFront();
    if (isFrontProcess) {
	medPtr->state = ButtonModifiers2State(GetCurrentEventButtonState(),
		GetCurrentEventKeyModifiers());
    } else {
	medPtr->state = ButtonModifiers2State(GetCurrentButtonState(),
		GetCurrentKeyModifiers());
    }
    medPtr->global = where;
    err = ChkErr(GetEventParameter, eventPtr->eventRef,
	    kEventParamWindowMouseLocation,
	    typeQDPoint, NULL,
	    sizeof(Point), NULL,
	    &medPtr->local);
    if (err == 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);
	}
    }
    medPtr->activeNonFloating = ActiveNonFloatingWindow();
    dispPtr = TkGetDisplayList();
    tkwin = Tk_IdToWindow(dispPtr->display, medPtr->window);

    if (eventPtr->eKind != kEventMouseDown) {
	int res = false;

	switch (eventPtr->eKind) {
	    case kEventMouseUp:
		/*
		 * The window manager only needs to know about mouse down
		 * events and sometimes we need to "eat" the mouse up.
		 * Otherwise, we just pass the event to Tk.
		 */
		if (TkMacOSXGetEatButtonUp()) {
		    TkMacOSXSetEatButtonUp(false);
		} else {
		    res = GenerateButtonEvent(medPtr);
		}
		break;
	    case kEventMouseWheelMoved:
		err = ChkErr(GetEventParameter, eventPtr->eventRef,
			kEventParamMouseWheelDelta, typeLongInteger, NULL,
			sizeof(long), NULL, &medPtr->delta);
		if (err != noErr ) {
		    statusPtr->err = 1;
		} else {
		    EventMouseWheelAxis axis;
		    err = ChkErr(GetEventParameter, eventPtr->eventRef,
			    kEventParamMouseWheelAxis, typeMouseWheelAxis,
			    NULL, sizeof(EventMouseWheelAxis), NULL, &axis);
		    if (err == noErr && axis == kEventMouseWheelAxisX) {
			 medPtr->state |= ShiftMask;
		    }
		    res = GenerateMouseWheelEvent(medPtr);
		}
		break;
	    case kEventMouseMoved:
	    case kEventMouseDragged:
		res = GeneratePollingEvents(medPtr);
		break;
	    default:
		Tcl_Panic("Unknown mouse event !");
	}
	if (res) {
		statusPtr->stopProcessing = 1;
	}
	return res;
    }
    TkMacOSXSetEatButtonUp(false);
    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
		|| !isFrontProcess)) {
	    int frontWindowOnly = 1;
	    int cmdDragGrow = ((medPtr->windowPart == inDrag ||
		    medPtr->windowPart == inGrow) && medPtr->state & Mod1Mask);

	    if (!cmdDragGrow) {
		Tk_Window grabWin = GetGrabWindowForWindow(tkwin);

		frontWindowOnly = !grabWin;
		if (grabWin && grabWin != tkwin) {
		    TkMacOSXSetEatButtonUp(true);
		    BringWindowForward(TkMacOSXDrawableWindow(
			    ((TkWindow*)grabWin)->window), isFrontProcess,
			    frontWindowOnly);
		    return false;
		}
	    }

	    /*
	     * Clicks in the titlebar widgets are handled without bringing the
	     * window forward.
	     */
	    if ((result = HandleWindowTitlebarMouseDown(medPtr, tkwin)) != -1) {
		statusPtr->stopProcessing = 1;
		return result;
	    } else {
		/*
		 * Only windows with the kWindowNoActivatesAttribute can
		 * receive mouse events in the background.
		 */
		if (!(((TkWindow *)tkwin)->wmInfoPtr->attributes &
			kWindowNoActivatesAttribute)) {
		    /*
		     * Allow background window dragging & growing with Command
		     * down.
		     */
		    if (!cmdDragGrow) {
			TkMacOSXSetEatButtonUp(true);
			BringWindowForward(medPtr->whichWin, isFrontProcess,
				frontWindowOnly);
		    }
		    /*
		     * Allow dragging & growing of windows that were/are in the
		     * background.
		     */
		    if (!(medPtr->windowPart == inDrag ||
			    medPtr->windowPart == inGrow)) {
			return false;
		    }
		}
	    }
	} else {
	    if ((result = HandleWindowTitlebarMouseDown(medPtr, tkwin)) != -1) {
		statusPtr->stopProcessing = 1;
		return result;
	    }
	}
	switch (medPtr->windowPart) {
	    case inDrag: {
		WindowAttributes attributes;

		GetWindowAttributes(medPtr->whichWin, &attributes);
		if (!(attributes & kWindowAsyncDragAttribute)) {
		    TkMacOSXTrackingLoop(1);
		    DragWindow(medPtr->whichWin, where, NULL);
		    TkMacOSXTrackingLoop(0);
		    where2.h = where2.v = 0;
		    QDLocalToGlobalPoint(GetWindowPort(medPtr->whichWin),
			    &where2);
		    if (EqualPt(where, where2)) {
			return false;
		    }
		    return true;
		}
		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) {
		    statusPtr->stopProcessing = 1;
		    return true;
		} else {
		    return GenerateButtonEvent(medPtr);
		}
		break;
	    case inContent:
		return GenerateButtonEvent(medPtr);
		break;
	    default:
		return false;
		break;
	}
    }
    return false;
}