OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [tk/] [unix/] [tkUnixFocus.c] - Blame information for rev 1770

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/*
2
 * tkUnixFocus.c --
3
 *
4
 *      This file contains platform specific procedures that manage
5
 *      focus for Tk.
6
 *
7
 * Copyright (c) 1997 Sun Microsystems, Inc.
8
 *
9
 * See the file "license.terms" for information on usage and redistribution
10
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
11
 *
12
 * RCS: @(#) $Id: tkUnixFocus.c,v 1.1.1.1 2002-01-16 10:26:01 markom Exp $
13
 */
14
 
15
#include "tkInt.h"
16
#include "tkPort.h"
17
#include "tkUnixInt.h"
18
 
19
extern int tclFocusDebug;
20
 
21
/*
22
 *----------------------------------------------------------------------
23
 *
24
 * TkpChangeFocus --
25
 *
26
 *      This procedure is invoked to move the official X focus from
27
 *      one window to another.
28
 *
29
 * Results:
30
 *      The return value is the serial number of the command that
31
 *      changed the focus.  It may be needed by the caller to filter
32
 *      out focus change events that were queued before the command.
33
 *      If the procedure doesn't actually change the focus then
34
 *      it returns 0.
35
 *
36
 * Side effects:
37
 *      The official X focus window changes;  the application's focus
38
 *      window isn't changed by this procedure.
39
 *
40
 *----------------------------------------------------------------------
41
 */
42
 
43
int
44
TkpChangeFocus(winPtr, force)
45
    TkWindow *winPtr;           /* Window that is to receive the X focus. */
46
    int force;                  /* Non-zero means claim the focus even
47
                                 * if it didn't originally belong to
48
                                 * topLevelPtr's application. */
49
{
50
    TkDisplay *dispPtr = winPtr->dispPtr;
51
    Tk_ErrorHandler errHandler;
52
    Window window, root, parent, *children;
53
    unsigned int numChildren, serial;
54
    TkWindow *winPtr2;
55
    int dummy;
56
 
57
    /*
58
     * Don't set the X focus to a window that's marked
59
     * override-redirect.  This is a hack to avoid problems with menus
60
     * under olvwm: if we move the focus then the focus can get lost
61
     * during keyboard traversal.  Fortunately, we don't really need to
62
     * move the focus for menus: events will still find their way to the
63
     * focus window, and menus aren't decorated anyway so the window
64
     * manager doesn't need to hear about the focus change in order to
65
     * redecorate the menu.
66
     */
67
 
68
    serial = 0;
69
    if (winPtr->atts.override_redirect) {
70
        return serial;
71
    }
72
 
73
    /*
74
     * Check to make sure that the focus is still in one of the windows
75
     * of this application or one of their descendants.  Furthermore,
76
     * grab the server to make sure that the focus doesn't change in the
77
     * middle of this operation.
78
     */
79
 
80
    XGrabServer(dispPtr->display);
81
    if (!force) {
82
        /*
83
         * Find the focus window, then see if it or one of its ancestors
84
         * is a window in our application (it's possible that the focus
85
         * window is in an embedded application, which may or may not be
86
         * in the same process.
87
         */
88
 
89
        XGetInputFocus(dispPtr->display, &window, &dummy);
90
        while (1) {
91
            winPtr2 = (TkWindow *) Tk_IdToWindow(dispPtr->display, window);
92
            if ((winPtr2 != NULL) && (winPtr2->mainPtr == winPtr->mainPtr)) {
93
                break;
94
            }
95
            if ((window == PointerRoot) || (window == None)) {
96
                goto done;
97
            }
98
            XQueryTree(dispPtr->display, window, &root, &parent, &children,
99
                    &numChildren);
100
            if (children != NULL) {
101
                XFree((void *) children);
102
            }
103
            if (parent == root) {
104
                goto done;
105
            }
106
            window = parent;
107
        }
108
    }
109
 
110
    /*
111
     * Tell X to change the focus.  Ignore errors that occur when changing
112
     * the focus:  it is still possible that the window we're focussing
113
     * to could have gotten unmapped, which will generate an error.
114
     */
115
 
116
    errHandler = Tk_CreateErrorHandler(dispPtr->display, -1, -1, -1,
117
            (Tk_ErrorProc *) NULL, (ClientData) NULL);
118
    if (winPtr->window == None) {
119
        panic("ChangeXFocus got null X window");
120
    }
121
    XSetInputFocus(dispPtr->display, winPtr->window, RevertToParent,
122
            CurrentTime);
123
    Tk_DeleteErrorHandler(errHandler);
124
 
125
    /*
126
     * Remember the current serial number for the X server and issue
127
     * a dummy server request.  This marks the position at which we
128
     * changed the focus, so we can distinguish FocusIn and FocusOut
129
     * events on either side of the mark.
130
     */
131
 
132
    serial = NextRequest(winPtr->display);
133
    XNoOp(winPtr->display);
134
 
135
    done:
136
    XUngrabServer(dispPtr->display);
137
 
138
    /*
139
     * After ungrabbing the server, it's important to flush the output
140
     * immediately so that the server sees the ungrab command.  Otherwise
141
     * we might do something else that needs to communicate with the
142
     * server (such as invoking a subprocess that needs to do I/O to
143
     * the screen); if the ungrab command is still sitting in our
144
     * output buffer, we could deadlock.
145
     */
146
 
147
    XFlush(dispPtr->display);
148
    return serial;
149
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.