Parent Directory | Revision Log | Patch
revision 69 by dashley, Sat Nov 5 10:54:17 2016 UTC | revision 71 by dashley, Sat Nov 5 11:07:06 2016 UTC | |
---|---|---|
# | Line 1 | Line 1 |
1 | /* $Header$ */ | /* $Header$ */ |
2 | ||
3 | /* | /* |
4 | * tkWindow.c -- | * tkWindow.c -- |
5 | * | * |
6 | * This file provides basic window-manipulation procedures, | * This file provides basic window-manipulation procedures, |
7 | * which are equivalent to procedures in Xlib (and even | * which are equivalent to procedures in Xlib (and even |
8 | * invoke them) but also maintain the local Tk_Window | * invoke them) but also maintain the local Tk_Window |
9 | * structure. | * structure. |
10 | * | * |
11 | * Copyright (c) 1989-1994 The Regents of the University of California. | * Copyright (c) 1989-1994 The Regents of the University of California. |
12 | * Copyright (c) 1994-1997 Sun Microsystems, Inc. | * Copyright (c) 1994-1997 Sun Microsystems, Inc. |
13 | * | * |
14 | * See the file "license.terms" for information on usage and redistribution | * See the file "license.terms" for information on usage and redistribution |
15 | * of this file, and for a DISCLAIMER OF ALL WARRANTIES. | * of this file, and for a DISCLAIMER OF ALL WARRANTIES. |
16 | * | * |
17 | * RCS: @(#) $Id: tkwindow.c,v 1.1.1.1 2001/06/13 05:12:54 dtashley Exp $ | * RCS: @(#) $Id: tkwindow.c,v 1.1.1.1 2001/06/13 05:12:54 dtashley Exp $ |
18 | */ | */ |
19 | ||
20 | #include "tkPort.h" | #include "tkPort.h" |
21 | #include "tkInt.h" | #include "tkInt.h" |
22 | ||
23 | #if !defined(__WIN32__) && !defined(MAC_TCL) | #if !defined(__WIN32__) && !defined(MAC_TCL) |
24 | #include "tkUnixInt.h" | #include "tkUnixInt.h" |
25 | #endif | #endif |
26 | ||
27 | ||
28 | typedef struct ThreadSpecificData { | typedef struct ThreadSpecificData { |
29 | int numMainWindows; /* Count of numver of main windows currently | int numMainWindows; /* Count of numver of main windows currently |
30 | * open in this thread. */ | * open in this thread. */ |
31 | TkMainInfo *mainWindowList; | TkMainInfo *mainWindowList; |
32 | /* First in list of all main windows managed | /* First in list of all main windows managed |
33 | * by this thread. */ | * by this thread. */ |
34 | TkDisplay *displayList; | TkDisplay *displayList; |
35 | /* List of all displays currently in use by | /* List of all displays currently in use by |
36 | * the current thread. */ | * the current thread. */ |
37 | int initialized; /* 0 means the structures above need | int initialized; /* 0 means the structures above need |
38 | * initializing. */ | * initializing. */ |
39 | } ThreadSpecificData; | } ThreadSpecificData; |
40 | static Tcl_ThreadDataKey dataKey; | static Tcl_ThreadDataKey dataKey; |
41 | ||
42 | /* | /* |
43 | * The Mutex below is used to lock access to the Tk_Uid structs above. | * The Mutex below is used to lock access to the Tk_Uid structs above. |
44 | */ | */ |
45 | ||
46 | TCL_DECLARE_MUTEX(windowMutex) | TCL_DECLARE_MUTEX(windowMutex) |
47 | ||
48 | /* | /* |
49 | * Default values for "changes" and "atts" fields of TkWindows. Note | * Default values for "changes" and "atts" fields of TkWindows. Note |
50 | * that Tk always requests all events for all windows, except StructureNotify | * that Tk always requests all events for all windows, except StructureNotify |
51 | * events on internal windows: these events are generated internally. | * events on internal windows: these events are generated internally. |
52 | */ | */ |
53 | ||
54 | static XWindowChanges defChanges = { | static XWindowChanges defChanges = { |
55 | 0, 0, 1, 1, 0, 0, Above | 0, 0, 1, 1, 0, 0, Above |
56 | }; | }; |
57 | #define ALL_EVENTS_MASK \ | #define ALL_EVENTS_MASK \ |
58 | KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask| \ | KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask| \ |
59 | EnterWindowMask|LeaveWindowMask|PointerMotionMask|ExposureMask| \ | EnterWindowMask|LeaveWindowMask|PointerMotionMask|ExposureMask| \ |
60 | VisibilityChangeMask|PropertyChangeMask|ColormapChangeMask | VisibilityChangeMask|PropertyChangeMask|ColormapChangeMask |
61 | static XSetWindowAttributes defAtts= { | static XSetWindowAttributes defAtts= { |
62 | None, /* background_pixmap */ | None, /* background_pixmap */ |
63 | 0, /* background_pixel */ | 0, /* background_pixel */ |
64 | CopyFromParent, /* border_pixmap */ | CopyFromParent, /* border_pixmap */ |
65 | 0, /* border_pixel */ | 0, /* border_pixel */ |
66 | NorthWestGravity, /* bit_gravity */ | NorthWestGravity, /* bit_gravity */ |
67 | NorthWestGravity, /* win_gravity */ | NorthWestGravity, /* win_gravity */ |
68 | NotUseful, /* backing_store */ | NotUseful, /* backing_store */ |
69 | (unsigned) ~0, /* backing_planes */ | (unsigned) ~0, /* backing_planes */ |
70 | 0, /* backing_pixel */ | 0, /* backing_pixel */ |
71 | False, /* save_under */ | False, /* save_under */ |
72 | ALL_EVENTS_MASK, /* event_mask */ | ALL_EVENTS_MASK, /* event_mask */ |
73 | 0, /* do_not_propagate_mask */ | 0, /* do_not_propagate_mask */ |
74 | False, /* override_redirect */ | False, /* override_redirect */ |
75 | CopyFromParent, /* colormap */ | CopyFromParent, /* colormap */ |
76 | None /* cursor */ | None /* cursor */ |
77 | }; | }; |
78 | ||
79 | /* | /* |
80 | * The following structure defines all of the commands supported by | * The following structure defines all of the commands supported by |
81 | * Tk, and the C procedures that execute them. | * Tk, and the C procedures that execute them. |
82 | */ | */ |
83 | ||
84 | typedef struct { | typedef struct { |
85 | char *name; /* Name of command. */ | char *name; /* Name of command. */ |
86 | Tcl_CmdProc *cmdProc; /* Command's string-based procedure. */ | Tcl_CmdProc *cmdProc; /* Command's string-based procedure. */ |
87 | Tcl_ObjCmdProc *objProc; /* Command's object-based procedure. */ | Tcl_ObjCmdProc *objProc; /* Command's object-based procedure. */ |
88 | int isSafe; /* If !0, this command will be exposed in | int isSafe; /* If !0, this command will be exposed in |
89 | * a safe interpreter. Otherwise it will be | * a safe interpreter. Otherwise it will be |
90 | * hidden in a safe interpreter. */ | * hidden in a safe interpreter. */ |
91 | int passMainWindow; /* 0 means provide NULL clientData to | int passMainWindow; /* 0 means provide NULL clientData to |
92 | * command procedure; 1 means pass main | * command procedure; 1 means pass main |
93 | * window as clientData to command | * window as clientData to command |
94 | * procedure. */ | * procedure. */ |
95 | } TkCmd; | } TkCmd; |
96 | ||
97 | static TkCmd commands[] = { | static TkCmd commands[] = { |
98 | /* | /* |
99 | * Commands that are part of the intrinsics: | * Commands that are part of the intrinsics: |
100 | */ | */ |
101 | ||
102 | {"bell", NULL, Tk_BellObjCmd, 0, 1}, | {"bell", NULL, Tk_BellObjCmd, 0, 1}, |
103 | {"bind", Tk_BindCmd, NULL, 1, 1}, | {"bind", Tk_BindCmd, NULL, 1, 1}, |
104 | {"bindtags", Tk_BindtagsCmd, NULL, 1, 1}, | {"bindtags", Tk_BindtagsCmd, NULL, 1, 1}, |
105 | {"clipboard", Tk_ClipboardCmd, NULL, 0, 1}, | {"clipboard", Tk_ClipboardCmd, NULL, 0, 1}, |
106 | {"destroy", NULL, Tk_DestroyObjCmd, 1, 1}, | {"destroy", NULL, Tk_DestroyObjCmd, 1, 1}, |
107 | {"event", NULL, Tk_EventObjCmd, 1, 1}, | {"event", NULL, Tk_EventObjCmd, 1, 1}, |
108 | {"focus", NULL, Tk_FocusObjCmd, 1, 1}, | {"focus", NULL, Tk_FocusObjCmd, 1, 1}, |
109 | {"font", NULL, Tk_FontObjCmd, 1, 1}, | {"font", NULL, Tk_FontObjCmd, 1, 1}, |
110 | {"grab", Tk_GrabCmd, NULL, 0, 1}, | {"grab", Tk_GrabCmd, NULL, 0, 1}, |
111 | {"grid", Tk_GridCmd, NULL, 1, 1}, | {"grid", Tk_GridCmd, NULL, 1, 1}, |
112 | {"image", NULL, Tk_ImageObjCmd, 1, 1}, | {"image", NULL, Tk_ImageObjCmd, 1, 1}, |
113 | {"lower", NULL, Tk_LowerObjCmd, 1, 1}, | {"lower", NULL, Tk_LowerObjCmd, 1, 1}, |
114 | {"option", NULL, Tk_OptionObjCmd, 1, 1}, | {"option", NULL, Tk_OptionObjCmd, 1, 1}, |
115 | {"pack", Tk_PackCmd, NULL, 1, 1}, | {"pack", Tk_PackCmd, NULL, 1, 1}, |
116 | {"place", Tk_PlaceCmd, NULL, 1, 1}, | {"place", Tk_PlaceCmd, NULL, 1, 1}, |
117 | {"raise", NULL, Tk_RaiseObjCmd, 1, 1}, | {"raise", NULL, Tk_RaiseObjCmd, 1, 1}, |
118 | {"selection", Tk_SelectionCmd, NULL, 0, 1}, | {"selection", Tk_SelectionCmd, NULL, 0, 1}, |
119 | {"tk", NULL, Tk_TkObjCmd, 0, 1}, | {"tk", NULL, Tk_TkObjCmd, 0, 1}, |
120 | {"tkwait", Tk_TkwaitCmd, NULL, 1, 1}, | {"tkwait", Tk_TkwaitCmd, NULL, 1, 1}, |
121 | #if defined(__WIN32__) || defined(MAC_TCL) | #if defined(__WIN32__) || defined(MAC_TCL) |
122 | {"tk_chooseColor", NULL, Tk_ChooseColorObjCmd, 0, 1}, | {"tk_chooseColor", NULL, Tk_ChooseColorObjCmd, 0, 1}, |
123 | {"tk_chooseDirectory", NULL, Tk_ChooseDirectoryObjCmd, 0, 1}, | {"tk_chooseDirectory", NULL, Tk_ChooseDirectoryObjCmd, 0, 1}, |
124 | {"tk_getOpenFile", NULL, Tk_GetOpenFileObjCmd, 0, 1}, | {"tk_getOpenFile", NULL, Tk_GetOpenFileObjCmd, 0, 1}, |
125 | {"tk_getSaveFile", NULL, Tk_GetSaveFileObjCmd, 0, 1}, | {"tk_getSaveFile", NULL, Tk_GetSaveFileObjCmd, 0, 1}, |
126 | #endif | #endif |
127 | #ifdef __WIN32__ | #ifdef __WIN32__ |
128 | {"tk_messageBox", NULL, Tk_MessageBoxObjCmd, 0, 1}, | {"tk_messageBox", NULL, Tk_MessageBoxObjCmd, 0, 1}, |
129 | #endif | #endif |
130 | {"update", NULL, Tk_UpdateObjCmd, 1, 1}, | {"update", NULL, Tk_UpdateObjCmd, 1, 1}, |
131 | {"winfo", NULL, Tk_WinfoObjCmd, 1, 1}, | {"winfo", NULL, Tk_WinfoObjCmd, 1, 1}, |
132 | {"wm", Tk_WmCmd, NULL, 0, 1}, | {"wm", Tk_WmCmd, NULL, 0, 1}, |
133 | ||
134 | /* | /* |
135 | * Widget class commands. | * Widget class commands. |
136 | */ | */ |
137 | ||
138 | {"button", NULL, Tk_ButtonObjCmd, 1, 0}, | {"button", NULL, Tk_ButtonObjCmd, 1, 0}, |
139 | {"canvas", NULL, Tk_CanvasObjCmd, 1, 1}, | {"canvas", NULL, Tk_CanvasObjCmd, 1, 1}, |
140 | {"checkbutton", NULL, Tk_CheckbuttonObjCmd, 1, 0}, | {"checkbutton", NULL, Tk_CheckbuttonObjCmd, 1, 0}, |
141 | {"entry", NULL, Tk_EntryObjCmd, 1, 0}, | {"entry", NULL, Tk_EntryObjCmd, 1, 0}, |
142 | {"frame", NULL, Tk_FrameObjCmd, 1, 1}, | {"frame", NULL, Tk_FrameObjCmd, 1, 1}, |
143 | {"label", NULL, Tk_LabelObjCmd, 1, 0}, | {"label", NULL, Tk_LabelObjCmd, 1, 0}, |
144 | {"listbox", NULL, Tk_ListboxObjCmd, 1, 0}, | {"listbox", NULL, Tk_ListboxObjCmd, 1, 0}, |
145 | {"menubutton", NULL, Tk_MenubuttonObjCmd, 1, 0}, | {"menubutton", NULL, Tk_MenubuttonObjCmd, 1, 0}, |
146 | {"message", Tk_MessageCmd, NULL, 1, 1}, | {"message", Tk_MessageCmd, NULL, 1, 1}, |
147 | {"radiobutton", NULL, Tk_RadiobuttonObjCmd, 1, 0}, | {"radiobutton", NULL, Tk_RadiobuttonObjCmd, 1, 0}, |
148 | {"scale", NULL, Tk_ScaleObjCmd, 1, 0}, | {"scale", NULL, Tk_ScaleObjCmd, 1, 0}, |
149 | {"scrollbar", Tk_ScrollbarCmd, NULL, 1, 1}, | {"scrollbar", Tk_ScrollbarCmd, NULL, 1, 1}, |
150 | {"text", Tk_TextCmd, NULL, 1, 1}, | {"text", Tk_TextCmd, NULL, 1, 1}, |
151 | {"toplevel", NULL, Tk_ToplevelObjCmd, 0, 1}, | {"toplevel", NULL, Tk_ToplevelObjCmd, 0, 1}, |
152 | ||
153 | /* | /* |
154 | * Misc. | * Misc. |
155 | */ | */ |
156 | ||
157 | #ifdef MAC_TCL | #ifdef MAC_TCL |
158 | {"unsupported1", TkUnsupported1Cmd, NULL, 1, 1}, | {"unsupported1", TkUnsupported1Cmd, NULL, 1, 1}, |
159 | #endif | #endif |
160 | {(char *) NULL, (int (*) _ANSI_ARGS_((ClientData, Tcl_Interp *, int, char **))) NULL, NULL, 0} | {(char *) NULL, (int (*) _ANSI_ARGS_((ClientData, Tcl_Interp *, int, char **))) NULL, NULL, 0} |
161 | }; | }; |
162 | ||
163 | /* | /* |
164 | * The variables and table below are used to parse arguments from | * The variables and table below are used to parse arguments from |
165 | * the "argv" variable in Tk_Init. | * the "argv" variable in Tk_Init. |
166 | */ | */ |
167 | ||
168 | static int synchronize = 0; | static int synchronize = 0; |
169 | static char *name = NULL; | static char *name = NULL; |
170 | static char *display = NULL; | static char *display = NULL; |
171 | static char *geometry = NULL; | static char *geometry = NULL; |
172 | static char *colormap = NULL; | static char *colormap = NULL; |
173 | static char *use = NULL; | static char *use = NULL; |
174 | static char *visual = NULL; | static char *visual = NULL; |
175 | static int rest = 0; | static int rest = 0; |
176 | ||
177 | static Tk_ArgvInfo argTable[] = { | static Tk_ArgvInfo argTable[] = { |
178 | {"-colormap", TK_ARGV_STRING, (char *) NULL, (char *) &colormap, | {"-colormap", TK_ARGV_STRING, (char *) NULL, (char *) &colormap, |
179 | "Colormap for main window"}, | "Colormap for main window"}, |
180 | {"-display", TK_ARGV_STRING, (char *) NULL, (char *) &display, | {"-display", TK_ARGV_STRING, (char *) NULL, (char *) &display, |
181 | "Display to use"}, | "Display to use"}, |
182 | {"-geometry", TK_ARGV_STRING, (char *) NULL, (char *) &geometry, | {"-geometry", TK_ARGV_STRING, (char *) NULL, (char *) &geometry, |
183 | "Initial geometry for window"}, | "Initial geometry for window"}, |
184 | {"-name", TK_ARGV_STRING, (char *) NULL, (char *) &name, | {"-name", TK_ARGV_STRING, (char *) NULL, (char *) &name, |
185 | "Name to use for application"}, | "Name to use for application"}, |
186 | {"-sync", TK_ARGV_CONSTANT, (char *) 1, (char *) &synchronize, | {"-sync", TK_ARGV_CONSTANT, (char *) 1, (char *) &synchronize, |
187 | "Use synchronous mode for display server"}, | "Use synchronous mode for display server"}, |
188 | {"-visual", TK_ARGV_STRING, (char *) NULL, (char *) &visual, | {"-visual", TK_ARGV_STRING, (char *) NULL, (char *) &visual, |
189 | "Visual for main window"}, | "Visual for main window"}, |
190 | {"-use", TK_ARGV_STRING, (char *) NULL, (char *) &use, | {"-use", TK_ARGV_STRING, (char *) NULL, (char *) &use, |
191 | "Id of window in which to embed application"}, | "Id of window in which to embed application"}, |
192 | {"--", TK_ARGV_REST, (char *) 1, (char *) &rest, | {"--", TK_ARGV_REST, (char *) 1, (char *) &rest, |
193 | "Pass all remaining arguments through to script"}, | "Pass all remaining arguments through to script"}, |
194 | {(char *) NULL, TK_ARGV_END, (char *) NULL, (char *) NULL, | {(char *) NULL, TK_ARGV_END, (char *) NULL, (char *) NULL, |
195 | (char *) NULL} | (char *) NULL} |
196 | }; | }; |
197 | ||
198 | /* | /* |
199 | * Forward declarations to procedures defined later in this file: | * Forward declarations to procedures defined later in this file: |
200 | */ | */ |
201 | ||
202 | static Tk_Window CreateTopLevelWindow _ANSI_ARGS_((Tcl_Interp *interp, | static Tk_Window CreateTopLevelWindow _ANSI_ARGS_((Tcl_Interp *interp, |
203 | Tk_Window parent, char *name, char *screenName)); | Tk_Window parent, char *name, char *screenName)); |
204 | static void DeleteWindowsExitProc _ANSI_ARGS_(( | static void DeleteWindowsExitProc _ANSI_ARGS_(( |
205 | ClientData clientData)); | ClientData clientData)); |
206 | static TkDisplay * GetScreen _ANSI_ARGS_((Tcl_Interp *interp, | static TkDisplay * GetScreen _ANSI_ARGS_((Tcl_Interp *interp, |
207 | char *screenName, int *screenPtr)); | char *screenName, int *screenPtr)); |
208 | static int Initialize _ANSI_ARGS_((Tcl_Interp *interp)); | static int Initialize _ANSI_ARGS_((Tcl_Interp *interp)); |
209 | static int NameWindow _ANSI_ARGS_((Tcl_Interp *interp, | static int NameWindow _ANSI_ARGS_((Tcl_Interp *interp, |
210 | TkWindow *winPtr, TkWindow *parentPtr, | TkWindow *winPtr, TkWindow *parentPtr, |
211 | char *name)); | char *name)); |
212 | static void OpenIM _ANSI_ARGS_((TkDisplay *dispPtr)); | static void OpenIM _ANSI_ARGS_((TkDisplay *dispPtr)); |
213 | static void UnlinkWindow _ANSI_ARGS_((TkWindow *winPtr)); | static void UnlinkWindow _ANSI_ARGS_((TkWindow *winPtr)); |
214 | ||
215 | /* | /* |
216 | *---------------------------------------------------------------------- | *---------------------------------------------------------------------- |
217 | * | * |
218 | * CreateTopLevelWindow -- | * CreateTopLevelWindow -- |
219 | * | * |
220 | * Make a new window that will be at top-level (its parent will | * Make a new window that will be at top-level (its parent will |
221 | * be the root window of a screen). | * be the root window of a screen). |
222 | * | * |
223 | * Results: | * Results: |
224 | * The return value is a token for the new window, or NULL if | * The return value is a token for the new window, or NULL if |
225 | * an error prevented the new window from being created. If | * an error prevented the new window from being created. If |
226 | * NULL is returned, an error message will be left in | * NULL is returned, an error message will be left in |
227 | * the interp's result. | * the interp's result. |
228 | * | * |
229 | * Side effects: | * Side effects: |
230 | * A new window structure is allocated locally. An X | * A new window structure is allocated locally. An X |
231 | * window is NOT initially created, but will be created | * window is NOT initially created, but will be created |
232 | * the first time the window is mapped. | * the first time the window is mapped. |
233 | * | * |
234 | *---------------------------------------------------------------------- | *---------------------------------------------------------------------- |
235 | */ | */ |
236 | ||
237 | static Tk_Window | static Tk_Window |
238 | CreateTopLevelWindow(interp, parent, name, screenName) | CreateTopLevelWindow(interp, parent, name, screenName) |
239 | Tcl_Interp *interp; /* Interpreter to use for error reporting. */ | Tcl_Interp *interp; /* Interpreter to use for error reporting. */ |
240 | Tk_Window parent; /* Token for logical parent of new window | Tk_Window parent; /* Token for logical parent of new window |
241 | * (used for naming, options, etc.). May | * (used for naming, options, etc.). May |
242 | * be NULL. */ | * be NULL. */ |
243 | char *name; /* Name for new window; if parent is | char *name; /* Name for new window; if parent is |
244 | * non-NULL, must be unique among parent's | * non-NULL, must be unique among parent's |
245 | * children. */ | * children. */ |
246 | char *screenName; /* Name of screen on which to create | char *screenName; /* Name of screen on which to create |
247 | * window. NULL means use DISPLAY environment | * window. NULL means use DISPLAY environment |
248 | * variable to determine. Empty string means | * variable to determine. Empty string means |
249 | * use parent's screen, or DISPLAY if no | * use parent's screen, or DISPLAY if no |
250 | * parent. */ | * parent. */ |
251 | { | { |
252 | register TkWindow *winPtr; | register TkWindow *winPtr; |
253 | register TkDisplay *dispPtr; | register TkDisplay *dispPtr; |
254 | int screenId; | int screenId; |
255 | ThreadSpecificData *tsdPtr = (ThreadSpecificData *) | ThreadSpecificData *tsdPtr = (ThreadSpecificData *) |
256 | Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); | Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); |
257 | ||
258 | if (!tsdPtr->initialized) { | if (!tsdPtr->initialized) { |
259 | tsdPtr->initialized = 1; | tsdPtr->initialized = 1; |
260 | ||
261 | /* | /* |
262 | * Create built-in image types. | * Create built-in image types. |
263 | */ | */ |
264 | ||
265 | Tk_CreateImageType(&tkBitmapImageType); | Tk_CreateImageType(&tkBitmapImageType); |
266 | Tk_CreateImageType(&tkPhotoImageType); | Tk_CreateImageType(&tkPhotoImageType); |
267 | ||
268 | /* | /* |
269 | * Create built-in photo image formats. | * Create built-in photo image formats. |
270 | */ | */ |
271 | ||
272 | Tk_CreatePhotoImageFormat(&tkImgFmtGIF); | Tk_CreatePhotoImageFormat(&tkImgFmtGIF); |
273 | Tk_CreateOldPhotoImageFormat(&tkImgFmtPPM); | Tk_CreateOldPhotoImageFormat(&tkImgFmtPPM); |
274 | ||
275 | /* | /* |
276 | * Create exit handler to delete all windows when the application | * Create exit handler to delete all windows when the application |
277 | * exits. | * exits. |
278 | */ | */ |
279 | ||
280 | Tcl_CreateExitHandler(DeleteWindowsExitProc, (ClientData) NULL); | Tcl_CreateExitHandler(DeleteWindowsExitProc, (ClientData) NULL); |
281 | } | } |
282 | ||
283 | if ((parent != NULL) && (screenName != NULL) && (screenName[0] == '\0')) { | if ((parent != NULL) && (screenName != NULL) && (screenName[0] == '\0')) { |
284 | dispPtr = ((TkWindow *) parent)->dispPtr; | dispPtr = ((TkWindow *) parent)->dispPtr; |
285 | screenId = Tk_ScreenNumber(parent); | screenId = Tk_ScreenNumber(parent); |
286 | } else { | } else { |
287 | dispPtr = GetScreen(interp, screenName, &screenId); | dispPtr = GetScreen(interp, screenName, &screenId); |
288 | if (dispPtr == NULL) { | if (dispPtr == NULL) { |
289 | return (Tk_Window) NULL; | return (Tk_Window) NULL; |
290 | } | } |
291 | } | } |
292 | ||
293 | winPtr = TkAllocWindow(dispPtr, screenId, (TkWindow *) parent); | winPtr = TkAllocWindow(dispPtr, screenId, (TkWindow *) parent); |
294 | ||
295 | /* | /* |
296 | * Force the window to use a border pixel instead of border pixmap. | * Force the window to use a border pixel instead of border pixmap. |
297 | * This is needed for the case where the window doesn't use the | * This is needed for the case where the window doesn't use the |
298 | * default visual. In this case, the default border is a pixmap | * default visual. In this case, the default border is a pixmap |
299 | * inherited from the root window, which won't work because it will | * inherited from the root window, which won't work because it will |
300 | * have the wrong visual. | * have the wrong visual. |
301 | */ | */ |
302 | ||
303 | winPtr->dirtyAtts |= CWBorderPixel; | winPtr->dirtyAtts |= CWBorderPixel; |
304 | ||
305 | /* | /* |
306 | * (Need to set the TK_TOP_LEVEL flag immediately here; otherwise | * (Need to set the TK_TOP_LEVEL flag immediately here; otherwise |
307 | * Tk_DestroyWindow will core dump if it is called before the flag | * Tk_DestroyWindow will core dump if it is called before the flag |
308 | * has been set.) | * has been set.) |
309 | */ | */ |
310 | ||
311 | winPtr->flags |= TK_TOP_LEVEL; | winPtr->flags |= TK_TOP_LEVEL; |
312 | ||
313 | if (parent != NULL) { | if (parent != NULL) { |
314 | if (NameWindow(interp, winPtr, (TkWindow *) parent, name) != TCL_OK) { | if (NameWindow(interp, winPtr, (TkWindow *) parent, name) != TCL_OK) { |
315 | Tk_DestroyWindow((Tk_Window) winPtr); | Tk_DestroyWindow((Tk_Window) winPtr); |
316 | return (Tk_Window) NULL; | return (Tk_Window) NULL; |
317 | } | } |
318 | } | } |
319 | TkWmNewWindow(winPtr); | TkWmNewWindow(winPtr); |
320 | ||
321 | return (Tk_Window) winPtr; | return (Tk_Window) winPtr; |
322 | } | } |
323 | ||
324 | /* | /* |
325 | *---------------------------------------------------------------------- | *---------------------------------------------------------------------- |
326 | * | * |
327 | * GetScreen -- | * GetScreen -- |
328 | * | * |
329 | * Given a string name for a display-plus-screen, find the | * Given a string name for a display-plus-screen, find the |
330 | * TkDisplay structure for the display and return the screen | * TkDisplay structure for the display and return the screen |
331 | * number too. | * number too. |
332 | * | * |
333 | * Results: | * Results: |
334 | * The return value is a pointer to information about the display, | * The return value is a pointer to information about the display, |
335 | * or NULL if the display couldn't be opened. In this case, an | * or NULL if the display couldn't be opened. In this case, an |
336 | * error message is left in the interp's result. The location at | * error message is left in the interp's result. The location at |
337 | * *screenPtr is overwritten with the screen number parsed from | * *screenPtr is overwritten with the screen number parsed from |
338 | * screenName. | * screenName. |
339 | * | * |
340 | * Side effects: | * Side effects: |
341 | * A new connection is opened to the display if there is no | * A new connection is opened to the display if there is no |
342 | * connection already. A new TkDisplay data structure is also | * connection already. A new TkDisplay data structure is also |
343 | * setup, if necessary. | * setup, if necessary. |
344 | * | * |
345 | *---------------------------------------------------------------------- | *---------------------------------------------------------------------- |
346 | */ | */ |
347 | ||
348 | static TkDisplay * | static TkDisplay * |
349 | GetScreen(interp, screenName, screenPtr) | GetScreen(interp, screenName, screenPtr) |
350 | Tcl_Interp *interp; /* Place to leave error message. */ | Tcl_Interp *interp; /* Place to leave error message. */ |
351 | char *screenName; /* Name for screen. NULL or empty means | char *screenName; /* Name for screen. NULL or empty means |
352 | * use DISPLAY envariable. */ | * use DISPLAY envariable. */ |
353 | int *screenPtr; /* Where to store screen number. */ | int *screenPtr; /* Where to store screen number. */ |
354 | { | { |
355 | register TkDisplay *dispPtr; | register TkDisplay *dispPtr; |
356 | char *p; | char *p; |
357 | int screenId; | int screenId; |
358 | size_t length; | size_t length; |
359 | ThreadSpecificData *tsdPtr = (ThreadSpecificData *) | ThreadSpecificData *tsdPtr = (ThreadSpecificData *) |
360 | Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); | Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); |
361 | ||
362 | /* | /* |
363 | * Separate the screen number from the rest of the display | * Separate the screen number from the rest of the display |
364 | * name. ScreenName is assumed to have the syntax | * name. ScreenName is assumed to have the syntax |
365 | * <display>.<screen> with the dot and the screen being | * <display>.<screen> with the dot and the screen being |
366 | * optional. | * optional. |
367 | */ | */ |
368 | ||
369 | screenName = TkGetDefaultScreenName(interp, screenName); | screenName = TkGetDefaultScreenName(interp, screenName); |
370 | if (screenName == NULL) { | if (screenName == NULL) { |
371 | Tcl_SetResult(interp, | Tcl_SetResult(interp, |
372 | "no display name and no $DISPLAY environment variable", | "no display name and no $DISPLAY environment variable", |
373 | TCL_STATIC); | TCL_STATIC); |
374 | return (TkDisplay *) NULL; | return (TkDisplay *) NULL; |
375 | } | } |
376 | length = strlen(screenName); | length = strlen(screenName); |
377 | screenId = 0; | screenId = 0; |
378 | p = screenName+length-1; | p = screenName+length-1; |
379 | while (isdigit(UCHAR(*p)) && (p != screenName)) { | while (isdigit(UCHAR(*p)) && (p != screenName)) { |
380 | p--; | p--; |
381 | } | } |
382 | if ((*p == '.') && (p[1] != '\0')) { | if ((*p == '.') && (p[1] != '\0')) { |
383 | length = p - screenName; | length = p - screenName; |
384 | screenId = strtoul(p+1, (char **) NULL, 10); | screenId = strtoul(p+1, (char **) NULL, 10); |
385 | } | } |
386 | ||
387 | /* | /* |
388 | * See if we already have a connection to this display. If not, | * See if we already have a connection to this display. If not, |
389 | * then open a new connection. | * then open a new connection. |
390 | */ | */ |
391 | ||
392 | for (dispPtr = TkGetDisplayList(); ; dispPtr = dispPtr->nextPtr) { | for (dispPtr = TkGetDisplayList(); ; dispPtr = dispPtr->nextPtr) { |
393 | if (dispPtr == NULL) { | if (dispPtr == NULL) { |
394 | dispPtr = TkpOpenDisplay(screenName); | dispPtr = TkpOpenDisplay(screenName); |
395 | if (dispPtr == NULL) { | if (dispPtr == NULL) { |
396 | Tcl_AppendResult(interp, "couldn't connect to display \"", | Tcl_AppendResult(interp, "couldn't connect to display \"", |
397 | screenName, "\"", (char *) NULL); | screenName, "\"", (char *) NULL); |
398 | return (TkDisplay *) NULL; | return (TkDisplay *) NULL; |
399 | } | } |
400 | dispPtr->nextPtr = TkGetDisplayList(); | dispPtr->nextPtr = TkGetDisplayList(); |
401 | dispPtr->name = (char *) ckalloc((unsigned) (length+1)); | dispPtr->name = (char *) ckalloc((unsigned) (length+1)); |
402 | dispPtr->lastEventTime = CurrentTime; | dispPtr->lastEventTime = CurrentTime; |
403 | dispPtr->borderInit = 0; | dispPtr->borderInit = 0; |
404 | dispPtr->atomInit = 0; | dispPtr->atomInit = 0; |
405 | dispPtr->bindInfoStale = 1; | dispPtr->bindInfoStale = 1; |
406 | dispPtr->modeModMask = 0; | dispPtr->modeModMask = 0; |
407 | dispPtr->metaModMask = 0; | dispPtr->metaModMask = 0; |
408 | dispPtr->altModMask = 0; | dispPtr->altModMask = 0; |
409 | dispPtr->numModKeyCodes = 0; | dispPtr->numModKeyCodes = 0; |
410 | dispPtr->modKeyCodes = NULL; | dispPtr->modKeyCodes = NULL; |
411 | dispPtr->bitmapInit = 0; | dispPtr->bitmapInit = 0; |
412 | dispPtr->bitmapAutoNumber = 0; | dispPtr->bitmapAutoNumber = 0; |
413 | dispPtr->numIdSearches = 0; | dispPtr->numIdSearches = 0; |
414 | dispPtr->numSlowSearches = 0; | dispPtr->numSlowSearches = 0; |
415 | dispPtr->colorInit = 0; | dispPtr->colorInit = 0; |
416 | dispPtr->stressPtr = NULL; | dispPtr->stressPtr = NULL; |
417 | dispPtr->cursorInit = 0; | dispPtr->cursorInit = 0; |
418 | dispPtr->cursorString[0] = '\0'; | dispPtr->cursorString[0] = '\0'; |
419 | dispPtr->cursorFont = None; | dispPtr->cursorFont = None; |
420 | dispPtr->errorPtr = NULL; | dispPtr->errorPtr = NULL; |
421 | dispPtr->deleteCount = 0; | dispPtr->deleteCount = 0; |
422 | dispPtr->delayedMotionPtr = NULL; | dispPtr->delayedMotionPtr = NULL; |
423 | dispPtr->focusDebug = 0; | dispPtr->focusDebug = 0; |
424 | dispPtr->implicitWinPtr = NULL; | dispPtr->implicitWinPtr = NULL; |
425 | dispPtr->focusPtr = NULL; | dispPtr->focusPtr = NULL; |
426 | dispPtr->gcInit = 0; | dispPtr->gcInit = 0; |
427 | dispPtr->geomInit = 0; | dispPtr->geomInit = 0; |
428 | dispPtr->uidInit = 0; | dispPtr->uidInit = 0; |
429 | dispPtr->grabWinPtr = NULL; | dispPtr->grabWinPtr = NULL; |
430 | dispPtr->eventualGrabWinPtr = NULL; | dispPtr->eventualGrabWinPtr = NULL; |
431 | dispPtr->buttonWinPtr = NULL; | dispPtr->buttonWinPtr = NULL; |
432 | dispPtr->serverWinPtr = NULL; | dispPtr->serverWinPtr = NULL; |
433 | dispPtr->firstGrabEventPtr = NULL; | dispPtr->firstGrabEventPtr = NULL; |
434 | dispPtr->lastGrabEventPtr = NULL; | dispPtr->lastGrabEventPtr = NULL; |
435 | dispPtr->grabFlags = 0; | dispPtr->grabFlags = 0; |
436 | dispPtr->mouseButtonState = 0; | dispPtr->mouseButtonState = 0; |
437 | dispPtr->warpInProgress = 0; | dispPtr->warpInProgress = 0; |
438 | dispPtr->warpWindow = None; | dispPtr->warpWindow = None; |
439 | dispPtr->warpX = 0; | dispPtr->warpX = 0; |
440 | dispPtr->warpY = 0; | dispPtr->warpY = 0; |
441 | dispPtr->gridInit = 0; | dispPtr->gridInit = 0; |
442 | dispPtr->imageId = 0; | dispPtr->imageId = 0; |
443 | dispPtr->packInit = 0; | dispPtr->packInit = 0; |
444 | dispPtr->placeInit = 0; | dispPtr->placeInit = 0; |
445 | dispPtr->selectionInfoPtr = NULL; | dispPtr->selectionInfoPtr = NULL; |
446 | dispPtr->multipleAtom = None; | dispPtr->multipleAtom = None; |
447 | dispPtr->clipWindow = NULL; | dispPtr->clipWindow = NULL; |
448 | dispPtr->clipboardActive = 0; | dispPtr->clipboardActive = 0; |
449 | dispPtr->clipboardAppPtr = NULL; | dispPtr->clipboardAppPtr = NULL; |
450 | dispPtr->clipTargetPtr = NULL; | dispPtr->clipTargetPtr = NULL; |
451 | dispPtr->commTkwin = NULL; | dispPtr->commTkwin = NULL; |
452 | dispPtr->wmTracing = 0; | dispPtr->wmTracing = 0; |
453 | dispPtr->firstWmPtr = NULL; | dispPtr->firstWmPtr = NULL; |
454 | dispPtr->foregroundWmPtr = NULL; | dispPtr->foregroundWmPtr = NULL; |
455 | dispPtr->destroyCount = 0; | dispPtr->destroyCount = 0; |
456 | dispPtr->lastDestroyRequest = 0; | dispPtr->lastDestroyRequest = 0; |
457 | dispPtr->cmapPtr = NULL; | dispPtr->cmapPtr = NULL; |
458 | Tcl_InitHashTable(&dispPtr->winTable, TCL_ONE_WORD_KEYS); | Tcl_InitHashTable(&dispPtr->winTable, TCL_ONE_WORD_KEYS); |
459 | ||
460 | dispPtr->refCount = 0; | dispPtr->refCount = 0; |
461 | strncpy(dispPtr->name, screenName, length); | strncpy(dispPtr->name, screenName, length); |
462 | dispPtr->name[length] = '\0'; | dispPtr->name[length] = '\0'; |
463 | dispPtr->useInputMethods = 0; | dispPtr->useInputMethods = 0; |
464 | OpenIM(dispPtr); | OpenIM(dispPtr); |
465 | TkInitXId(dispPtr); | TkInitXId(dispPtr); |
466 | ||
467 | tsdPtr->displayList = dispPtr; | tsdPtr->displayList = dispPtr; |
468 | break; | break; |
469 | } | } |
470 | if ((strncmp(dispPtr->name, screenName, length) == 0) | if ((strncmp(dispPtr->name, screenName, length) == 0) |
471 | && (dispPtr->name[length] == '\0')) { | && (dispPtr->name[length] == '\0')) { |
472 | break; | break; |
473 | } | } |
474 | } | } |
475 | if (screenId >= ScreenCount(dispPtr->display)) { | if (screenId >= ScreenCount(dispPtr->display)) { |
476 | char buf[32 + TCL_INTEGER_SPACE]; | char buf[32 + TCL_INTEGER_SPACE]; |
477 | ||
478 | sprintf(buf, "bad screen number \"%d\"", screenId); | sprintf(buf, "bad screen number \"%d\"", screenId); |
479 | Tcl_SetResult(interp, buf, TCL_VOLATILE); | Tcl_SetResult(interp, buf, TCL_VOLATILE); |
480 | return (TkDisplay *) NULL; | return (TkDisplay *) NULL; |
481 | } | } |
482 | *screenPtr = screenId; | *screenPtr = screenId; |
483 | return dispPtr; | return dispPtr; |
484 | } | } |
485 | ||
486 | /* | /* |
487 | *---------------------------------------------------------------------- | *---------------------------------------------------------------------- |
488 | * | * |
489 | * TkGetDisplay -- | * TkGetDisplay -- |
490 | * | * |
491 | * Given an X display, TkGetDisplay returns the TkDisplay | * Given an X display, TkGetDisplay returns the TkDisplay |
492 | * structure for the display. | * structure for the display. |
493 | * | * |
494 | * Results: | * Results: |
495 | * The return value is a pointer to information about the display, | * The return value is a pointer to information about the display, |
496 | * or NULL if the display did not have a TkDisplay structure. | * or NULL if the display did not have a TkDisplay structure. |
497 | * | * |
498 | * Side effects: | * Side effects: |
499 | * None. | * None. |
500 | * | * |
501 | *---------------------------------------------------------------------- | *---------------------------------------------------------------------- |
502 | */ | */ |
503 | ||
504 | TkDisplay * | TkDisplay * |
505 | TkGetDisplay(display) | TkGetDisplay(display) |
506 | Display *display; /* X's display pointer */ | Display *display; /* X's display pointer */ |
507 | { | { |
508 | TkDisplay *dispPtr; | TkDisplay *dispPtr; |
509 | ThreadSpecificData *tsdPtr = (ThreadSpecificData *) | ThreadSpecificData *tsdPtr = (ThreadSpecificData *) |
510 | Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); | Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); |
511 | ||
512 | for (dispPtr = tsdPtr->displayList; dispPtr != NULL; | for (dispPtr = tsdPtr->displayList; dispPtr != NULL; |
513 | dispPtr = dispPtr->nextPtr) { | dispPtr = dispPtr->nextPtr) { |
514 | if (dispPtr->display == display) { | if (dispPtr->display == display) { |
515 | break; | break; |
516 | } | } |
517 | } | } |
518 | return dispPtr; | return dispPtr; |
519 | } | } |
520 | ||
521 | /* | /* |
522 | *-------------------------------------------------------------- | *-------------------------------------------------------------- |
523 | * | * |
524 | * TkGetDisplayList -- | * TkGetDisplayList -- |
525 | * | * |
526 | * This procedure returns a pointer to the thread-local | * This procedure returns a pointer to the thread-local |
527 | * list of TkDisplays corresponding to the open displays. | * list of TkDisplays corresponding to the open displays. |
528 | * | * |
529 | * Results: | * Results: |
530 | * The return value is a pointer to the first TkDisplay | * The return value is a pointer to the first TkDisplay |
531 | * structure in thread-local-storage. | * structure in thread-local-storage. |
532 | * | * |
533 | * Side effects: | * Side effects: |
534 | * None. | * None. |
535 | * | * |
536 | *-------------------------------------------------------------- | *-------------------------------------------------------------- |
537 | */ | */ |
538 | TkDisplay * | TkDisplay * |
539 | TkGetDisplayList() | TkGetDisplayList() |
540 | { | { |
541 | ThreadSpecificData *tsdPtr = (ThreadSpecificData *) | ThreadSpecificData *tsdPtr = (ThreadSpecificData *) |
542 | Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); | Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); |
543 | ||
544 | return tsdPtr->displayList; | return tsdPtr->displayList; |
545 | } | } |
546 | ||
547 | /* | /* |
548 | *-------------------------------------------------------------- | *-------------------------------------------------------------- |
549 | * | * |
550 | * TkGetMainInfoList -- | * TkGetMainInfoList -- |
551 | * | * |
552 | * This procedure returns a pointer to the list of structures | * This procedure returns a pointer to the list of structures |
553 | * containing information about all main windows for the | * containing information about all main windows for the |
554 | * current thread. | * current thread. |
555 | * | * |
556 | * Results: | * Results: |
557 | * The return value is a pointer to the first TkMainInfo | * The return value is a pointer to the first TkMainInfo |
558 | * structure in thread local storage. | * structure in thread local storage. |
559 | * | * |
560 | * Side effects: | * Side effects: |
561 | * None. | * None. |
562 | * | * |
563 | *-------------------------------------------------------------- | *-------------------------------------------------------------- |
564 | */ | */ |
565 | TkMainInfo * | TkMainInfo * |
566 | TkGetMainInfoList() | TkGetMainInfoList() |
567 | { | { |
568 | ThreadSpecificData *tsdPtr = (ThreadSpecificData *) | ThreadSpecificData *tsdPtr = (ThreadSpecificData *) |
569 | Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); | Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); |
570 | ||
571 | return tsdPtr->mainWindowList; | return tsdPtr->mainWindowList; |
572 | } | } |
573 | /* | /* |
574 | *-------------------------------------------------------------- | *-------------------------------------------------------------- |
575 | * | * |
576 | * TkAllocWindow -- | * TkAllocWindow -- |
577 | * | * |
578 | * This procedure creates and initializes a TkWindow structure. | * This procedure creates and initializes a TkWindow structure. |
579 | * | * |
580 | * Results: | * Results: |
581 | * The return value is a pointer to the new window. | * The return value is a pointer to the new window. |
582 | * | * |
583 | * Side effects: | * Side effects: |
584 | * A new window structure is allocated and all its fields are | * A new window structure is allocated and all its fields are |
585 | * initialized. | * initialized. |
586 | * | * |
587 | *-------------------------------------------------------------- | *-------------------------------------------------------------- |
588 | */ | */ |
589 | ||
590 | TkWindow * | TkWindow * |
591 | TkAllocWindow(dispPtr, screenNum, parentPtr) | TkAllocWindow(dispPtr, screenNum, parentPtr) |
592 | TkDisplay *dispPtr; /* Display associated with new window. */ | TkDisplay *dispPtr; /* Display associated with new window. */ |
593 | int screenNum; /* Index of screen for new window. */ | int screenNum; /* Index of screen for new window. */ |
594 | TkWindow *parentPtr; /* Parent from which this window should | TkWindow *parentPtr; /* Parent from which this window should |
595 | * inherit visual information. NULL means | * inherit visual information. NULL means |
596 | * use screen defaults instead of | * use screen defaults instead of |
597 | * inheriting. */ | * inheriting. */ |
598 | { | { |
599 | register TkWindow *winPtr; | register TkWindow *winPtr; |
600 | ||
601 | winPtr = (TkWindow *) ckalloc(sizeof(TkWindow)); | winPtr = (TkWindow *) ckalloc(sizeof(TkWindow)); |
602 | winPtr->display = dispPtr->display; | winPtr->display = dispPtr->display; |
603 | winPtr->dispPtr = dispPtr; | winPtr->dispPtr = dispPtr; |
604 | winPtr->screenNum = screenNum; | winPtr->screenNum = screenNum; |
605 | if ((parentPtr != NULL) && (parentPtr->display == winPtr->display) | if ((parentPtr != NULL) && (parentPtr->display == winPtr->display) |
606 | && (parentPtr->screenNum == winPtr->screenNum)) { | && (parentPtr->screenNum == winPtr->screenNum)) { |
607 | winPtr->visual = parentPtr->visual; | winPtr->visual = parentPtr->visual; |
608 | winPtr->depth = parentPtr->depth; | winPtr->depth = parentPtr->depth; |
609 | } else { | } else { |
610 | winPtr->visual = DefaultVisual(dispPtr->display, screenNum); | winPtr->visual = DefaultVisual(dispPtr->display, screenNum); |
611 | winPtr->depth = DefaultDepth(dispPtr->display, screenNum); | winPtr->depth = DefaultDepth(dispPtr->display, screenNum); |
612 | } | } |
613 | winPtr->window = None; | winPtr->window = None; |
614 | winPtr->childList = NULL; | winPtr->childList = NULL; |
615 | winPtr->lastChildPtr = NULL; | winPtr->lastChildPtr = NULL; |
616 | winPtr->parentPtr = NULL; | winPtr->parentPtr = NULL; |
617 | winPtr->nextPtr = NULL; | winPtr->nextPtr = NULL; |
618 | winPtr->mainPtr = NULL; | winPtr->mainPtr = NULL; |
619 | winPtr->pathName = NULL; | winPtr->pathName = NULL; |
620 | winPtr->nameUid = NULL; | winPtr->nameUid = NULL; |
621 | winPtr->classUid = NULL; | winPtr->classUid = NULL; |
622 | winPtr->changes = defChanges; | winPtr->changes = defChanges; |
623 | winPtr->dirtyChanges = CWX|CWY|CWWidth|CWHeight|CWBorderWidth; | winPtr->dirtyChanges = CWX|CWY|CWWidth|CWHeight|CWBorderWidth; |
624 | winPtr->atts = defAtts; | winPtr->atts = defAtts; |
625 | if ((parentPtr != NULL) && (parentPtr->display == winPtr->display) | if ((parentPtr != NULL) && (parentPtr->display == winPtr->display) |
626 | && (parentPtr->screenNum == winPtr->screenNum)) { | && (parentPtr->screenNum == winPtr->screenNum)) { |
627 | winPtr->atts.colormap = parentPtr->atts.colormap; | winPtr->atts.colormap = parentPtr->atts.colormap; |
628 | } else { | } else { |
629 | winPtr->atts.colormap = DefaultColormap(dispPtr->display, screenNum); | winPtr->atts.colormap = DefaultColormap(dispPtr->display, screenNum); |
630 | } | } |
631 | winPtr->dirtyAtts = CWEventMask|CWColormap|CWBitGravity; | winPtr->dirtyAtts = CWEventMask|CWColormap|CWBitGravity; |
632 | winPtr->flags = 0; | winPtr->flags = 0; |
633 | winPtr->handlerList = NULL; | winPtr->handlerList = NULL; |
634 | #ifdef TK_USE_INPUT_METHODS | #ifdef TK_USE_INPUT_METHODS |
635 | winPtr->inputContext = NULL; | winPtr->inputContext = NULL; |
636 | #endif /* TK_USE_INPUT_METHODS */ | #endif /* TK_USE_INPUT_METHODS */ |
637 | winPtr->tagPtr = NULL; | winPtr->tagPtr = NULL; |
638 | winPtr->numTags = 0; | winPtr->numTags = 0; |
639 | winPtr->optionLevel = -1; | winPtr->optionLevel = -1; |
640 | winPtr->selHandlerList = NULL; | winPtr->selHandlerList = NULL; |
641 | winPtr->geomMgrPtr = NULL; | winPtr->geomMgrPtr = NULL; |
642 | winPtr->geomData = NULL; | winPtr->geomData = NULL; |
643 | winPtr->reqWidth = winPtr->reqHeight = 1; | winPtr->reqWidth = winPtr->reqHeight = 1; |
644 | winPtr->internalBorderWidth = 0; | winPtr->internalBorderWidth = 0; |
645 | winPtr->wmInfoPtr = NULL; | winPtr->wmInfoPtr = NULL; |
646 | winPtr->classProcsPtr = NULL; | winPtr->classProcsPtr = NULL; |
647 | winPtr->instanceData = NULL; | winPtr->instanceData = NULL; |
648 | winPtr->privatePtr = NULL; | winPtr->privatePtr = NULL; |
649 | ||
650 | return winPtr; | return winPtr; |
651 | } | } |
652 | ||
653 | /* | /* |
654 | *---------------------------------------------------------------------- | *---------------------------------------------------------------------- |
655 | * | * |
656 | * NameWindow -- | * NameWindow -- |
657 | * | * |
658 | * This procedure is invoked to give a window a name and insert | * This procedure is invoked to give a window a name and insert |
659 | * the window into the hierarchy associated with a particular | * the window into the hierarchy associated with a particular |
660 | * application. | * application. |
661 | * | * |
662 | * Results: | * Results: |
663 | * A standard Tcl return value. | * A standard Tcl return value. |
664 | * | * |
665 | * Side effects: | * Side effects: |
666 | * See above. | * See above. |
667 | * | * |
668 | *---------------------------------------------------------------------- | *---------------------------------------------------------------------- |
669 | */ | */ |
670 | ||
671 | static int | static int |
672 | NameWindow(interp, winPtr, parentPtr, name) | NameWindow(interp, winPtr, parentPtr, name) |
673 | Tcl_Interp *interp; /* Interpreter to use for error reporting. */ | Tcl_Interp *interp; /* Interpreter to use for error reporting. */ |
674 | register TkWindow *winPtr; /* Window that is to be named and inserted. */ | register TkWindow *winPtr; /* Window that is to be named and inserted. */ |
675 | TkWindow *parentPtr; /* Pointer to logical parent for winPtr | TkWindow *parentPtr; /* Pointer to logical parent for winPtr |
676 | * (used for naming, options, etc.). */ | * (used for naming, options, etc.). */ |
677 | char *name; /* Name for winPtr; must be unique among | char *name; /* Name for winPtr; must be unique among |
678 | * parentPtr's children. */ | * parentPtr's children. */ |
679 | { | { |
680 | #define FIXED_SIZE 200 | #define FIXED_SIZE 200 |
681 | char staticSpace[FIXED_SIZE]; | char staticSpace[FIXED_SIZE]; |
682 | char *pathName; | char *pathName; |
683 | int new; | int new; |
684 | Tcl_HashEntry *hPtr; | Tcl_HashEntry *hPtr; |
685 | int length1, length2; | int length1, length2; |
686 | ||
687 | /* | /* |
688 | * Setup all the stuff except name right away, then do the name stuff | * Setup all the stuff except name right away, then do the name stuff |
689 | * last. This is so that if the name stuff fails, everything else | * last. This is so that if the name stuff fails, everything else |
690 | * will be properly initialized (needed to destroy the window cleanly | * will be properly initialized (needed to destroy the window cleanly |
691 | * after the naming failure). | * after the naming failure). |
692 | */ | */ |
693 | winPtr->parentPtr = parentPtr; | winPtr->parentPtr = parentPtr; |
694 | winPtr->nextPtr = NULL; | winPtr->nextPtr = NULL; |
695 | if (parentPtr->childList == NULL) { | if (parentPtr->childList == NULL) { |
696 | parentPtr->childList = winPtr; | parentPtr->childList = winPtr; |
697 | } else { | } else { |
698 | parentPtr->lastChildPtr->nextPtr = winPtr; | parentPtr->lastChildPtr->nextPtr = winPtr; |
699 | } | } |
700 | parentPtr->lastChildPtr = winPtr; | parentPtr->lastChildPtr = winPtr; |
701 | winPtr->mainPtr = parentPtr->mainPtr; | winPtr->mainPtr = parentPtr->mainPtr; |
702 | winPtr->mainPtr->refCount++; | winPtr->mainPtr->refCount++; |
703 | winPtr->nameUid = Tk_GetUid(name); | winPtr->nameUid = Tk_GetUid(name); |
704 | ||
705 | /* | /* |
706 | * Don't permit names that start with an upper-case letter: this | * Don't permit names that start with an upper-case letter: this |
707 | * will just cause confusion with class names in the option database. | * will just cause confusion with class names in the option database. |
708 | */ | */ |
709 | ||
710 | if (isupper(UCHAR(name[0]))) { | if (isupper(UCHAR(name[0]))) { |
711 | Tcl_AppendResult(interp, | Tcl_AppendResult(interp, |
712 | "window name starts with an upper-case letter: \"", | "window name starts with an upper-case letter: \"", |
713 | name, "\"", (char *) NULL); | name, "\"", (char *) NULL); |
714 | return TCL_ERROR; | return TCL_ERROR; |
715 | } | } |
716 | ||
717 | /* | /* |
718 | * To permit names of arbitrary length, must be prepared to malloc | * To permit names of arbitrary length, must be prepared to malloc |
719 | * a buffer to hold the new path name. To run fast in the common | * a buffer to hold the new path name. To run fast in the common |
720 | * case where names are short, use a fixed-size buffer on the | * case where names are short, use a fixed-size buffer on the |
721 | * stack. | * stack. |
722 | */ | */ |
723 | ||
724 | length1 = strlen(parentPtr->pathName); | length1 = strlen(parentPtr->pathName); |
725 | length2 = strlen(name); | length2 = strlen(name); |
726 | if ((length1+length2+2) <= FIXED_SIZE) { | if ((length1+length2+2) <= FIXED_SIZE) { |
727 | pathName = staticSpace; | pathName = staticSpace; |
728 | } else { | } else { |
729 | pathName = (char *) ckalloc((unsigned) (length1+length2+2)); | pathName = (char *) ckalloc((unsigned) (length1+length2+2)); |
730 | } | } |
731 | if (length1 == 1) { | if (length1 == 1) { |
732 | pathName[0] = '.'; | pathName[0] = '.'; |
733 | strcpy(pathName+1, name); | strcpy(pathName+1, name); |
734 | } else { | } else { |
735 | strcpy(pathName, parentPtr->pathName); | strcpy(pathName, parentPtr->pathName); |
736 | pathName[length1] = '.'; | pathName[length1] = '.'; |
737 | strcpy(pathName+length1+1, name); | strcpy(pathName+length1+1, name); |
738 | } | } |
739 | hPtr = Tcl_CreateHashEntry(&parentPtr->mainPtr->nameTable, pathName, &new); | hPtr = Tcl_CreateHashEntry(&parentPtr->mainPtr->nameTable, pathName, &new); |
740 | if (pathName != staticSpace) { | if (pathName != staticSpace) { |
741 | ckfree(pathName); | ckfree(pathName); |
742 | } | } |
743 | if (!new) { | if (!new) { |
744 | Tcl_AppendResult(interp, "window name \"", name, | Tcl_AppendResult(interp, "window name \"", name, |
745 | "\" already exists in parent", (char *) NULL); | "\" already exists in parent", (char *) NULL); |
746 | return TCL_ERROR; | return TCL_ERROR; |
747 | } | } |
748 | Tcl_SetHashValue(hPtr, winPtr); | Tcl_SetHashValue(hPtr, winPtr); |
749 | winPtr->pathName = Tcl_GetHashKey(&parentPtr->mainPtr->nameTable, hPtr); | winPtr->pathName = Tcl_GetHashKey(&parentPtr->mainPtr->nameTable, hPtr); |
750 | return TCL_OK; | return TCL_OK; |
751 | } | } |
752 | ||
753 | /* | /* |
754 | *---------------------------------------------------------------------- | *---------------------------------------------------------------------- |
755 | * | * |
756 | * TkCreateMainWindow -- | * TkCreateMainWindow -- |
757 | * | * |
758 | * Make a new main window. A main window is a special kind of | * Make a new main window. A main window is a special kind of |
759 | * top-level window used as the outermost window in an | * top-level window used as the outermost window in an |
760 | * application. | * application. |
761 | * | * |
762 | * Results: | * Results: |
763 | * The return value is a token for the new window, or NULL if | * The return value is a token for the new window, or NULL if |
764 | * an error prevented the new window from being created. If | * an error prevented the new window from being created. If |
765 | * NULL is returned, an error message will be left in | * NULL is returned, an error message will be left in |
766 | * the interp's result. | * the interp's result. |
767 | * | * |
768 | * Side effects: | * Side effects: |
769 | * A new window structure is allocated locally; "interp" is | * A new window structure is allocated locally; "interp" is |
770 | * associated with the window and registered for "send" commands | * associated with the window and registered for "send" commands |
771 | * under "baseName". BaseName may be extended with an instance | * under "baseName". BaseName may be extended with an instance |
772 | * number in the form "#2" if necessary to make it globally | * number in the form "#2" if necessary to make it globally |
773 | * unique. Tk-related commands are bound into interp. | * unique. Tk-related commands are bound into interp. |
774 | * | * |
775 | *---------------------------------------------------------------------- | *---------------------------------------------------------------------- |
776 | */ | */ |
777 | ||
778 | Tk_Window | Tk_Window |
779 | TkCreateMainWindow(interp, screenName, baseName) | TkCreateMainWindow(interp, screenName, baseName) |
780 | Tcl_Interp *interp; /* Interpreter to use for error reporting. */ | Tcl_Interp *interp; /* Interpreter to use for error reporting. */ |
781 | char *screenName; /* Name of screen on which to create | char *screenName; /* Name of screen on which to create |
782 | * window. Empty or NULL string means | * window. Empty or NULL string means |
783 | * use DISPLAY environment variable. */ | * use DISPLAY environment variable. */ |
784 | char *baseName; /* Base name for application; usually of the | char *baseName; /* Base name for application; usually of the |
785 | * form "prog instance". */ | * form "prog instance". */ |
786 | { | { |
787 | Tk_Window tkwin; | Tk_Window tkwin; |
788 | int dummy; | int dummy; |
789 | int isSafe; | int isSafe; |
790 | Tcl_HashEntry *hPtr; | Tcl_HashEntry *hPtr; |
791 | register TkMainInfo *mainPtr; | register TkMainInfo *mainPtr; |
792 | register TkWindow *winPtr; | register TkWindow *winPtr; |
793 | register TkCmd *cmdPtr; | register TkCmd *cmdPtr; |
794 | ClientData clientData; | ClientData clientData; |
795 | ThreadSpecificData *tsdPtr = (ThreadSpecificData *) | ThreadSpecificData *tsdPtr = (ThreadSpecificData *) |
796 | Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); | Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); |
797 | ||
798 | /* | /* |
799 | * Panic if someone updated the TkWindow structure without | * Panic if someone updated the TkWindow structure without |
800 | * also updating the Tk_FakeWin structure (or vice versa). | * also updating the Tk_FakeWin structure (or vice versa). |
801 | */ | */ |
802 | ||
803 | if (sizeof(TkWindow) != sizeof(Tk_FakeWin)) { | if (sizeof(TkWindow) != sizeof(Tk_FakeWin)) { |
804 | panic("TkWindow and Tk_FakeWin are not the same size"); | panic("TkWindow and Tk_FakeWin are not the same size"); |
805 | } | } |
806 | ||
807 | /* | /* |
808 | * Create the basic TkWindow structure. | * Create the basic TkWindow structure. |
809 | */ | */ |
810 | ||
811 | tkwin = CreateTopLevelWindow(interp, (Tk_Window) NULL, baseName, | tkwin = CreateTopLevelWindow(interp, (Tk_Window) NULL, baseName, |
812 | screenName); | screenName); |
813 | if (tkwin == NULL) { | if (tkwin == NULL) { |
814 | return NULL; | return NULL; |
815 | } | } |
816 | ||
817 | /* | /* |
818 | * Create the TkMainInfo structure for this application, and set | * Create the TkMainInfo structure for this application, and set |
819 | * up name-related information for the new window. | * up name-related information for the new window. |
820 | */ | */ |
821 | ||
822 | winPtr = (TkWindow *) tkwin; | winPtr = (TkWindow *) tkwin; |
823 | mainPtr = (TkMainInfo *) ckalloc(sizeof(TkMainInfo)); | mainPtr = (TkMainInfo *) ckalloc(sizeof(TkMainInfo)); |
824 | mainPtr->winPtr = winPtr; | mainPtr->winPtr = winPtr; |
825 | mainPtr->refCount = 1; | mainPtr->refCount = 1; |
826 | mainPtr->interp = interp; | mainPtr->interp = interp; |
827 | Tcl_InitHashTable(&mainPtr->nameTable, TCL_STRING_KEYS); | Tcl_InitHashTable(&mainPtr->nameTable, TCL_STRING_KEYS); |
828 | TkEventInit(); | TkEventInit(); |
829 | TkBindInit(mainPtr); | TkBindInit(mainPtr); |
830 | TkFontPkgInit(mainPtr); | TkFontPkgInit(mainPtr); |
831 | mainPtr->tlFocusPtr = NULL; | mainPtr->tlFocusPtr = NULL; |
832 | mainPtr->displayFocusPtr = NULL; | mainPtr->displayFocusPtr = NULL; |
833 | mainPtr->optionRootPtr = NULL; | mainPtr->optionRootPtr = NULL; |
834 | Tcl_InitHashTable(&mainPtr->imageTable, TCL_STRING_KEYS); | Tcl_InitHashTable(&mainPtr->imageTable, TCL_STRING_KEYS); |
835 | mainPtr->strictMotif = 0; | mainPtr->strictMotif = 0; |
836 | if (Tcl_LinkVar(interp, "tk_strictMotif", (char *) &mainPtr->strictMotif, | if (Tcl_LinkVar(interp, "tk_strictMotif", (char *) &mainPtr->strictMotif, |
837 | TCL_LINK_BOOLEAN) != TCL_OK) { | TCL_LINK_BOOLEAN) != TCL_OK) { |
838 | Tcl_ResetResult(interp); | Tcl_ResetResult(interp); |
839 | } | } |
840 | mainPtr->nextPtr = tsdPtr->mainWindowList; | mainPtr->nextPtr = tsdPtr->mainWindowList; |
841 | tsdPtr->mainWindowList = mainPtr; | tsdPtr->mainWindowList = mainPtr; |
842 | winPtr->mainPtr = mainPtr; | winPtr->mainPtr = mainPtr; |
843 | hPtr = Tcl_CreateHashEntry(&mainPtr->nameTable, ".", &dummy); | hPtr = Tcl_CreateHashEntry(&mainPtr->nameTable, ".", &dummy); |
844 | Tcl_SetHashValue(hPtr, winPtr); | Tcl_SetHashValue(hPtr, winPtr); |
845 | winPtr->pathName = Tcl_GetHashKey(&mainPtr->nameTable, hPtr); | winPtr->pathName = Tcl_GetHashKey(&mainPtr->nameTable, hPtr); |
846 | ||
847 | /* | /* |
848 | * We have just created another Tk application; increment the refcount | * We have just created another Tk application; increment the refcount |
849 | * on the display pointer. | * on the display pointer. |
850 | */ | */ |
851 | ||
852 | winPtr->dispPtr->refCount++; | winPtr->dispPtr->refCount++; |
853 | ||
854 | /* | /* |
855 | * Register the interpreter for "send" purposes. | * Register the interpreter for "send" purposes. |
856 | */ | */ |
857 | ||
858 | winPtr->nameUid = Tk_GetUid(Tk_SetAppName(tkwin, baseName)); | winPtr->nameUid = Tk_GetUid(Tk_SetAppName(tkwin, baseName)); |
859 | ||
860 | /* | /* |
861 | * Bind in Tk's commands. | * Bind in Tk's commands. |
862 | */ | */ |
863 | ||
864 | isSafe = Tcl_IsSafe(interp); | isSafe = Tcl_IsSafe(interp); |
865 | for (cmdPtr = commands; cmdPtr->name != NULL; cmdPtr++) { | for (cmdPtr = commands; cmdPtr->name != NULL; cmdPtr++) { |
866 | if ((cmdPtr->cmdProc == NULL) && (cmdPtr->objProc == NULL)) { | if ((cmdPtr->cmdProc == NULL) && (cmdPtr->objProc == NULL)) { |
867 | panic("TkCreateMainWindow: builtin command with NULL string and object procs"); | panic("TkCreateMainWindow: builtin command with NULL string and object procs"); |
868 | } | } |
869 | if (cmdPtr->passMainWindow) { | if (cmdPtr->passMainWindow) { |
870 | clientData = (ClientData) tkwin; | clientData = (ClientData) tkwin; |
871 | } else { | } else { |
872 | clientData = (ClientData) NULL; | clientData = (ClientData) NULL; |
873 | } | } |
874 | if (cmdPtr->cmdProc != NULL) { | if (cmdPtr->cmdProc != NULL) { |
875 | Tcl_CreateCommand(interp, cmdPtr->name, cmdPtr->cmdProc, | Tcl_CreateCommand(interp, cmdPtr->name, cmdPtr->cmdProc, |
876 | clientData, (void (*) _ANSI_ARGS_((ClientData))) NULL); | clientData, (void (*) _ANSI_ARGS_((ClientData))) NULL); |
877 | } else { | } else { |
878 | Tcl_CreateObjCommand(interp, cmdPtr->name, cmdPtr->objProc, | Tcl_CreateObjCommand(interp, cmdPtr->name, cmdPtr->objProc, |
879 | clientData, NULL); | clientData, NULL); |
880 | } | } |
881 | if (isSafe) { | if (isSafe) { |
882 | if (!(cmdPtr->isSafe)) { | if (!(cmdPtr->isSafe)) { |
883 | Tcl_HideCommand(interp, cmdPtr->name, cmdPtr->name); | Tcl_HideCommand(interp, cmdPtr->name, cmdPtr->name); |
884 | } | } |
885 | } | } |
886 | } | } |
887 | ||
888 | TkCreateMenuCmd(interp); | TkCreateMenuCmd(interp); |
889 | ||
890 | /* | /* |
891 | * Set variables for the intepreter. | * Set variables for the intepreter. |
892 | */ | */ |
893 | ||
894 | Tcl_SetVar(interp, "tk_patchLevel", TK_PATCH_LEVEL, TCL_GLOBAL_ONLY); | Tcl_SetVar(interp, "tk_patchLevel", TK_PATCH_LEVEL, TCL_GLOBAL_ONLY); |
895 | Tcl_SetVar(interp, "tk_version", TK_VERSION, TCL_GLOBAL_ONLY); | Tcl_SetVar(interp, "tk_version", TK_VERSION, TCL_GLOBAL_ONLY); |
896 | ||
897 | tsdPtr->numMainWindows++; | tsdPtr->numMainWindows++; |
898 | return tkwin; | return tkwin; |
899 | } | } |
900 | ||
901 | /* | /* |
902 | *-------------------------------------------------------------- | *-------------------------------------------------------------- |
903 | * | * |
904 | * Tk_CreateWindow -- | * Tk_CreateWindow -- |
905 | * | * |
906 | * Create a new internal or top-level window as a child of an | * Create a new internal or top-level window as a child of an |
907 | * existing window. | * existing window. |
908 | * | * |
909 | * Results: | * Results: |
910 | * The return value is a token for the new window. This | * The return value is a token for the new window. This |
911 | * is not the same as X's token for the window. If an error | * is not the same as X's token for the window. If an error |
912 | * occurred in creating the window (e.g. no such display or | * occurred in creating the window (e.g. no such display or |
913 | * screen), then an error message is left in the interp's result and | * screen), then an error message is left in the interp's result and |
914 | * NULL is returned. | * NULL is returned. |
915 | * | * |
916 | * Side effects: | * Side effects: |
917 | * A new window structure is allocated locally. An X | * A new window structure is allocated locally. An X |
918 | * window is not initially created, but will be created | * window is not initially created, but will be created |
919 | * the first time the window is mapped. | * the first time the window is mapped. |
920 | * | * |
921 | *-------------------------------------------------------------- | *-------------------------------------------------------------- |
922 | */ | */ |
923 | ||
924 | Tk_Window | Tk_Window |
925 | Tk_CreateWindow(interp, parent, name, screenName) | Tk_CreateWindow(interp, parent, name, screenName) |
926 | Tcl_Interp *interp; /* Interpreter to use for error reporting. | Tcl_Interp *interp; /* Interpreter to use for error reporting. |
927 | * the interp's result is assumed to be | * the interp's result is assumed to be |
928 | * initialized by the caller. */ | * initialized by the caller. */ |
929 | Tk_Window parent; /* Token for parent of new window. */ | Tk_Window parent; /* Token for parent of new window. */ |
930 | char *name; /* Name for new window. Must be unique | char *name; /* Name for new window. Must be unique |
931 | * among parent's children. */ | * among parent's children. */ |
932 | char *screenName; /* If NULL, new window will be internal on | char *screenName; /* If NULL, new window will be internal on |
933 | * same screen as its parent. If non-NULL, | * same screen as its parent. If non-NULL, |
934 | * gives name of screen on which to create | * gives name of screen on which to create |
935 | * new window; window will be a top-level | * new window; window will be a top-level |
936 | * window. */ | * window. */ |
937 | { | { |
938 | TkWindow *parentPtr = (TkWindow *) parent; | TkWindow *parentPtr = (TkWindow *) parent; |
939 | TkWindow *winPtr; | TkWindow *winPtr; |
940 | ||
941 | if ((parentPtr != NULL) && (parentPtr->flags & TK_ALREADY_DEAD)) { | if ((parentPtr != NULL) && (parentPtr->flags & TK_ALREADY_DEAD)) { |
942 | Tcl_AppendResult(interp, | Tcl_AppendResult(interp, |
943 | "can't create window: parent has been destroyed", | "can't create window: parent has been destroyed", |
944 | (char *) NULL); | (char *) NULL); |
945 | return NULL; | return NULL; |
946 | } else if ((parentPtr != NULL) && | } else if ((parentPtr != NULL) && |
947 | (parentPtr->flags & TK_CONTAINER)) { | (parentPtr->flags & TK_CONTAINER)) { |
948 | Tcl_AppendResult(interp, | Tcl_AppendResult(interp, |
949 | "can't create window: its parent has -container = yes", | "can't create window: its parent has -container = yes", |
950 | (char *) NULL); | (char *) NULL); |
951 | return NULL; | return NULL; |
952 | } | } |
953 | if (screenName == NULL) { | if (screenName == NULL) { |
954 | winPtr = TkAllocWindow(parentPtr->dispPtr, parentPtr->screenNum, | winPtr = TkAllocWindow(parentPtr->dispPtr, parentPtr->screenNum, |
955 | parentPtr); | parentPtr); |
956 | if (NameWindow(interp, winPtr, parentPtr, name) != TCL_OK) { | if (NameWindow(interp, winPtr, parentPtr, name) != TCL_OK) { |
957 | Tk_DestroyWindow((Tk_Window) winPtr); | Tk_DestroyWindow((Tk_Window) winPtr); |
958 | return NULL; | return NULL; |
959 | } else { | } else { |
960 | return (Tk_Window) winPtr; | return (Tk_Window) winPtr; |
961 | } | } |
962 | } else { | } else { |
963 | return CreateTopLevelWindow(interp, parent, name, screenName); | return CreateTopLevelWindow(interp, parent, name, screenName); |
964 | } | } |
965 | } | } |
966 | ||
967 | /* | /* |
968 | *---------------------------------------------------------------------- | *---------------------------------------------------------------------- |
969 | * | * |
970 | * Tk_CreateWindowFromPath -- | * Tk_CreateWindowFromPath -- |
971 | * | * |
972 | * This procedure is similar to Tk_CreateWindow except that | * This procedure is similar to Tk_CreateWindow except that |
973 | * it uses a path name to create the window, rather than a | * it uses a path name to create the window, rather than a |
974 | * parent and a child name. | * parent and a child name. |
975 | * | * |
976 | * Results: | * Results: |
977 | * The return value is a token for the new window. This | * The return value is a token for the new window. This |
978 | * is not the same as X's token for the window. If an error | * is not the same as X's token for the window. If an error |
979 | * occurred in creating the window (e.g. no such display or | * occurred in creating the window (e.g. no such display or |
980 | * screen), then an error message is left in the interp's result and | * screen), then an error message is left in the interp's result and |
981 | * NULL is returned. | * NULL is returned. |
982 | * | * |
983 | * Side effects: | * Side effects: |
984 | * A new window structure is allocated locally. An X | * A new window structure is allocated locally. An X |
985 | * window is not initially created, but will be created | * window is not initially created, but will be created |
986 | * the first time the window is mapped. | * the first time the window is mapped. |
987 | * | * |
988 | *---------------------------------------------------------------------- | *---------------------------------------------------------------------- |
989 | */ | */ |
990 | ||
991 | Tk_Window | Tk_Window |
992 | Tk_CreateWindowFromPath(interp, tkwin, pathName, screenName) | Tk_CreateWindowFromPath(interp, tkwin, pathName, screenName) |
993 | Tcl_Interp *interp; /* Interpreter to use for error reporting. | Tcl_Interp *interp; /* Interpreter to use for error reporting. |
994 | * the interp's result is assumed to be | * the interp's result is assumed to be |
995 | * initialized by the caller. */ | * initialized by the caller. */ |
996 | Tk_Window tkwin; /* Token for any window in application | Tk_Window tkwin; /* Token for any window in application |
997 | * that is to contain new window. */ | * that is to contain new window. */ |
998 | char *pathName; /* Path name for new window within the | char *pathName; /* Path name for new window within the |
999 | * application of tkwin. The parent of | * application of tkwin. The parent of |
1000 | * this window must already exist, but | * this window must already exist, but |
1001 | * the window itself must not exist. */ | * the window itself must not exist. */ |
1002 | char *screenName; /* If NULL, new window will be on same | char *screenName; /* If NULL, new window will be on same |
1003 | * screen as its parent. If non-NULL, | * screen as its parent. If non-NULL, |
1004 | * gives name of screen on which to create | * gives name of screen on which to create |
1005 | * new window; window will be a top-level | * new window; window will be a top-level |
1006 | * window. */ | * window. */ |
1007 | { | { |
1008 | #define FIXED_SPACE 5 | #define FIXED_SPACE 5 |
1009 | char fixedSpace[FIXED_SPACE+1]; | char fixedSpace[FIXED_SPACE+1]; |
1010 | char *p; | char *p; |
1011 | Tk_Window parent; | Tk_Window parent; |
1012 | int numChars; | int numChars; |
1013 | ||
1014 | /* | /* |
1015 | * Strip the parent's name out of pathName (it's everything up | * Strip the parent's name out of pathName (it's everything up |
1016 | * to the last dot). There are two tricky parts: (a) must | * to the last dot). There are two tricky parts: (a) must |
1017 | * copy the parent's name somewhere else to avoid modifying | * copy the parent's name somewhere else to avoid modifying |
1018 | * the pathName string (for large names, space for the copy | * the pathName string (for large names, space for the copy |
1019 | * will have to be malloc'ed); (b) must special-case the | * will have to be malloc'ed); (b) must special-case the |
1020 | * situation where the parent is ".". | * situation where the parent is ".". |
1021 | */ | */ |
1022 | ||
1023 | p = strrchr(pathName, '.'); | p = strrchr(pathName, '.'); |
1024 | if (p == NULL) { | if (p == NULL) { |
1025 | Tcl_AppendResult(interp, "bad window path name \"", pathName, | Tcl_AppendResult(interp, "bad window path name \"", pathName, |
1026 | "\"", (char *) NULL); | "\"", (char *) NULL); |
1027 | return NULL; | return NULL; |
1028 | } | } |
1029 | numChars = p-pathName; | numChars = p-pathName; |
1030 | if (numChars > FIXED_SPACE) { | if (numChars > FIXED_SPACE) { |
1031 | p = (char *) ckalloc((unsigned) (numChars+1)); | p = (char *) ckalloc((unsigned) (numChars+1)); |
1032 | } else { | } else { |
1033 | p = fixedSpace; | p = fixedSpace; |
1034 | } | } |
1035 | if (numChars == 0) { | if (numChars == 0) { |
1036 | *p = '.'; | *p = '.'; |
1037 | p[1] = '\0'; | p[1] = '\0'; |
1038 | } else { | } else { |
1039 | strncpy(p, pathName, (size_t) numChars); | strncpy(p, pathName, (size_t) numChars); |
1040 | p[numChars] = '\0'; | p[numChars] = '\0'; |
1041 | } | } |
1042 | ||
1043 | /* | /* |
1044 | * Find the parent window. | * Find the parent window. |
1045 | */ | */ |
1046 | ||
1047 | parent = Tk_NameToWindow(interp, p, tkwin); | parent = Tk_NameToWindow(interp, p, tkwin); |
1048 | if (p != fixedSpace) { | if (p != fixedSpace) { |
1049 | ckfree(p); | ckfree(p); |
1050 | } | } |
1051 | if (parent == NULL) { | if (parent == NULL) { |
1052 | return NULL; | return NULL; |
1053 | } | } |
1054 | if (((TkWindow *) parent)->flags & TK_ALREADY_DEAD) { | if (((TkWindow *) parent)->flags & TK_ALREADY_DEAD) { |
1055 | Tcl_AppendResult(interp, | Tcl_AppendResult(interp, |
1056 | "can't create window: parent has been destroyed", (char *) NULL); | "can't create window: parent has been destroyed", (char *) NULL); |
1057 | return NULL; | return NULL; |
1058 | } else if (((TkWindow *) parent)->flags & TK_CONTAINER) { | } else if (((TkWindow *) parent)->flags & TK_CONTAINER) { |
1059 | Tcl_AppendResult(interp, | Tcl_AppendResult(interp, |
1060 | "can't create window: its parent has -container = yes", | "can't create window: its parent has -container = yes", |
1061 | (char *) NULL); | (char *) NULL); |
1062 | return NULL; | return NULL; |
1063 | } | } |
1064 | ||
1065 | /* | /* |
1066 | * Create the window. | * Create the window. |
1067 | */ | */ |
1068 | ||
1069 | if (screenName == NULL) { | if (screenName == NULL) { |
1070 | TkWindow *parentPtr = (TkWindow *) parent; | TkWindow *parentPtr = (TkWindow *) parent; |
1071 | TkWindow *winPtr; | TkWindow *winPtr; |
1072 | ||
1073 | winPtr = TkAllocWindow(parentPtr->dispPtr, parentPtr->screenNum, | winPtr = TkAllocWindow(parentPtr->dispPtr, parentPtr->screenNum, |
1074 | parentPtr); | parentPtr); |
1075 | if (NameWindow(interp, winPtr, parentPtr, pathName+numChars+1) | if (NameWindow(interp, winPtr, parentPtr, pathName+numChars+1) |
1076 | != TCL_OK) { | != TCL_OK) { |
1077 | Tk_DestroyWindow((Tk_Window) winPtr); | Tk_DestroyWindow((Tk_Window) winPtr); |
1078 | return NULL; | return NULL; |
1079 | } else { | } else { |
1080 | return (Tk_Window) winPtr; | return (Tk_Window) winPtr; |
1081 | } | } |
1082 | } else { | } else { |
1083 | return CreateTopLevelWindow(interp, parent, pathName+numChars+1, | return CreateTopLevelWindow(interp, parent, pathName+numChars+1, |
1084 | screenName); | screenName); |
1085 | } | } |
1086 | } | } |
1087 | ||
1088 | /* | /* |
1089 | *-------------------------------------------------------------- | *-------------------------------------------------------------- |
1090 | * | * |
1091 | * Tk_DestroyWindow -- | * Tk_DestroyWindow -- |
1092 | * | * |
1093 | * Destroy an existing window. After this call, the caller | * Destroy an existing window. After this call, the caller |
1094 | * should never again use the token. | * should never again use the token. |
1095 | * | * |
1096 | * Results: | * Results: |
1097 | * None. | * None. |
1098 | * | * |
1099 | * Side effects: | * Side effects: |
1100 | * The window is deleted, along with all of its children. | * The window is deleted, along with all of its children. |
1101 | * Relevant callback procedures are invoked. | * Relevant callback procedures are invoked. |
1102 | * | * |
1103 | *-------------------------------------------------------------- | *-------------------------------------------------------------- |
1104 | */ | */ |
1105 | ||
1106 | void | void |
1107 | Tk_DestroyWindow(tkwin) | Tk_DestroyWindow(tkwin) |
1108 | Tk_Window tkwin; /* Window to destroy. */ | Tk_Window tkwin; /* Window to destroy. */ |
1109 | { | { |
1110 | TkWindow *winPtr = (TkWindow *) tkwin; | TkWindow *winPtr = (TkWindow *) tkwin; |
1111 | TkDisplay *dispPtr = winPtr->dispPtr; | TkDisplay *dispPtr = winPtr->dispPtr; |
1112 | XEvent event; | XEvent event; |
1113 | ThreadSpecificData *tsdPtr = (ThreadSpecificData *) | ThreadSpecificData *tsdPtr = (ThreadSpecificData *) |
1114 | Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); | Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); |
1115 | ||
1116 | if (winPtr->flags & TK_ALREADY_DEAD) { | if (winPtr->flags & TK_ALREADY_DEAD) { |
1117 | /* | /* |
1118 | * A destroy event binding caused the window to be destroyed | * A destroy event binding caused the window to be destroyed |
1119 | * again. Ignore the request. | * again. Ignore the request. |
1120 | */ | */ |
1121 | ||
1122 | return; | return; |
1123 | } | } |
1124 | winPtr->flags |= TK_ALREADY_DEAD; | winPtr->flags |= TK_ALREADY_DEAD; |
1125 | ||
1126 | /* | /* |
1127 | * Some cleanup needs to be done immediately, rather than later, | * Some cleanup needs to be done immediately, rather than later, |
1128 | * because it needs information that will be destoyed before we | * because it needs information that will be destoyed before we |
1129 | * get to the main cleanup point. For example, TkFocusDeadWindow | * get to the main cleanup point. For example, TkFocusDeadWindow |
1130 | * needs to access the parentPtr field from a window, but if | * needs to access the parentPtr field from a window, but if |
1131 | * a Destroy event handler deletes the window's parent this | * a Destroy event handler deletes the window's parent this |
1132 | * field will be NULL before the main cleanup point is reached. | * field will be NULL before the main cleanup point is reached. |
1133 | */ | */ |
1134 | ||
1135 | TkFocusDeadWindow(winPtr); | TkFocusDeadWindow(winPtr); |
1136 | ||
1137 | /* | /* |
1138 | * If this is a main window, remove it from the list of main | * If this is a main window, remove it from the list of main |
1139 | * windows. This needs to be done now (rather than later with | * windows. This needs to be done now (rather than later with |
1140 | * all the other main window cleanup) to handle situations where | * all the other main window cleanup) to handle situations where |
1141 | * a destroy binding for a window calls "exit". In this case | * a destroy binding for a window calls "exit". In this case |
1142 | * the child window cleanup isn't complete when exit is called, | * the child window cleanup isn't complete when exit is called, |
1143 | * so the reference count of its application doesn't go to zero | * so the reference count of its application doesn't go to zero |
1144 | * when exit calls Tk_DestroyWindow on ".", so the main window | * when exit calls Tk_DestroyWindow on ".", so the main window |
1145 | * doesn't get removed from the list and exit loops infinitely. | * doesn't get removed from the list and exit loops infinitely. |
1146 | * Even worse, if "destroy ." is called by the destroy binding | * Even worse, if "destroy ." is called by the destroy binding |
1147 | * before calling "exit", "exit" will attempt to destroy | * before calling "exit", "exit" will attempt to destroy |
1148 | * mainPtr->winPtr, which no longer exists, and there may be a | * mainPtr->winPtr, which no longer exists, and there may be a |
1149 | * core dump. | * core dump. |
1150 | * | * |
1151 | * Also decrement the display refcount so that if this is the | * Also decrement the display refcount so that if this is the |
1152 | * last Tk application in this process on this display, the display | * last Tk application in this process on this display, the display |
1153 | * can be closed and its data structures deleted. | * can be closed and its data structures deleted. |
1154 | */ | */ |
1155 | ||
1156 | if (winPtr->mainPtr->winPtr == winPtr) { | if (winPtr->mainPtr->winPtr == winPtr) { |
1157 | dispPtr->refCount--; | dispPtr->refCount--; |
1158 | if (tsdPtr->mainWindowList == winPtr->mainPtr) { | if (tsdPtr->mainWindowList == winPtr->mainPtr) { |
1159 | tsdPtr->mainWindowList = winPtr->mainPtr->nextPtr; | tsdPtr->mainWindowList = winPtr->mainPtr->nextPtr; |
1160 | } else { | } else { |
1161 | TkMainInfo *prevPtr; | TkMainInfo *prevPtr; |
1162 | ||
1163 | for (prevPtr = tsdPtr->mainWindowList; | for (prevPtr = tsdPtr->mainWindowList; |
1164 | prevPtr->nextPtr != winPtr->mainPtr; | prevPtr->nextPtr != winPtr->mainPtr; |
1165 | prevPtr = prevPtr->nextPtr) { | prevPtr = prevPtr->nextPtr) { |
1166 | /* Empty loop body. */ | /* Empty loop body. */ |
1167 | } | } |
1168 | prevPtr->nextPtr = winPtr->mainPtr->nextPtr; | prevPtr->nextPtr = winPtr->mainPtr->nextPtr; |
1169 | } | } |
1170 | tsdPtr->numMainWindows--; | tsdPtr->numMainWindows--; |
1171 | } | } |
1172 | ||
1173 | /* | /* |
1174 | * Recursively destroy children. | * Recursively destroy children. |
1175 | */ | */ |
1176 | ||
1177 | dispPtr->destroyCount++; | dispPtr->destroyCount++; |
1178 | while (winPtr->childList != NULL) { | while (winPtr->childList != NULL) { |
1179 | TkWindow *childPtr; | TkWindow *childPtr; |
1180 | childPtr = winPtr->childList; | childPtr = winPtr->childList; |
1181 | childPtr->flags |= TK_DONT_DESTROY_WINDOW; | childPtr->flags |= TK_DONT_DESTROY_WINDOW; |
1182 | Tk_DestroyWindow((Tk_Window) childPtr); | Tk_DestroyWindow((Tk_Window) childPtr); |
1183 | if (winPtr->childList == childPtr) { | if (winPtr->childList == childPtr) { |
1184 | /* | /* |
1185 | * The child didn't remove itself from the child list, so | * The child didn't remove itself from the child list, so |
1186 | * let's remove it here. This can happen in some strange | * let's remove it here. This can happen in some strange |
1187 | * conditions, such as when a Delete event handler for a | * conditions, such as when a Delete event handler for a |
1188 | * window deletes the window's parent. | * window deletes the window's parent. |
1189 | */ | */ |
1190 | ||
1191 | winPtr->childList = childPtr->nextPtr; | winPtr->childList = childPtr->nextPtr; |
1192 | childPtr->parentPtr = NULL; | childPtr->parentPtr = NULL; |
1193 | } | } |
1194 | } | } |
1195 | if ((winPtr->flags & (TK_CONTAINER|TK_BOTH_HALVES)) | if ((winPtr->flags & (TK_CONTAINER|TK_BOTH_HALVES)) |
1196 | == (TK_CONTAINER|TK_BOTH_HALVES)) { | == (TK_CONTAINER|TK_BOTH_HALVES)) { |
1197 | /* | /* |
1198 | * This is the container for an embedded application, and | * This is the container for an embedded application, and |
1199 | * the embedded application is also in this process. Delete | * the embedded application is also in this process. Delete |
1200 | * the embedded window in-line here, for the same reasons we | * the embedded window in-line here, for the same reasons we |
1201 | * delete children in-line (otherwise, for example, the Tk | * delete children in-line (otherwise, for example, the Tk |
1202 | * window may appear to exist even though its X window is | * window may appear to exist even though its X window is |
1203 | * gone; this could cause errors). Special note: it's possible | * gone; this could cause errors). Special note: it's possible |
1204 | * that the embedded window has already been deleted, in which | * that the embedded window has already been deleted, in which |
1205 | * case TkpGetOtherWindow will return NULL. | * case TkpGetOtherWindow will return NULL. |
1206 | */ | */ |
1207 | ||
1208 | TkWindow *childPtr; | TkWindow *childPtr; |
1209 | childPtr = TkpGetOtherWindow(winPtr); | childPtr = TkpGetOtherWindow(winPtr); |
1210 | if (childPtr != NULL) { | if (childPtr != NULL) { |
1211 | childPtr->flags |= TK_DONT_DESTROY_WINDOW; | childPtr->flags |= TK_DONT_DESTROY_WINDOW; |
1212 | Tk_DestroyWindow((Tk_Window) childPtr); | Tk_DestroyWindow((Tk_Window) childPtr); |
1213 | } | } |
1214 | } | } |
1215 | ||
1216 | /* | /* |
1217 | * Generate a DestroyNotify event. In order for the DestroyNotify | * Generate a DestroyNotify event. In order for the DestroyNotify |
1218 | * event to be processed correctly, need to make sure the window | * event to be processed correctly, need to make sure the window |
1219 | * exists. This is a bit of a kludge, and may be unnecessarily | * exists. This is a bit of a kludge, and may be unnecessarily |
1220 | * expensive, but without it no event handlers will get called for | * expensive, but without it no event handlers will get called for |
1221 | * windows that don't exist yet. | * windows that don't exist yet. |
1222 | * | * |
1223 | * Note: if the window's pathName is NULL it means that the window | * Note: if the window's pathName is NULL it means that the window |
1224 | * was not successfully initialized in the first place, so we should | * was not successfully initialized in the first place, so we should |
1225 | * not make the window exist or generate the event. | * not make the window exist or generate the event. |
1226 | */ | */ |
1227 | ||
1228 | if (winPtr->pathName != NULL) { | if (winPtr->pathName != NULL) { |
1229 | if (winPtr->window == None) { | if (winPtr->window == None) { |
1230 | Tk_MakeWindowExist(tkwin); | Tk_MakeWindowExist(tkwin); |
1231 | } | } |
1232 | event.type = DestroyNotify; | event.type = DestroyNotify; |
1233 | event.xdestroywindow.serial = | event.xdestroywindow.serial = |
1234 | LastKnownRequestProcessed(winPtr->display); | LastKnownRequestProcessed(winPtr->display); |
1235 | event.xdestroywindow.send_event = False; | event.xdestroywindow.send_event = False; |
1236 | event.xdestroywindow.display = winPtr->display; | event.xdestroywindow.display = winPtr->display; |
1237 | event.xdestroywindow.event = winPtr->window; | event.xdestroywindow.event = winPtr->window; |
1238 | event.xdestroywindow.window = winPtr->window; | event.xdestroywindow.window = winPtr->window; |
1239 | Tk_HandleEvent(&event); | Tk_HandleEvent(&event); |
1240 | } | } |
1241 | ||
1242 | /* | /* |
1243 | * Cleanup the data structures associated with this window. | * Cleanup the data structures associated with this window. |
1244 | */ | */ |
1245 | ||
1246 | if (winPtr->flags & TK_TOP_LEVEL) { | if (winPtr->flags & TK_TOP_LEVEL) { |
1247 | TkWmDeadWindow(winPtr); | TkWmDeadWindow(winPtr); |
1248 | } else if (winPtr->flags & TK_WM_COLORMAP_WINDOW) { | } else if (winPtr->flags & TK_WM_COLORMAP_WINDOW) { |
1249 | TkWmRemoveFromColormapWindows(winPtr); | TkWmRemoveFromColormapWindows(winPtr); |
1250 | } | } |
1251 | if (winPtr->window != None) { | if (winPtr->window != None) { |
1252 | #if defined(MAC_TCL) || defined(__WIN32__) | #if defined(MAC_TCL) || defined(__WIN32__) |
1253 | XDestroyWindow(winPtr->display, winPtr->window); | XDestroyWindow(winPtr->display, winPtr->window); |
1254 | #else | #else |
1255 | if ((winPtr->flags & TK_TOP_LEVEL) | if ((winPtr->flags & TK_TOP_LEVEL) |
1256 | || !(winPtr->flags & TK_DONT_DESTROY_WINDOW)) { | || !(winPtr->flags & TK_DONT_DESTROY_WINDOW)) { |
1257 | /* | /* |
1258 | * The parent has already been destroyed and this isn't | * The parent has already been destroyed and this isn't |
1259 | * a top-level window, so this window will be destroyed | * a top-level window, so this window will be destroyed |
1260 | * implicitly when the parent's X window is destroyed; | * implicitly when the parent's X window is destroyed; |
1261 | * it's much faster not to do an explicit destroy of this | * it's much faster not to do an explicit destroy of this |
1262 | * X window. | * X window. |
1263 | */ | */ |
1264 | ||
1265 | dispPtr->lastDestroyRequest = NextRequest(winPtr->display); | dispPtr->lastDestroyRequest = NextRequest(winPtr->display); |
1266 | XDestroyWindow(winPtr->display, winPtr->window); | XDestroyWindow(winPtr->display, winPtr->window); |
1267 | } | } |
1268 | #endif | #endif |
1269 | TkFreeWindowId(dispPtr, winPtr->window); | TkFreeWindowId(dispPtr, winPtr->window); |
1270 | Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->winTable, | Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->winTable, |
1271 | (char *) winPtr->window)); | (char *) winPtr->window)); |
1272 | winPtr->window = None; | winPtr->window = None; |
1273 | } | } |
1274 | dispPtr->destroyCount--; | dispPtr->destroyCount--; |
1275 | UnlinkWindow(winPtr); | UnlinkWindow(winPtr); |
1276 | TkEventDeadWindow(winPtr); | TkEventDeadWindow(winPtr); |
1277 | TkBindDeadWindow(winPtr); | TkBindDeadWindow(winPtr); |
1278 | #ifdef TK_USE_INPUT_METHODS | #ifdef TK_USE_INPUT_METHODS |
1279 | if (winPtr->inputContext != NULL) { | if (winPtr->inputContext != NULL) { |
1280 | XDestroyIC(winPtr->inputContext); | XDestroyIC(winPtr->inputContext); |
1281 | } | } |
1282 | #endif /* TK_USE_INPUT_METHODS */ | #endif /* TK_USE_INPUT_METHODS */ |
1283 | if (winPtr->tagPtr != NULL) { | if (winPtr->tagPtr != NULL) { |
1284 | TkFreeBindingTags(winPtr); | TkFreeBindingTags(winPtr); |
1285 | } | } |
1286 | TkOptionDeadWindow(winPtr); | TkOptionDeadWindow(winPtr); |
1287 | TkSelDeadWindow(winPtr); | TkSelDeadWindow(winPtr); |
1288 | TkGrabDeadWindow(winPtr); | TkGrabDeadWindow(winPtr); |
1289 | if (winPtr->mainPtr != NULL) { | if (winPtr->mainPtr != NULL) { |
1290 | if (winPtr->pathName != NULL) { | if (winPtr->pathName != NULL) { |
1291 | Tk_DeleteAllBindings(winPtr->mainPtr->bindingTable, | Tk_DeleteAllBindings(winPtr->mainPtr->bindingTable, |
1292 | (ClientData) winPtr->pathName); | (ClientData) winPtr->pathName); |
1293 | Tcl_DeleteHashEntry(Tcl_FindHashEntry(&winPtr->mainPtr->nameTable, | Tcl_DeleteHashEntry(Tcl_FindHashEntry(&winPtr->mainPtr->nameTable, |
1294 | winPtr->pathName)); | winPtr->pathName)); |
1295 | } | } |
1296 | winPtr->mainPtr->refCount--; | winPtr->mainPtr->refCount--; |
1297 | if (winPtr->mainPtr->refCount == 0) { | if (winPtr->mainPtr->refCount == 0) { |
1298 | register TkCmd *cmdPtr; | register TkCmd *cmdPtr; |
1299 | ||
1300 | /* | /* |
1301 | * We just deleted the last window in the application. Delete | * We just deleted the last window in the application. Delete |
1302 | * the TkMainInfo structure too and replace all of Tk's commands | * the TkMainInfo structure too and replace all of Tk's commands |
1303 | * with dummy commands that return errors. Also delete the | * with dummy commands that return errors. Also delete the |
1304 | * "send" command to unregister the interpreter. | * "send" command to unregister the interpreter. |
1305 | * | * |
1306 | * NOTE: Only replace the commands it if the interpreter is | * NOTE: Only replace the commands it if the interpreter is |
1307 | * not being deleted. If it *is*, the interpreter cleanup will | * not being deleted. If it *is*, the interpreter cleanup will |
1308 | * do all the needed work. | * do all the needed work. |
1309 | */ | */ |
1310 | ||
1311 | if ((winPtr->mainPtr->interp != NULL) && | if ((winPtr->mainPtr->interp != NULL) && |
1312 | (!Tcl_InterpDeleted(winPtr->mainPtr->interp))) { | (!Tcl_InterpDeleted(winPtr->mainPtr->interp))) { |
1313 | for (cmdPtr = commands; cmdPtr->name != NULL; cmdPtr++) { | for (cmdPtr = commands; cmdPtr->name != NULL; cmdPtr++) { |
1314 | Tcl_CreateCommand(winPtr->mainPtr->interp, cmdPtr->name, | Tcl_CreateCommand(winPtr->mainPtr->interp, cmdPtr->name, |
1315 | TkDeadAppCmd, (ClientData) NULL, | TkDeadAppCmd, (ClientData) NULL, |
1316 | (void (*) _ANSI_ARGS_((ClientData))) NULL); | (void (*) _ANSI_ARGS_((ClientData))) NULL); |
1317 | } | } |
1318 | Tcl_CreateCommand(winPtr->mainPtr->interp, "send", | Tcl_CreateCommand(winPtr->mainPtr->interp, "send", |
1319 | TkDeadAppCmd, (ClientData) NULL, | TkDeadAppCmd, (ClientData) NULL, |
1320 | (void (*) _ANSI_ARGS_((ClientData))) NULL); | (void (*) _ANSI_ARGS_((ClientData))) NULL); |
1321 | Tcl_UnlinkVar(winPtr->mainPtr->interp, "tk_strictMotif"); | Tcl_UnlinkVar(winPtr->mainPtr->interp, "tk_strictMotif"); |
1322 | } | } |
1323 | ||
1324 | Tcl_DeleteHashTable(&winPtr->mainPtr->nameTable); | Tcl_DeleteHashTable(&winPtr->mainPtr->nameTable); |
1325 | TkBindFree(winPtr->mainPtr); | TkBindFree(winPtr->mainPtr); |
1326 | TkDeleteAllImages(winPtr->mainPtr); | TkDeleteAllImages(winPtr->mainPtr); |
1327 | TkFontPkgFree(winPtr->mainPtr); | TkFontPkgFree(winPtr->mainPtr); |
1328 | ||
1329 | /* | /* |
1330 | * When embedding Tk into other applications, make sure | * When embedding Tk into other applications, make sure |
1331 | * that all destroy events reach the server. Otherwise | * that all destroy events reach the server. Otherwise |
1332 | * the embedding application may also attempt to destroy | * the embedding application may also attempt to destroy |
1333 | * the windows, resulting in an X error | * the windows, resulting in an X error |
1334 | */ | */ |
1335 | ||
1336 | if (winPtr->flags & TK_EMBEDDED) { | if (winPtr->flags & TK_EMBEDDED) { |
1337 | XSync(winPtr->display,False) ; | XSync(winPtr->display,False) ; |
1338 | } | } |
1339 | ckfree((char *) winPtr->mainPtr); | ckfree((char *) winPtr->mainPtr); |
1340 | ||
1341 | /* | /* |
1342 | * If no other applications are using the display, close the | * If no other applications are using the display, close the |
1343 | * display now and relinquish its data structures. | * display now and relinquish its data structures. |
1344 | */ | */ |
1345 | ||
1346 | if (dispPtr->refCount <= 0) { | if (dispPtr->refCount <= 0) { |
1347 | #ifdef NOT_YET | #ifdef NOT_YET |
1348 | /* | /* |
1349 | * I have disabled this code because on Windows there are | * I have disabled this code because on Windows there are |
1350 | * still order dependencies in close-down. All displays | * still order dependencies in close-down. All displays |
1351 | * and resources will get closed down properly anyway at | * and resources will get closed down properly anyway at |
1352 | * exit, through the exit handler. | * exit, through the exit handler. |
1353 | */ | */ |
1354 | ||
1355 | TkDisplay *theDispPtr, *backDispPtr; | TkDisplay *theDispPtr, *backDispPtr; |
1356 | ||
1357 | /* | /* |
1358 | * Splice this display out of the list of displays. | * Splice this display out of the list of displays. |
1359 | */ | */ |
1360 | ||
1361 | for (theDispPtr = displayList, backDispPtr = NULL; | for (theDispPtr = displayList, backDispPtr = NULL; |
1362 | (theDispPtr != winPtr->dispPtr) && | (theDispPtr != winPtr->dispPtr) && |
1363 | (theDispPtr != NULL); | (theDispPtr != NULL); |
1364 | theDispPtr = theDispPtr->nextPtr) { | theDispPtr = theDispPtr->nextPtr) { |
1365 | backDispPtr = theDispPtr; | backDispPtr = theDispPtr; |
1366 | } | } |
1367 | if (theDispPtr == NULL) { | if (theDispPtr == NULL) { |
1368 | panic("could not find display to close!"); | panic("could not find display to close!"); |
1369 | } | } |
1370 | if (backDispPtr == NULL) { | if (backDispPtr == NULL) { |
1371 | displayList = theDispPtr->nextPtr; | displayList = theDispPtr->nextPtr; |
1372 | } else { | } else { |
1373 | backDispPtr->nextPtr = theDispPtr->nextPtr; | backDispPtr->nextPtr = theDispPtr->nextPtr; |
1374 | } | } |
1375 | ||
1376 | /* | /* |
1377 | * Found and spliced it out, now actually do the cleanup. | * Found and spliced it out, now actually do the cleanup. |
1378 | */ | */ |
1379 | ||
1380 | if (dispPtr->name != NULL) { | if (dispPtr->name != NULL) { |
1381 | ckfree(dispPtr->name); | ckfree(dispPtr->name); |
1382 | } | } |
1383 | ||
1384 | Tcl_DeleteHashTable(&(dispPtr->winTable)); | Tcl_DeleteHashTable(&(dispPtr->winTable)); |
1385 | ||
1386 | /* | /* |
1387 | * Cannot yet close the display because we still have | * Cannot yet close the display because we still have |
1388 | * order of deletion problems. Defer until exit handling | * order of deletion problems. Defer until exit handling |
1389 | * instead. At that time, the display will cleanly shut | * instead. At that time, the display will cleanly shut |
1390 | * down (hopefully..). (JYL) | * down (hopefully..). (JYL) |
1391 | */ | */ |
1392 | ||
1393 | TkpCloseDisplay(dispPtr); | TkpCloseDisplay(dispPtr); |
1394 | ||
1395 | /* | /* |
1396 | * There is lots more to clean up, we leave it at this for | * There is lots more to clean up, we leave it at this for |
1397 | * the time being. | * the time being. |
1398 | */ | */ |
1399 | #endif | #endif |
1400 | } | } |
1401 | } | } |
1402 | } | } |
1403 | ckfree((char *) winPtr); | ckfree((char *) winPtr); |
1404 | } | } |
1405 | ||
1406 | /* | /* |
1407 | *-------------------------------------------------------------- | *-------------------------------------------------------------- |
1408 | * | * |
1409 | * Tk_MapWindow -- | * Tk_MapWindow -- |
1410 | * | * |
1411 | * Map a window within its parent. This may require the | * Map a window within its parent. This may require the |
1412 | * window and/or its parents to actually be created. | * window and/or its parents to actually be created. |
1413 | * | * |
1414 | * Results: | * Results: |
1415 | * None. | * None. |
1416 | * | * |
1417 | * Side effects: | * Side effects: |
1418 | * The given window will be mapped. Windows may also | * The given window will be mapped. Windows may also |
1419 | * be created. | * be created. |
1420 | * | * |
1421 | *-------------------------------------------------------------- | *-------------------------------------------------------------- |
1422 | */ | */ |
1423 | ||
1424 | void | void |
1425 | Tk_MapWindow(tkwin) | Tk_MapWindow(tkwin) |
1426 | Tk_Window tkwin; /* Token for window to map. */ | Tk_Window tkwin; /* Token for window to map. */ |
1427 | { | { |
1428 | register TkWindow *winPtr = (TkWindow *) tkwin; | register TkWindow *winPtr = (TkWindow *) tkwin; |
1429 | XEvent event; | XEvent event; |
1430 | ||
1431 | if (winPtr->flags & TK_MAPPED) { | if (winPtr->flags & TK_MAPPED) { |
1432 | return; | return; |
1433 | } | } |
1434 | if (winPtr->window == None) { | if (winPtr->window == None) { |
1435 | Tk_MakeWindowExist(tkwin); | Tk_MakeWindowExist(tkwin); |
1436 | } | } |
1437 | if (winPtr->flags & TK_TOP_LEVEL) { | if (winPtr->flags & TK_TOP_LEVEL) { |
1438 | /* | /* |
1439 | * Lots of special processing has to be done for top-level | * Lots of special processing has to be done for top-level |
1440 | * windows. Let tkWm.c handle everything itself. | * windows. Let tkWm.c handle everything itself. |
1441 | */ | */ |
1442 | ||
1443 | TkWmMapWindow(winPtr); | TkWmMapWindow(winPtr); |
1444 | return; | return; |
1445 | } | } |
1446 | winPtr->flags |= TK_MAPPED; | winPtr->flags |= TK_MAPPED; |
1447 | XMapWindow(winPtr->display, winPtr->window); | XMapWindow(winPtr->display, winPtr->window); |
1448 | event.type = MapNotify; | event.type = MapNotify; |
1449 | event.xmap.serial = LastKnownRequestProcessed(winPtr->display); | event.xmap.serial = LastKnownRequestProcessed(winPtr->display); |
1450 | event.xmap.send_event = False; | event.xmap.send_event = False; |
1451 | event.xmap.display = winPtr->display; | event.xmap.display = winPtr->display; |
1452 | event.xmap.event = winPtr->window; | event.xmap.event = winPtr->window; |
1453 | event.xmap.window = winPtr->window; | event.xmap.window = winPtr->window; |
1454 | event.xmap.override_redirect = winPtr->atts.override_redirect; | event.xmap.override_redirect = winPtr->atts.override_redirect; |
1455 | Tk_HandleEvent(&event); | Tk_HandleEvent(&event); |
1456 | } | } |
1457 | ||
1458 | /* | /* |
1459 | *-------------------------------------------------------------- | *-------------------------------------------------------------- |
1460 | * | * |
1461 | * Tk_MakeWindowExist -- | * Tk_MakeWindowExist -- |
1462 | * | * |
1463 | * Ensure that a particular window actually exists. This | * Ensure that a particular window actually exists. This |
1464 | * procedure shouldn't normally need to be invoked from | * procedure shouldn't normally need to be invoked from |
1465 | * outside the Tk package, but may be needed if someone | * outside the Tk package, but may be needed if someone |
1466 | * wants to manipulate a window before mapping it. | * wants to manipulate a window before mapping it. |
1467 | * | * |
1468 | * Results: | * Results: |
1469 | * None. | * None. |
1470 | * | * |
1471 | * Side effects: | * Side effects: |
1472 | * When the procedure returns, the X window associated with | * When the procedure returns, the X window associated with |
1473 | * tkwin is guaranteed to exist. This may require the | * tkwin is guaranteed to exist. This may require the |
1474 | * window's ancestors to be created also. | * window's ancestors to be created also. |
1475 | * | * |
1476 | *-------------------------------------------------------------- | *-------------------------------------------------------------- |
1477 | */ | */ |
1478 | ||
1479 | void | void |
1480 | Tk_MakeWindowExist(tkwin) | Tk_MakeWindowExist(tkwin) |
1481 | Tk_Window tkwin; /* Token for window. */ | Tk_Window tkwin; /* Token for window. */ |
1482 | { | { |
1483 | register TkWindow *winPtr = (TkWindow *) tkwin; | register TkWindow *winPtr = (TkWindow *) tkwin; |
1484 | TkWindow *winPtr2; | TkWindow *winPtr2; |
1485 | Window parent; | Window parent; |
1486 | Tcl_HashEntry *hPtr; | Tcl_HashEntry *hPtr; |
1487 | int new; | int new; |
1488 | ||
1489 | if (winPtr->window != None) { | if (winPtr->window != None) { |
1490 | return; | return; |
1491 | } | } |
1492 | ||
1493 | if ((winPtr->parentPtr == NULL) || (winPtr->flags & TK_TOP_LEVEL)) { | if ((winPtr->parentPtr == NULL) || (winPtr->flags & TK_TOP_LEVEL)) { |
1494 | parent = XRootWindow(winPtr->display, winPtr->screenNum); | parent = XRootWindow(winPtr->display, winPtr->screenNum); |
1495 | } else { | } else { |
1496 | if (winPtr->parentPtr->window == None) { | if (winPtr->parentPtr->window == None) { |
1497 | Tk_MakeWindowExist((Tk_Window) winPtr->parentPtr); | Tk_MakeWindowExist((Tk_Window) winPtr->parentPtr); |
1498 | } | } |
1499 | parent = winPtr->parentPtr->window; | parent = winPtr->parentPtr->window; |
1500 | } | } |
1501 | ||
1502 | if (winPtr->classProcsPtr != NULL | if (winPtr->classProcsPtr != NULL |
1503 | && winPtr->classProcsPtr->createProc != NULL) { | && winPtr->classProcsPtr->createProc != NULL) { |
1504 | winPtr->window = (*winPtr->classProcsPtr->createProc)(tkwin, parent, | winPtr->window = (*winPtr->classProcsPtr->createProc)(tkwin, parent, |
1505 | winPtr->instanceData); | winPtr->instanceData); |
1506 | } else { | } else { |
1507 | winPtr->window = TkpMakeWindow(winPtr, parent); | winPtr->window = TkpMakeWindow(winPtr, parent); |
1508 | } | } |
1509 | ||
1510 | hPtr = Tcl_CreateHashEntry(&winPtr->dispPtr->winTable, | hPtr = Tcl_CreateHashEntry(&winPtr->dispPtr->winTable, |
1511 | (char *) winPtr->window, &new); | (char *) winPtr->window, &new); |
1512 | Tcl_SetHashValue(hPtr, winPtr); | Tcl_SetHashValue(hPtr, winPtr); |
1513 | winPtr->dirtyAtts = 0; | winPtr->dirtyAtts = 0; |
1514 | winPtr->dirtyChanges = 0; | winPtr->dirtyChanges = 0; |
1515 | #ifdef TK_USE_INPUT_METHODS | #ifdef TK_USE_INPUT_METHODS |
1516 | winPtr->inputContext = NULL; | winPtr->inputContext = NULL; |
1517 | #endif /* TK_USE_INPUT_METHODS */ | #endif /* TK_USE_INPUT_METHODS */ |
1518 | ||
1519 | if (!(winPtr->flags & TK_TOP_LEVEL)) { | if (!(winPtr->flags & TK_TOP_LEVEL)) { |
1520 | /* | /* |
1521 | * If any siblings higher up in the stacking order have already | * If any siblings higher up in the stacking order have already |
1522 | * been created then move this window to its rightful position | * been created then move this window to its rightful position |
1523 | * in the stacking order. | * in the stacking order. |
1524 | * | * |
1525 | * NOTE: this code ignores any changes anyone might have made | * NOTE: this code ignores any changes anyone might have made |
1526 | * to the sibling and stack_mode field of the window's attributes, | * to the sibling and stack_mode field of the window's attributes, |
1527 | * so it really isn't safe for these to be manipulated except | * so it really isn't safe for these to be manipulated except |
1528 | * by calling Tk_RestackWindow. | * by calling Tk_RestackWindow. |
1529 | */ | */ |
1530 | ||
1531 | for (winPtr2 = winPtr->nextPtr; winPtr2 != NULL; | for (winPtr2 = winPtr->nextPtr; winPtr2 != NULL; |
1532 | winPtr2 = winPtr2->nextPtr) { | winPtr2 = winPtr2->nextPtr) { |
1533 | if ((winPtr2->window != None) | if ((winPtr2->window != None) |
1534 | && !(winPtr2->flags & (TK_TOP_LEVEL|TK_REPARENTED))) { | && !(winPtr2->flags & (TK_TOP_LEVEL|TK_REPARENTED))) { |
1535 | XWindowChanges changes; | XWindowChanges changes; |
1536 | changes.sibling = winPtr2->window; | changes.sibling = winPtr2->window; |
1537 | changes.stack_mode = Below; | changes.stack_mode = Below; |
1538 | XConfigureWindow(winPtr->display, winPtr->window, | XConfigureWindow(winPtr->display, winPtr->window, |
1539 | CWSibling|CWStackMode, &changes); | CWSibling|CWStackMode, &changes); |
1540 | break; | break; |
1541 | } | } |
1542 | } | } |
1543 | ||
1544 | /* | /* |
1545 | * If this window has a different colormap than its parent, add | * If this window has a different colormap than its parent, add |
1546 | * the window to the WM_COLORMAP_WINDOWS property for its top-level. | * the window to the WM_COLORMAP_WINDOWS property for its top-level. |
1547 | */ | */ |
1548 | ||
1549 | if ((winPtr->parentPtr != NULL) && | if ((winPtr->parentPtr != NULL) && |
1550 | (winPtr->atts.colormap != winPtr->parentPtr->atts.colormap)) { | (winPtr->atts.colormap != winPtr->parentPtr->atts.colormap)) { |
1551 | TkWmAddToColormapWindows(winPtr); | TkWmAddToColormapWindows(winPtr); |
1552 | winPtr->flags |= TK_WM_COLORMAP_WINDOW; | winPtr->flags |= TK_WM_COLORMAP_WINDOW; |
1553 | } | } |
1554 | } | } |
1555 | ||
1556 | /* | /* |
1557 | * Issue a ConfigureNotify event if there were deferred configuration | * Issue a ConfigureNotify event if there were deferred configuration |
1558 | * changes (but skip it if the window is being deleted; the | * changes (but skip it if the window is being deleted; the |
1559 | * ConfigureNotify event could cause problems if we're being called | * ConfigureNotify event could cause problems if we're being called |
1560 | * from Tk_DestroyWindow under some conditions). | * from Tk_DestroyWindow under some conditions). |
1561 | */ | */ |
1562 | ||
1563 | if ((winPtr->flags & TK_NEED_CONFIG_NOTIFY) | if ((winPtr->flags & TK_NEED_CONFIG_NOTIFY) |
1564 | && !(winPtr->flags & TK_ALREADY_DEAD)){ | && !(winPtr->flags & TK_ALREADY_DEAD)){ |
1565 | winPtr->flags &= ~TK_NEED_CONFIG_NOTIFY; | winPtr->flags &= ~TK_NEED_CONFIG_NOTIFY; |
1566 | TkDoConfigureNotify(winPtr); | TkDoConfigureNotify(winPtr); |
1567 | } | } |
1568 | } | } |
1569 | ||
1570 | /* | /* |
1571 | *-------------------------------------------------------------- | *-------------------------------------------------------------- |
1572 | * | * |
1573 | * Tk_UnmapWindow, etc. -- | * Tk_UnmapWindow, etc. -- |
1574 | * | * |
1575 | * There are several procedures under here, each of which | * There are several procedures under here, each of which |
1576 | * mirrors an existing X procedure. In addition to performing | * mirrors an existing X procedure. In addition to performing |
1577 | * the functions of the corresponding procedure, each | * the functions of the corresponding procedure, each |
1578 | * procedure also updates the local window structure and | * procedure also updates the local window structure and |
1579 | * synthesizes an X event (if the window's structure is being | * synthesizes an X event (if the window's structure is being |
1580 | * managed internally). | * managed internally). |
1581 | * | * |
1582 | * Results: | * Results: |
1583 | * See the manual entries. | * See the manual entries. |
1584 | * | * |
1585 | * Side effects: | * Side effects: |
1586 | * See the manual entries. | * See the manual entries. |
1587 | * | * |
1588 | *-------------------------------------------------------------- | *-------------------------------------------------------------- |
1589 | */ | */ |
1590 | ||
1591 | void | void |
1592 | Tk_UnmapWindow(tkwin) | Tk_UnmapWindow(tkwin) |
1593 | Tk_Window tkwin; /* Token for window to unmap. */ | Tk_Window tkwin; /* Token for window to unmap. */ |
1594 | { | { |
1595 | register TkWindow *winPtr = (TkWindow *) tkwin; | register TkWindow *winPtr = (TkWindow *) tkwin; |
1596 | ||
1597 | if (!(winPtr->flags & TK_MAPPED) || (winPtr->flags & TK_ALREADY_DEAD)) { | if (!(winPtr->flags & TK_MAPPED) || (winPtr->flags & TK_ALREADY_DEAD)) { |
1598 | return; | return; |
1599 | } | } |
1600 | if (winPtr->flags & TK_TOP_LEVEL) { | if (winPtr->flags & TK_TOP_LEVEL) { |
1601 | /* | /* |
1602 | * Special processing has to be done for top-level windows. Let | * Special processing has to be done for top-level windows. Let |
1603 | * tkWm.c handle everything itself. | * tkWm.c handle everything itself. |
1604 | */ | */ |
1605 | ||
1606 | TkWmUnmapWindow(winPtr); | TkWmUnmapWindow(winPtr); |
1607 | return; | return; |
1608 | } | } |
1609 | winPtr->flags &= ~TK_MAPPED; | winPtr->flags &= ~TK_MAPPED; |
1610 | XUnmapWindow(winPtr->display, winPtr->window); | XUnmapWindow(winPtr->display, winPtr->window); |
1611 | if (!(winPtr->flags & TK_TOP_LEVEL)) { | if (!(winPtr->flags & TK_TOP_LEVEL)) { |
1612 | XEvent event; | XEvent event; |
1613 | ||
1614 | event.type = UnmapNotify; | event.type = UnmapNotify; |
1615 | event.xunmap.serial = LastKnownRequestProcessed(winPtr->display); | event.xunmap.serial = LastKnownRequestProcessed(winPtr->display); |
1616 | event.xunmap.send_event = False; | event.xunmap.send_event = False; |
1617 | event.xunmap.display = winPtr->display; | event.xunmap.display = winPtr->display; |
1618 | event.xunmap.event = winPtr->window; | event.xunmap.event = winPtr->window; |
1619 | event.xunmap.window = winPtr->window; | event.xunmap.window = winPtr->window; |
1620 | event.xunmap.from_configure = False; | event.xunmap.from_configure = False; |
1621 | Tk_HandleEvent(&event); | Tk_HandleEvent(&event); |
1622 | } | } |
1623 | } | } |
1624 | ||
1625 | void | void |
1626 | Tk_ConfigureWindow(tkwin, valueMask, valuePtr) | Tk_ConfigureWindow(tkwin, valueMask, valuePtr) |
1627 | Tk_Window tkwin; /* Window to re-configure. */ | Tk_Window tkwin; /* Window to re-configure. */ |
1628 | unsigned int valueMask; /* Mask indicating which parts of | unsigned int valueMask; /* Mask indicating which parts of |
1629 | * *valuePtr are to be used. */ | * *valuePtr are to be used. */ |
1630 | XWindowChanges *valuePtr; /* New values. */ | XWindowChanges *valuePtr; /* New values. */ |
1631 | { | { |
1632 | register TkWindow *winPtr = (TkWindow *) tkwin; | register TkWindow *winPtr = (TkWindow *) tkwin; |
1633 | ||
1634 | if (valueMask & CWX) { | if (valueMask & CWX) { |
1635 | winPtr->changes.x = valuePtr->x; | winPtr->changes.x = valuePtr->x; |
1636 | } | } |
1637 | if (valueMask & CWY) { | if (valueMask & CWY) { |
1638 | winPtr->changes.y = valuePtr->y; | winPtr->changes.y = valuePtr->y; |
1639 | } | } |
1640 | if (valueMask & CWWidth) { | if (valueMask & CWWidth) { |
1641 | winPtr->changes.width = valuePtr->width; | winPtr->changes.width = valuePtr->width; |
1642 | } | } |
1643 | if (valueMask & CWHeight) { | if (valueMask & CWHeight) { |
1644 | winPtr->changes.height = valuePtr->height; | winPtr->changes.height = valuePtr->height; |
1645 | } | } |
1646 | if (valueMask & CWBorderWidth) { | if (valueMask & CWBorderWidth) { |
1647 | winPtr->changes.border_width = valuePtr->border_width; | winPtr->changes.border_width = valuePtr->border_width; |
1648 | } | } |
1649 | if (valueMask & (CWSibling|CWStackMode)) { | if (valueMask & (CWSibling|CWStackMode)) { |
1650 | panic("Can't set sibling or stack mode from Tk_ConfigureWindow."); | panic("Can't set sibling or stack mode from Tk_ConfigureWindow."); |
1651 | } | } |
1652 | ||
1653 | if (winPtr->window != None) { | if (winPtr->window != None) { |
1654 | XConfigureWindow(winPtr->display, winPtr->window, | XConfigureWindow(winPtr->display, winPtr->window, |
1655 | valueMask, valuePtr); | valueMask, valuePtr); |
1656 | TkDoConfigureNotify(winPtr); | TkDoConfigureNotify(winPtr); |
1657 | } else { | } else { |
1658 | winPtr->dirtyChanges |= valueMask; | winPtr->dirtyChanges |= valueMask; |
1659 | winPtr->flags |= TK_NEED_CONFIG_NOTIFY; | winPtr->flags |= TK_NEED_CONFIG_NOTIFY; |
1660 | } | } |
1661 | } | } |
1662 | ||
1663 | void | void |
1664 | Tk_MoveWindow(tkwin, x, y) | Tk_MoveWindow(tkwin, x, y) |
1665 | Tk_Window tkwin; /* Window to move. */ | Tk_Window tkwin; /* Window to move. */ |
1666 | int x, y; /* New location for window (within | int x, y; /* New location for window (within |
1667 | * parent). */ | * parent). */ |
1668 | { | { |
1669 | register TkWindow *winPtr = (TkWindow *) tkwin; | register TkWindow *winPtr = (TkWindow *) tkwin; |
1670 | ||
1671 | winPtr->changes.x = x; | winPtr->changes.x = x; |
1672 | winPtr->changes.y = y; | winPtr->changes.y = y; |
1673 | if (winPtr->window != None) { | if (winPtr->window != None) { |
1674 | XMoveWindow(winPtr->display, winPtr->window, x, y); | XMoveWindow(winPtr->display, winPtr->window, x, y); |
1675 | TkDoConfigureNotify(winPtr); | TkDoConfigureNotify(winPtr); |
1676 | } else { | } else { |
1677 | winPtr->dirtyChanges |= CWX|CWY; | winPtr->dirtyChanges |= CWX|CWY; |
1678 | winPtr->flags |= TK_NEED_CONFIG_NOTIFY; | winPtr->flags |= TK_NEED_CONFIG_NOTIFY; |
1679 | } | } |
1680 | } | } |
1681 | ||
1682 | void | void |
1683 | Tk_ResizeWindow(tkwin, width, height) | Tk_ResizeWindow(tkwin, width, height) |
1684 | Tk_Window tkwin; /* Window to resize. */ | Tk_Window tkwin; /* Window to resize. */ |
1685 | int width, height; /* New dimensions for window. */ | int width, height; /* New dimensions for window. */ |
1686 | { | { |
1687 | register TkWindow *winPtr = (TkWindow *) tkwin; | register TkWindow *winPtr = (TkWindow *) tkwin; |
1688 | ||
1689 | winPtr->changes.width = (unsigned) width; | winPtr->changes.width = (unsigned) width; |
1690 | winPtr->changes.height = (unsigned) height; | winPtr->changes.height = (unsigned) height; |
1691 | if (winPtr->window != None) { | if (winPtr->window != None) { |
1692 | XResizeWindow(winPtr->display, winPtr->window, (unsigned) width, | XResizeWindow(winPtr->display, winPtr->window, (unsigned) width, |
1693 | (unsigned) height); | (unsigned) height); |
1694 | TkDoConfigureNotify(winPtr); | TkDoConfigureNotify(winPtr); |
1695 | } else { | } else { |
1696 | winPtr->dirtyChanges |= CWWidth|CWHeight; | winPtr->dirtyChanges |= CWWidth|CWHeight; |
1697 | winPtr->flags |= TK_NEED_CONFIG_NOTIFY; | winPtr->flags |= TK_NEED_CONFIG_NOTIFY; |
1698 | } | } |
1699 | } | } |
1700 | ||
1701 | void | void |
1702 | Tk_MoveResizeWindow(tkwin, x, y, width, height) | Tk_MoveResizeWindow(tkwin, x, y, width, height) |
1703 | Tk_Window tkwin; /* Window to move and resize. */ | Tk_Window tkwin; /* Window to move and resize. */ |
1704 | int x, y; /* New location for window (within | int x, y; /* New location for window (within |
1705 | * parent). */ | * parent). */ |
1706 | int width, height; /* New dimensions for window. */ | int width, height; /* New dimensions for window. */ |
1707 | { | { |
1708 | register TkWindow *winPtr = (TkWindow *) tkwin; | register TkWindow *winPtr = (TkWindow *) tkwin; |
1709 | ||
1710 | winPtr->changes.x = x; | winPtr->changes.x = x; |
1711 | winPtr->changes.y = y; | winPtr->changes.y = y; |
1712 | winPtr->changes.width = (unsigned) width; | winPtr->changes.width = (unsigned) width; |
1713 | winPtr->changes.height = (unsigned) height; | winPtr->changes.height = (unsigned) height; |
1714 | if (winPtr->window != None) { | if (winPtr->window != None) { |
1715 | XMoveResizeWindow(winPtr->display, winPtr->window, x, y, | XMoveResizeWindow(winPtr->display, winPtr->window, x, y, |
1716 | (unsigned) width, (unsigned) height); | (unsigned) width, (unsigned) height); |
1717 | TkDoConfigureNotify(winPtr); | TkDoConfigureNotify(winPtr); |
1718 | } else { | } else { |
1719 | winPtr->dirtyChanges |= CWX|CWY|CWWidth|CWHeight; | winPtr->dirtyChanges |= CWX|CWY|CWWidth|CWHeight; |
1720 | winPtr->flags |= TK_NEED_CONFIG_NOTIFY; | winPtr->flags |= TK_NEED_CONFIG_NOTIFY; |
1721 | } | } |
1722 | } | } |
1723 | ||
1724 | void | void |
1725 | Tk_SetWindowBorderWidth(tkwin, width) | Tk_SetWindowBorderWidth(tkwin, width) |
1726 | Tk_Window tkwin; /* Window to modify. */ | Tk_Window tkwin; /* Window to modify. */ |
1727 | int width; /* New border width for window. */ | int width; /* New border width for window. */ |
1728 | { | { |
1729 | register TkWindow *winPtr = (TkWindow *) tkwin; | register TkWindow *winPtr = (TkWindow *) tkwin; |
1730 | ||
1731 | winPtr->changes.border_width = width; | winPtr->changes.border_width = width; |
1732 | if (winPtr->window != None) { | if (winPtr->window != None) { |
1733 | XSetWindowBorderWidth(winPtr->display, winPtr->window, | XSetWindowBorderWidth(winPtr->display, winPtr->window, |
1734 | (unsigned) width); | (unsigned) width); |
1735 | TkDoConfigureNotify(winPtr); | TkDoConfigureNotify(winPtr); |
1736 | } else { | } else { |
1737 | winPtr->dirtyChanges |= CWBorderWidth; | winPtr->dirtyChanges |= CWBorderWidth; |
1738 | winPtr->flags |= TK_NEED_CONFIG_NOTIFY; | winPtr->flags |= TK_NEED_CONFIG_NOTIFY; |
1739 | } | } |
1740 | } | } |
1741 | ||
1742 | void | void |
1743 | Tk_ChangeWindowAttributes(tkwin, valueMask, attsPtr) | Tk_ChangeWindowAttributes(tkwin, valueMask, attsPtr) |
1744 | Tk_Window tkwin; /* Window to manipulate. */ | Tk_Window tkwin; /* Window to manipulate. */ |
1745 | unsigned long valueMask; /* OR'ed combination of bits, | unsigned long valueMask; /* OR'ed combination of bits, |
1746 | * indicating which fields of | * indicating which fields of |
1747 | * *attsPtr are to be used. */ | * *attsPtr are to be used. */ |
1748 | register XSetWindowAttributes *attsPtr; | register XSetWindowAttributes *attsPtr; |
1749 | /* New values for some attributes. */ | /* New values for some attributes. */ |
1750 | { | { |
1751 | register TkWindow *winPtr = (TkWindow *) tkwin; | register TkWindow *winPtr = (TkWindow *) tkwin; |
1752 | ||
1753 | if (valueMask & CWBackPixmap) { | if (valueMask & CWBackPixmap) { |
1754 | winPtr->atts.background_pixmap = attsPtr->background_pixmap; | winPtr->atts.background_pixmap = attsPtr->background_pixmap; |
1755 | } | } |
1756 | if (valueMask & CWBackPixel) { | if (valueMask & CWBackPixel) { |
1757 | winPtr->atts.background_pixel = attsPtr->background_pixel; | winPtr->atts.background_pixel = attsPtr->background_pixel; |
1758 | } | } |
1759 | if (valueMask & CWBorderPixmap) { | if (valueMask & CWBorderPixmap) { |
1760 | winPtr->atts.border_pixmap = attsPtr->border_pixmap; | winPtr->atts.border_pixmap = attsPtr->border_pixmap; |
1761 | } | } |
1762 | if (valueMask & CWBorderPixel) { | if (valueMask & CWBorderPixel) { |
1763 | winPtr->atts.border_pixel = attsPtr->border_pixel; | winPtr->atts.border_pixel = attsPtr->border_pixel; |
1764 | } | } |
1765 | if (valueMask & CWBitGravity) { | if (valueMask & CWBitGravity) { |
1766 | winPtr->atts.bit_gravity = attsPtr->bit_gravity; | winPtr->atts.bit_gravity = attsPtr->bit_gravity; |
1767 | } | } |
1768 | if (valueMask & CWWinGravity) { | if (valueMask & CWWinGravity) { |
1769 | winPtr->atts.win_gravity = attsPtr->win_gravity; | winPtr->atts.win_gravity = attsPtr->win_gravity; |
1770 | } | } |
1771 | if (valueMask & CWBackingStore) { | if (valueMask & CWBackingStore) { |
1772 | winPtr->atts.backing_store = attsPtr->backing_store; | winPtr->atts.backing_store = attsPtr->backing_store; |
1773 | } | } |
1774 | if (valueMask & CWBackingPlanes) { | if (valueMask & CWBackingPlanes) { |
1775 | winPtr->atts.backing_planes = attsPtr->backing_planes; | winPtr->atts.backing_planes = attsPtr->backing_planes; |
1776 | } | } |
1777 | if (valueMask & CWBackingPixel) { | if (valueMask & CWBackingPixel) { |
1778 | winPtr->atts.backing_pixel = attsPtr->backing_pixel; | winPtr->atts.backing_pixel = attsPtr->backing_pixel; |
1779 | } | } |
1780 | if (valueMask & CWOverrideRedirect) { | if (valueMask & CWOverrideRedirect) { |
1781 | winPtr->atts.override_redirect = attsPtr->override_redirect; | winPtr->atts.override_redirect = attsPtr->override_redirect; |
1782 | } | } |
1783 | if (valueMask & CWSaveUnder) { | if (valueMask & CWSaveUnder) { |
1784 | winPtr->atts.save_under = attsPtr->save_under; | winPtr->atts.save_under = attsPtr->save_under; |
1785 | } | } |
1786 | if (valueMask & CWEventMask) { | if (valueMask & CWEventMask) { |
1787 | winPtr->atts.event_mask = attsPtr->event_mask; | winPtr->atts.event_mask = attsPtr->event_mask; |
1788 | } | } |
1789 | if (valueMask & CWDontPropagate) { | if (valueMask & CWDontPropagate) { |
1790 | winPtr->atts.do_not_propagate_mask | winPtr->atts.do_not_propagate_mask |
1791 | = attsPtr->do_not_propagate_mask; | = attsPtr->do_not_propagate_mask; |
1792 | } | } |
1793 | if (valueMask & CWColormap) { | if (valueMask & CWColormap) { |
1794 | winPtr->atts.colormap = attsPtr->colormap; | winPtr->atts.colormap = attsPtr->colormap; |
1795 | } | } |
1796 | if (valueMask & CWCursor) { | if (valueMask & CWCursor) { |
1797 | winPtr->atts.cursor = attsPtr->cursor; | winPtr->atts.cursor = attsPtr->cursor; |
1798 | } | } |
1799 | ||
1800 | if (winPtr->window != None) { | if (winPtr->window != None) { |
1801 | XChangeWindowAttributes(winPtr->display, winPtr->window, | XChangeWindowAttributes(winPtr->display, winPtr->window, |
1802 | valueMask, attsPtr); | valueMask, attsPtr); |
1803 | } else { | } else { |
1804 | winPtr->dirtyAtts |= valueMask; | winPtr->dirtyAtts |= valueMask; |
1805 | } | } |
1806 | } | } |
1807 | ||
1808 | void | void |
1809 | Tk_SetWindowBackground(tkwin, pixel) | Tk_SetWindowBackground(tkwin, pixel) |
1810 | Tk_Window tkwin; /* Window to manipulate. */ | Tk_Window tkwin; /* Window to manipulate. */ |
1811 | unsigned long pixel; /* Pixel value to use for | unsigned long pixel; /* Pixel value to use for |
1812 | * window's background. */ | * window's background. */ |
1813 | { | { |
1814 | register TkWindow *winPtr = (TkWindow *) tkwin; | register TkWindow *winPtr = (TkWindow *) tkwin; |
1815 | ||
1816 | winPtr->atts.background_pixel = pixel; | winPtr->atts.background_pixel = pixel; |
1817 | ||
1818 | if (winPtr->window != None) { | if (winPtr->window != None) { |
1819 | XSetWindowBackground(winPtr->display, winPtr->window, pixel); | XSetWindowBackground(winPtr->display, winPtr->window, pixel); |
1820 | } else { | } else { |
1821 | winPtr->dirtyAtts = (winPtr->dirtyAtts & (unsigned) ~CWBackPixmap) | winPtr->dirtyAtts = (winPtr->dirtyAtts & (unsigned) ~CWBackPixmap) |
1822 | | CWBackPixel; | | CWBackPixel; |
1823 | } | } |
1824 | } | } |
1825 | ||
1826 | void | void |
1827 | Tk_SetWindowBackgroundPixmap(tkwin, pixmap) | Tk_SetWindowBackgroundPixmap(tkwin, pixmap) |
1828 | Tk_Window tkwin; /* Window to manipulate. */ | Tk_Window tkwin; /* Window to manipulate. */ |
1829 | Pixmap pixmap; /* Pixmap to use for window's | Pixmap pixmap; /* Pixmap to use for window's |
1830 | * background. */ | * background. */ |
1831 | { | { |
1832 | register TkWindow *winPtr = (TkWindow *) tkwin; | register TkWindow *winPtr = (TkWindow *) tkwin; |
1833 | ||
1834 | winPtr->atts.background_pixmap = pixmap; | winPtr->atts.background_pixmap = pixmap; |
1835 | ||
1836 | if (winPtr->window != None) { | if (winPtr->window != None) { |
1837 | XSetWindowBackgroundPixmap(winPtr->display, | XSetWindowBackgroundPixmap(winPtr->display, |
1838 | winPtr->window, pixmap); | winPtr->window, pixmap); |
1839 | } else { | } else { |
1840 | winPtr->dirtyAtts = (winPtr->dirtyAtts & (unsigned) ~CWBackPixel) | winPtr->dirtyAtts = (winPtr->dirtyAtts & (unsigned) ~CWBackPixel) |
1841 | | CWBackPixmap; | | CWBackPixmap; |
1842 | } | } |
1843 | } | } |
1844 | ||
1845 | void | void |
1846 | Tk_SetWindowBorder(tkwin, pixel) | Tk_SetWindowBorder(tkwin, pixel) |
1847 | Tk_Window tkwin; /* Window to manipulate. */ | Tk_Window tkwin; /* Window to manipulate. */ |
1848 | unsigned long pixel; /* Pixel value to use for | unsigned long pixel; /* Pixel value to use for |
1849 | * window's border. */ | * window's border. */ |
1850 | { | { |
1851 | register TkWindow *winPtr = (TkWindow *) tkwin; | register TkWindow *winPtr = (TkWindow *) tkwin; |
1852 | ||
1853 | winPtr->atts.border_pixel = pixel; | winPtr->atts.border_pixel = pixel; |
1854 | ||
1855 | if (winPtr->window != None) { | if (winPtr->window != None) { |
1856 | XSetWindowBorder(winPtr->display, winPtr->window, pixel); | XSetWindowBorder(winPtr->display, winPtr->window, pixel); |
1857 | } else { | } else { |
1858 | winPtr->dirtyAtts = (winPtr->dirtyAtts & (unsigned) ~CWBorderPixmap) | winPtr->dirtyAtts = (winPtr->dirtyAtts & (unsigned) ~CWBorderPixmap) |
1859 | | CWBorderPixel; | | CWBorderPixel; |
1860 | } | } |
1861 | } | } |
1862 | ||
1863 | void | void |
1864 | Tk_SetWindowBorderPixmap(tkwin, pixmap) | Tk_SetWindowBorderPixmap(tkwin, pixmap) |
1865 | Tk_Window tkwin; /* Window to manipulate. */ | Tk_Window tkwin; /* Window to manipulate. */ |
1866 | Pixmap pixmap; /* Pixmap to use for window's | Pixmap pixmap; /* Pixmap to use for window's |
1867 | * border. */ | * border. */ |
1868 | { | { |
1869 | register TkWindow *winPtr = (TkWindow *) tkwin; | register TkWindow *winPtr = (TkWindow *) tkwin; |
1870 | ||
1871 | winPtr->atts.border_pixmap = pixmap; | winPtr->atts.border_pixmap = pixmap; |
1872 | ||
1873 | if (winPtr->window != None) { | if (winPtr->window != None) { |
1874 | XSetWindowBorderPixmap(winPtr->display, | XSetWindowBorderPixmap(winPtr->display, |
1875 | winPtr->window, pixmap); | winPtr->window, pixmap); |
1876 | } else { | } else { |
1877 | winPtr->dirtyAtts = (winPtr->dirtyAtts & (unsigned) ~CWBorderPixel) | winPtr->dirtyAtts = (winPtr->dirtyAtts & (unsigned) ~CWBorderPixel) |
1878 | | CWBorderPixmap; | | CWBorderPixmap; |
1879 | } | } |
1880 | } | } |
1881 | ||
1882 | void | void |
1883 | Tk_DefineCursor(tkwin, cursor) | Tk_DefineCursor(tkwin, cursor) |
1884 | Tk_Window tkwin; /* Window to manipulate. */ | Tk_Window tkwin; /* Window to manipulate. */ |
1885 | Tk_Cursor cursor; /* Cursor to use for window (may be None). */ | Tk_Cursor cursor; /* Cursor to use for window (may be None). */ |
1886 | { | { |
1887 | register TkWindow *winPtr = (TkWindow *) tkwin; | register TkWindow *winPtr = (TkWindow *) tkwin; |
1888 | ||
1889 | #ifdef MAC_TCL | #ifdef MAC_TCL |
1890 | winPtr->atts.cursor = (XCursor) cursor; | winPtr->atts.cursor = (XCursor) cursor; |
1891 | #else | #else |
1892 | winPtr->atts.cursor = (Cursor) cursor; | winPtr->atts.cursor = (Cursor) cursor; |
1893 | #endif | #endif |
1894 | ||
1895 | if (winPtr->window != None) { | if (winPtr->window != None) { |
1896 | XDefineCursor(winPtr->display, winPtr->window, winPtr->atts.cursor); | XDefineCursor(winPtr->display, winPtr->window, winPtr->atts.cursor); |
1897 | } else { | } else { |
1898 | winPtr->dirtyAtts = winPtr->dirtyAtts | CWCursor; | winPtr->dirtyAtts = winPtr->dirtyAtts | CWCursor; |
1899 | } | } |
1900 | } | } |
1901 | ||
1902 | void | void |
1903 | Tk_UndefineCursor(tkwin) | Tk_UndefineCursor(tkwin) |
1904 | Tk_Window tkwin; /* Window to manipulate. */ | Tk_Window tkwin; /* Window to manipulate. */ |
1905 | { | { |
1906 | Tk_DefineCursor(tkwin, None); | Tk_DefineCursor(tkwin, None); |
1907 | } | } |
1908 | ||
1909 | void | void |
1910 | Tk_SetWindowColormap(tkwin, colormap) | Tk_SetWindowColormap(tkwin, colormap) |
1911 | Tk_Window tkwin; /* Window to manipulate. */ | Tk_Window tkwin; /* Window to manipulate. */ |
1912 | Colormap colormap; /* Colormap to use for window. */ | Colormap colormap; /* Colormap to use for window. */ |
1913 | { | { |
1914 | register TkWindow *winPtr = (TkWindow *) tkwin; | register TkWindow *winPtr = (TkWindow *) tkwin; |
1915 | ||
1916 | winPtr->atts.colormap = colormap; | winPtr->atts.colormap = colormap; |
1917 | ||
1918 | if (winPtr->window != None) { | if (winPtr->window != None) { |
1919 | XSetWindowColormap(winPtr->display, winPtr->window, colormap); | XSetWindowColormap(winPtr->display, winPtr->window, colormap); |
1920 | if (!(winPtr->flags & TK_TOP_LEVEL)) { | if (!(winPtr->flags & TK_TOP_LEVEL)) { |
1921 | TkWmAddToColormapWindows(winPtr); | TkWmAddToColormapWindows(winPtr); |
1922 | winPtr->flags |= TK_WM_COLORMAP_WINDOW; | winPtr->flags |= TK_WM_COLORMAP_WINDOW; |
1923 | } | } |
1924 | } else { | } else { |
1925 | winPtr->dirtyAtts |= CWColormap; | winPtr->dirtyAtts |= CWColormap; |
1926 | } | } |
1927 | } | } |
1928 | ||
1929 | /* | /* |
1930 | *---------------------------------------------------------------------- | *---------------------------------------------------------------------- |
1931 | * | * |
1932 | * Tk_SetWindowVisual -- | * Tk_SetWindowVisual -- |
1933 | * | * |
1934 | * This procedure is called to specify a visual to be used | * This procedure is called to specify a visual to be used |
1935 | * for a Tk window when it is created. This procedure, if | * for a Tk window when it is created. This procedure, if |
1936 | * called at all, must be called before the X window is created | * called at all, must be called before the X window is created |
1937 | * (i.e. before Tk_MakeWindowExist is called). | * (i.e. before Tk_MakeWindowExist is called). |
1938 | * | * |
1939 | * Results: | * Results: |
1940 | * The return value is 1 if successful, or 0 if the X window has | * The return value is 1 if successful, or 0 if the X window has |
1941 | * been already created. | * been already created. |
1942 | * | * |
1943 | * Side effects: | * Side effects: |
1944 | * The information given is stored for when the window is created. | * The information given is stored for when the window is created. |
1945 | * | * |
1946 | *---------------------------------------------------------------------- | *---------------------------------------------------------------------- |
1947 | */ | */ |
1948 | ||
1949 | int | int |
1950 | Tk_SetWindowVisual(tkwin, visual, depth, colormap) | Tk_SetWindowVisual(tkwin, visual, depth, colormap) |
1951 | Tk_Window tkwin; /* Window to manipulate. */ | Tk_Window tkwin; /* Window to manipulate. */ |
1952 | Visual *visual; /* New visual for window. */ | Visual *visual; /* New visual for window. */ |
1953 | int depth; /* New depth for window. */ | int depth; /* New depth for window. */ |
1954 | Colormap colormap; /* An appropriate colormap for the visual. */ | Colormap colormap; /* An appropriate colormap for the visual. */ |
1955 | { | { |
1956 | register TkWindow *winPtr = (TkWindow *) tkwin; | register TkWindow *winPtr = (TkWindow *) tkwin; |
1957 | ||
1958 | if( winPtr->window != None ){ | if( winPtr->window != None ){ |
1959 | /* Too late! */ | /* Too late! */ |
1960 | return 0; | return 0; |
1961 | } | } |
1962 | ||
1963 | winPtr->visual = visual; | winPtr->visual = visual; |
1964 | winPtr->depth = depth; | winPtr->depth = depth; |
1965 | winPtr->atts.colormap = colormap; | winPtr->atts.colormap = colormap; |
1966 | winPtr->dirtyAtts |= CWColormap; | winPtr->dirtyAtts |= CWColormap; |
1967 | ||
1968 | /* | /* |
1969 | * The following code is needed to make sure that the window doesn't | * The following code is needed to make sure that the window doesn't |
1970 | * inherit the parent's border pixmap, which would result in a BadMatch | * inherit the parent's border pixmap, which would result in a BadMatch |
1971 | * error. | * error. |
1972 | */ | */ |
1973 | ||
1974 | if (!(winPtr->dirtyAtts & CWBorderPixmap)) { | if (!(winPtr->dirtyAtts & CWBorderPixmap)) { |
1975 | winPtr->dirtyAtts |= CWBorderPixel; | winPtr->dirtyAtts |= CWBorderPixel; |
1976 | } | } |
1977 | return 1; | return 1; |
1978 | } | } |
1979 | ||
1980 | /* | /* |
1981 | *---------------------------------------------------------------------- | *---------------------------------------------------------------------- |
1982 | * | * |
1983 | * TkDoConfigureNotify -- | * TkDoConfigureNotify -- |
1984 | * | * |
1985 | * Generate a ConfigureNotify event describing the current | * Generate a ConfigureNotify event describing the current |
1986 | * configuration of a window. | * configuration of a window. |
1987 | * | * |
1988 | * Results: | * Results: |
1989 | * None. | * None. |
1990 | * | * |
1991 | * Side effects: | * Side effects: |
1992 | * An event is generated and processed by Tk_HandleEvent. | * An event is generated and processed by Tk_HandleEvent. |
1993 | * | * |
1994 | *---------------------------------------------------------------------- | *---------------------------------------------------------------------- |
1995 | */ | */ |
1996 | ||
1997 | void | void |
1998 | TkDoConfigureNotify(winPtr) | TkDoConfigureNotify(winPtr) |
1999 | register TkWindow *winPtr; /* Window whose configuration | register TkWindow *winPtr; /* Window whose configuration |
2000 | * was just changed. */ | * was just changed. */ |
2001 | { | { |
2002 | XEvent event; | XEvent event; |
2003 | ||
2004 | event.type = ConfigureNotify; | event.type = ConfigureNotify; |
2005 | event.xconfigure.serial = LastKnownRequestProcessed(winPtr->display); | event.xconfigure.serial = LastKnownRequestProcessed(winPtr->display); |
2006 | event.xconfigure.send_event = False; | event.xconfigure.send_event = False; |
2007 | event.xconfigure.display = winPtr->display; | event.xconfigure.display = winPtr->display; |
2008 | event.xconfigure.event = winPtr->window; | event.xconfigure.event = winPtr->window; |
2009 | event.xconfigure.window = winPtr->window; | event.xconfigure.window = winPtr->window; |
2010 | event.xconfigure.x = winPtr->changes.x; | event.xconfigure.x = winPtr->changes.x; |
2011 | event.xconfigure.y = winPtr->changes.y; | event.xconfigure.y = winPtr->changes.y; |
2012 | event.xconfigure.width = winPtr->changes.width; | event.xconfigure.width = winPtr->changes.width; |
2013 | event.xconfigure.height = winPtr->changes.height; | event.xconfigure.height = winPtr->changes.height; |
2014 | event.xconfigure.border_width = winPtr->changes.border_width; | event.xconfigure.border_width = winPtr->changes.border_width; |
2015 | if (winPtr->changes.stack_mode == Above) { | if (winPtr->changes.stack_mode == Above) { |
2016 | event.xconfigure.above = winPtr->changes.sibling; | event.xconfigure.above = winPtr->changes.sibling; |
2017 | } else { | } else { |
2018 | event.xconfigure.above = None; | event.xconfigure.above = None; |
2019 | } | } |
2020 | event.xconfigure.override_redirect = winPtr->atts.override_redirect; | event.xconfigure.override_redirect = winPtr->atts.override_redirect; |
2021 | Tk_HandleEvent(&event); | Tk_HandleEvent(&event); |
2022 | } | } |
2023 | ||
2024 | /* | /* |
2025 | *---------------------------------------------------------------------- | *---------------------------------------------------------------------- |
2026 | * | * |
2027 | * Tk_SetClass -- | * Tk_SetClass -- |
2028 | * | * |
2029 | * This procedure is used to give a window a class. | * This procedure is used to give a window a class. |
2030 | * | * |
2031 | * Results: | * Results: |
2032 | * None. | * None. |
2033 | * | * |
2034 | * Side effects: | * Side effects: |
2035 | * A new class is stored for tkwin, replacing any existing | * A new class is stored for tkwin, replacing any existing |
2036 | * class for it. | * class for it. |
2037 | * | * |
2038 | *---------------------------------------------------------------------- | *---------------------------------------------------------------------- |
2039 | */ | */ |
2040 | ||
2041 | void | void |
2042 | Tk_SetClass(tkwin, className) | Tk_SetClass(tkwin, className) |
2043 | Tk_Window tkwin; /* Token for window to assign class. */ | Tk_Window tkwin; /* Token for window to assign class. */ |
2044 | char *className; /* New class for tkwin. */ | char *className; /* New class for tkwin. */ |
2045 | { | { |
2046 | register TkWindow *winPtr = (TkWindow *) tkwin; | register TkWindow *winPtr = (TkWindow *) tkwin; |
2047 | ||
2048 | winPtr->classUid = Tk_GetUid(className); | winPtr->classUid = Tk_GetUid(className); |
2049 | if (winPtr->flags & TK_TOP_LEVEL) { | if (winPtr->flags & TK_TOP_LEVEL) { |
2050 | TkWmSetClass(winPtr); | TkWmSetClass(winPtr); |
2051 | } | } |
2052 | TkOptionClassChanged(winPtr); | TkOptionClassChanged(winPtr); |
2053 | } | } |
2054 | ||
2055 | /* | /* |
2056 | *---------------------------------------------------------------------- | *---------------------------------------------------------------------- |
2057 | * | * |
2058 | * TkSetClassProcs -- | * TkSetClassProcs -- |
2059 | * | * |
2060 | * This procedure is used to set the class procedures and | * This procedure is used to set the class procedures and |
2061 | * instance data for a window. | * instance data for a window. |
2062 | * | * |
2063 | * Results: | * Results: |
2064 | * None. | * None. |
2065 | * | * |
2066 | * Side effects: | * Side effects: |
2067 | * A new set of class procedures and instance data is stored | * A new set of class procedures and instance data is stored |
2068 | * for tkwin, replacing any existing values. | * for tkwin, replacing any existing values. |
2069 | * | * |
2070 | *---------------------------------------------------------------------- | *---------------------------------------------------------------------- |
2071 | */ | */ |
2072 | ||
2073 | void | void |
2074 | TkSetClassProcs(tkwin, procs, instanceData) | TkSetClassProcs(tkwin, procs, instanceData) |
2075 | Tk_Window tkwin; /* Token for window to modify. */ | Tk_Window tkwin; /* Token for window to modify. */ |
2076 | TkClassProcs *procs; /* Class procs structure. */ | TkClassProcs *procs; /* Class procs structure. */ |
2077 | ClientData instanceData; /* Data to be passed to class procedures. */ | ClientData instanceData; /* Data to be passed to class procedures. */ |
2078 | { | { |
2079 | register TkWindow *winPtr = (TkWindow *) tkwin; | register TkWindow *winPtr = (TkWindow *) tkwin; |
2080 | ||
2081 | winPtr->classProcsPtr = procs; | winPtr->classProcsPtr = procs; |
2082 | winPtr->instanceData = instanceData; | winPtr->instanceData = instanceData; |
2083 | } | } |
2084 | ||
2085 | /* | /* |
2086 | *---------------------------------------------------------------------- | *---------------------------------------------------------------------- |
2087 | * | * |
2088 | * Tk_NameToWindow -- | * Tk_NameToWindow -- |
2089 | * | * |
2090 | * Given a string name for a window, this procedure | * Given a string name for a window, this procedure |
2091 | * returns the token for the window, if there exists a | * returns the token for the window, if there exists a |
2092 | * window corresponding to the given name. | * window corresponding to the given name. |
2093 | * | * |
2094 | * Results: | * Results: |
2095 | * The return result is either a token for the window corresponding | * The return result is either a token for the window corresponding |
2096 | * to "name", or else NULL to indicate that there is no such | * to "name", or else NULL to indicate that there is no such |
2097 | * window. In this case, an error message is left in the interp's result. | * window. In this case, an error message is left in the interp's result. |
2098 | * | * |
2099 | * Side effects: | * Side effects: |
2100 | * None. | * None. |
2101 | * | * |
2102 | *---------------------------------------------------------------------- | *---------------------------------------------------------------------- |
2103 | */ | */ |
2104 | ||
2105 | Tk_Window | Tk_Window |
2106 | Tk_NameToWindow(interp, pathName, tkwin) | Tk_NameToWindow(interp, pathName, tkwin) |
2107 | Tcl_Interp *interp; /* Where to report errors. */ | Tcl_Interp *interp; /* Where to report errors. */ |
2108 | char *pathName; /* Path name of window. */ | char *pathName; /* Path name of window. */ |
2109 | Tk_Window tkwin; /* Token for window: name is assumed to | Tk_Window tkwin; /* Token for window: name is assumed to |
2110 | * belong to the same main window as tkwin. */ | * belong to the same main window as tkwin. */ |
2111 | { | { |
2112 | Tcl_HashEntry *hPtr; | Tcl_HashEntry *hPtr; |
2113 | ||
2114 | if (tkwin == NULL) { | if (tkwin == NULL) { |
2115 | /* | /* |
2116 | * Either we're not really in Tk, or the main window was destroyed and | * Either we're not really in Tk, or the main window was destroyed and |
2117 | * we're on our way out of the application | * we're on our way out of the application |
2118 | */ | */ |
2119 | Tcl_AppendResult(interp, "NULL main window", (char *)NULL); | Tcl_AppendResult(interp, "NULL main window", (char *)NULL); |
2120 | return NULL; | return NULL; |
2121 | } | } |
2122 | ||
2123 | hPtr = Tcl_FindHashEntry(&((TkWindow *) tkwin)->mainPtr->nameTable, | hPtr = Tcl_FindHashEntry(&((TkWindow *) tkwin)->mainPtr->nameTable, |
2124 | pathName); | pathName); |
2125 | if (hPtr == NULL) { | if (hPtr == NULL) { |
2126 | Tcl_AppendResult(interp, "bad window path name \"", | Tcl_AppendResult(interp, "bad window path name \"", |
2127 | pathName, "\"", (char *) NULL); | pathName, "\"", (char *) NULL); |
2128 | return NULL; | return NULL; |
2129 | } | } |
2130 | return (Tk_Window) Tcl_GetHashValue(hPtr); | return (Tk_Window) Tcl_GetHashValue(hPtr); |
2131 | } | } |
2132 | ||
2133 | /* | /* |
2134 | *---------------------------------------------------------------------- | *---------------------------------------------------------------------- |
2135 | * | * |
2136 | * Tk_IdToWindow -- | * Tk_IdToWindow -- |
2137 | * | * |
2138 | * Given an X display and window ID, this procedure returns the | * Given an X display and window ID, this procedure returns the |
2139 | * Tk token for the window, if there exists a Tk window corresponding | * Tk token for the window, if there exists a Tk window corresponding |
2140 | * to the given ID. | * to the given ID. |
2141 | * | * |
2142 | * Results: | * Results: |
2143 | * The return result is either a token for the window corresponding | * The return result is either a token for the window corresponding |
2144 | * to the given X id, or else NULL to indicate that there is no such | * to the given X id, or else NULL to indicate that there is no such |
2145 | * window. | * window. |
2146 | * | * |
2147 | * Side effects: | * Side effects: |
2148 | * None. | * None. |
2149 | * | * |
2150 | *---------------------------------------------------------------------- | *---------------------------------------------------------------------- |
2151 | */ | */ |
2152 | ||
2153 | Tk_Window | Tk_Window |
2154 | Tk_IdToWindow(display, window) | Tk_IdToWindow(display, window) |
2155 | Display *display; /* X display containing the window. */ | Display *display; /* X display containing the window. */ |
2156 | Window window; /* X window window id. */ | Window window; /* X window window id. */ |
2157 | { | { |
2158 | TkDisplay *dispPtr; | TkDisplay *dispPtr; |
2159 | Tcl_HashEntry *hPtr; | Tcl_HashEntry *hPtr; |
2160 | ||
2161 | for (dispPtr = TkGetDisplayList(); ; dispPtr = dispPtr->nextPtr) { | for (dispPtr = TkGetDisplayList(); ; dispPtr = dispPtr->nextPtr) { |
2162 | if (dispPtr == NULL) { | if (dispPtr == NULL) { |
2163 | return NULL; | return NULL; |
2164 | } | } |
2165 | if (dispPtr->display == display) { | if (dispPtr->display == display) { |
2166 | break; | break; |
2167 | } | } |
2168 | } | } |
2169 | ||
2170 | hPtr = Tcl_FindHashEntry(&dispPtr->winTable, (char *) window); | hPtr = Tcl_FindHashEntry(&dispPtr->winTable, (char *) window); |
2171 | if (hPtr == NULL) { | if (hPtr == NULL) { |
2172 | return NULL; | return NULL; |
2173 | } | } |
2174 | return (Tk_Window) Tcl_GetHashValue(hPtr); | return (Tk_Window) Tcl_GetHashValue(hPtr); |
2175 | } | } |
2176 | ||
2177 | /* | /* |
2178 | *---------------------------------------------------------------------- | *---------------------------------------------------------------------- |
2179 | * | * |
2180 | * Tk_DisplayName -- | * Tk_DisplayName -- |
2181 | * | * |
2182 | * Return the textual name of a window's display. | * Return the textual name of a window's display. |
2183 | * | * |
2184 | * Results: | * Results: |
2185 | * The return value is the string name of the display associated | * The return value is the string name of the display associated |
2186 | * with tkwin. | * with tkwin. |
2187 | * | * |
2188 | * Side effects: | * Side effects: |
2189 | * None. | * None. |
2190 | * | * |
2191 | *---------------------------------------------------------------------- | *---------------------------------------------------------------------- |
2192 | */ | */ |
2193 | ||
2194 | char * | char * |
2195 | Tk_DisplayName(tkwin) | Tk_DisplayName(tkwin) |
2196 | Tk_Window tkwin; /* Window whose display name is desired. */ | Tk_Window tkwin; /* Window whose display name is desired. */ |
2197 | { | { |
2198 | return ((TkWindow *) tkwin)->dispPtr->name; | return ((TkWindow *) tkwin)->dispPtr->name; |
2199 | } | } |
2200 | ||
2201 | /* | /* |
2202 | *---------------------------------------------------------------------- | *---------------------------------------------------------------------- |
2203 | * | * |
2204 | * UnlinkWindow -- | * UnlinkWindow -- |
2205 | * | * |
2206 | * This procedure removes a window from the childList of its | * This procedure removes a window from the childList of its |
2207 | * parent. | * parent. |
2208 | * | * |
2209 | * Results: | * Results: |
2210 | * None. | * None. |
2211 | * | * |
2212 | * Side effects: | * Side effects: |
2213 | * The window is unlinked from its childList. | * The window is unlinked from its childList. |
2214 | * | * |
2215 | *---------------------------------------------------------------------- | *---------------------------------------------------------------------- |
2216 | */ | */ |
2217 | ||
2218 | static void | static void |
2219 | UnlinkWindow(winPtr) | UnlinkWindow(winPtr) |
2220 | TkWindow *winPtr; /* Child window to be unlinked. */ | TkWindow *winPtr; /* Child window to be unlinked. */ |
2221 | { | { |
2222 | TkWindow *prevPtr; | TkWindow *prevPtr; |
2223 | ||
2224 | if (winPtr->parentPtr == NULL) { | if (winPtr->parentPtr == NULL) { |
2225 | return; | return; |
2226 | } | } |
2227 | prevPtr = winPtr->parentPtr->childList; | prevPtr = winPtr->parentPtr->childList; |
2228 | if (prevPtr == winPtr) { | if (prevPtr == winPtr) { |
2229 | winPtr->parentPtr->childList = winPtr->nextPtr; | winPtr->parentPtr->childList = winPtr->nextPtr; |
2230 | if (winPtr->nextPtr == NULL) { | if (winPtr->nextPtr == NULL) { |
2231 | winPtr->parentPtr->lastChildPtr = NULL; | winPtr->parentPtr->lastChildPtr = NULL; |
2232 | } | } |
2233 | } else { | } else { |
2234 | while (prevPtr->nextPtr != winPtr) { | while (prevPtr->nextPtr != winPtr) { |
2235 | prevPtr = prevPtr->nextPtr; | prevPtr = prevPtr->nextPtr; |
2236 | if (prevPtr == NULL) { | if (prevPtr == NULL) { |
2237 | panic("UnlinkWindow couldn't find child in parent"); | panic("UnlinkWindow couldn't find child in parent"); |
2238 | } | } |
2239 | } | } |
2240 | prevPtr->nextPtr = winPtr->nextPtr; | prevPtr->nextPtr = winPtr->nextPtr; |
2241 | if (winPtr->nextPtr == NULL) { | if (winPtr->nextPtr == NULL) { |
2242 | winPtr->parentPtr->lastChildPtr = prevPtr; | winPtr->parentPtr->lastChildPtr = prevPtr; |
2243 | } | } |
2244 | } | } |
2245 | } | } |
2246 | ||
2247 | /* | /* |
2248 | *---------------------------------------------------------------------- | *---------------------------------------------------------------------- |
2249 | * | * |
2250 | * Tk_RestackWindow -- | * Tk_RestackWindow -- |
2251 | * | * |
2252 | * Change a window's position in the stacking order. | * Change a window's position in the stacking order. |
2253 | * | * |
2254 | * Results: | * Results: |
2255 | * TCL_OK is normally returned. If other is not a descendant | * TCL_OK is normally returned. If other is not a descendant |
2256 | * of tkwin's parent then TCL_ERROR is returned and tkwin is | * of tkwin's parent then TCL_ERROR is returned and tkwin is |
2257 | * not repositioned. | * not repositioned. |
2258 | * | * |
2259 | * Side effects: | * Side effects: |
2260 | * Tkwin is repositioned in the stacking order. | * Tkwin is repositioned in the stacking order. |
2261 | * | * |
2262 | *---------------------------------------------------------------------- | *---------------------------------------------------------------------- |
2263 | */ | */ |
2264 | ||
2265 | int | int |
2266 | Tk_RestackWindow(tkwin, aboveBelow, other) | Tk_RestackWindow(tkwin, aboveBelow, other) |
2267 | Tk_Window tkwin; /* Token for window whose position in | Tk_Window tkwin; /* Token for window whose position in |
2268 | * the stacking order is to change. */ | * the stacking order is to change. */ |
2269 | int aboveBelow; /* Indicates new position of tkwin relative | int aboveBelow; /* Indicates new position of tkwin relative |
2270 | * to other; must be Above or Below. */ | * to other; must be Above or Below. */ |
2271 | Tk_Window other; /* Tkwin will be moved to a position that | Tk_Window other; /* Tkwin will be moved to a position that |
2272 | * puts it just above or below this window. | * puts it just above or below this window. |
2273 | * If NULL then tkwin goes above or below | * If NULL then tkwin goes above or below |
2274 | * all windows in the same parent. */ | * all windows in the same parent. */ |
2275 | { | { |
2276 | TkWindow *winPtr = (TkWindow *) tkwin; | TkWindow *winPtr = (TkWindow *) tkwin; |
2277 | TkWindow *otherPtr = (TkWindow *) other; | TkWindow *otherPtr = (TkWindow *) other; |
2278 | ||
2279 | /* | /* |
2280 | * Special case: if winPtr is a top-level window then just find | * Special case: if winPtr is a top-level window then just find |
2281 | * the top-level ancestor of otherPtr and restack winPtr above | * the top-level ancestor of otherPtr and restack winPtr above |
2282 | * otherPtr without changing any of Tk's childLists. | * otherPtr without changing any of Tk's childLists. |
2283 | */ | */ |
2284 | ||
2285 | if (winPtr->flags & TK_TOP_LEVEL) { | if (winPtr->flags & TK_TOP_LEVEL) { |
2286 | while ((otherPtr != NULL) && !(otherPtr->flags & TK_TOP_LEVEL)) { | while ((otherPtr != NULL) && !(otherPtr->flags & TK_TOP_LEVEL)) { |
2287 | otherPtr = otherPtr->parentPtr; | otherPtr = otherPtr->parentPtr; |
2288 | } | } |
2289 | TkWmRestackToplevel(winPtr, aboveBelow, otherPtr); | TkWmRestackToplevel(winPtr, aboveBelow, otherPtr); |
2290 | return TCL_OK; | return TCL_OK; |
2291 | } | } |
2292 | ||
2293 | /* | /* |
2294 | * Find an ancestor of otherPtr that is a sibling of winPtr. | * Find an ancestor of otherPtr that is a sibling of winPtr. |
2295 | */ | */ |
2296 | ||
2297 | if (winPtr->parentPtr == NULL) { | if (winPtr->parentPtr == NULL) { |
2298 | /* | /* |
2299 | * Window is going to be deleted shortly; don't do anything. | * Window is going to be deleted shortly; don't do anything. |
2300 | */ | */ |
2301 | ||
2302 | return TCL_OK; | return TCL_OK; |
2303 | } | } |
2304 | if (otherPtr == NULL) { | if (otherPtr == NULL) { |
2305 | if (aboveBelow == Above) { | if (aboveBelow == Above) { |
2306 | otherPtr = winPtr->parentPtr->lastChildPtr; | otherPtr = winPtr->parentPtr->lastChildPtr; |
2307 | } else { | } else { |
2308 | otherPtr = winPtr->parentPtr->childList; | otherPtr = winPtr->parentPtr->childList; |
2309 | } | } |
2310 | } else { | } else { |
2311 | while (winPtr->parentPtr != otherPtr->parentPtr) { | while (winPtr->parentPtr != otherPtr->parentPtr) { |
2312 | if ((otherPtr == NULL) || (otherPtr->flags & TK_TOP_LEVEL)) { | if ((otherPtr == NULL) || (otherPtr->flags & TK_TOP_LEVEL)) { |
2313 | return TCL_ERROR; | return TCL_ERROR; |
2314 | } | } |
2315 | otherPtr = otherPtr->parentPtr; | otherPtr = otherPtr->parentPtr; |
2316 | } | } |
2317 | } | } |
2318 | if (otherPtr == winPtr) { | if (otherPtr == winPtr) { |
2319 | return TCL_OK; | return TCL_OK; |
2320 | } | } |
2321 | ||
2322 | /* | /* |
2323 | * Reposition winPtr in the stacking order. | * Reposition winPtr in the stacking order. |
2324 | */ | */ |
2325 | ||
2326 | UnlinkWindow(winPtr); | UnlinkWindow(winPtr); |
2327 | if (aboveBelow == Above) { | if (aboveBelow == Above) { |
2328 | winPtr->nextPtr = otherPtr->nextPtr; | winPtr->nextPtr = otherPtr->nextPtr; |
2329 | if (winPtr->nextPtr == NULL) { | if (winPtr->nextPtr == NULL) { |
2330 | winPtr->parentPtr->lastChildPtr = winPtr; | winPtr->parentPtr->lastChildPtr = winPtr; |
2331 | } | } |
2332 | otherPtr->nextPtr = winPtr; | otherPtr->nextPtr = winPtr; |
2333 | } else { | } else { |
2334 | TkWindow *prevPtr; | TkWindow *prevPtr; |
2335 | ||
2336 | prevPtr = winPtr->parentPtr->childList; | prevPtr = winPtr->parentPtr->childList; |
2337 | if (prevPtr == otherPtr) { | if (prevPtr == otherPtr) { |
2338 | winPtr->parentPtr->childList = winPtr; | winPtr->parentPtr->childList = winPtr; |
2339 | } else { | } else { |
2340 | while (prevPtr->nextPtr != otherPtr) { | while (prevPtr->nextPtr != otherPtr) { |
2341 | prevPtr = prevPtr->nextPtr; | prevPtr = prevPtr->nextPtr; |
2342 | } | } |
2343 | prevPtr->nextPtr = winPtr; | prevPtr->nextPtr = winPtr; |
2344 | } | } |
2345 | winPtr->nextPtr = otherPtr; | winPtr->nextPtr = otherPtr; |
2346 | } | } |
2347 | ||
2348 | /* | /* |
2349 | * Notify the X server of the change. If winPtr hasn't yet been | * Notify the X server of the change. If winPtr hasn't yet been |
2350 | * created then there's no need to tell the X server now, since | * created then there's no need to tell the X server now, since |
2351 | * the stacking order will be handled properly when the window | * the stacking order will be handled properly when the window |
2352 | * is finally created. | * is finally created. |
2353 | */ | */ |
2354 | ||
2355 | if (winPtr->window != None) { | if (winPtr->window != None) { |
2356 | XWindowChanges changes; | XWindowChanges changes; |
2357 | unsigned int mask; | unsigned int mask; |
2358 | ||
2359 | mask = CWStackMode; | mask = CWStackMode; |
2360 | changes.stack_mode = Above; | changes.stack_mode = Above; |
2361 | for (otherPtr = winPtr->nextPtr; otherPtr != NULL; | for (otherPtr = winPtr->nextPtr; otherPtr != NULL; |
2362 | otherPtr = otherPtr->nextPtr) { | otherPtr = otherPtr->nextPtr) { |
2363 | if ((otherPtr->window != None) | if ((otherPtr->window != None) |
2364 | && !(otherPtr->flags & (TK_TOP_LEVEL|TK_REPARENTED))){ | && !(otherPtr->flags & (TK_TOP_LEVEL|TK_REPARENTED))){ |
2365 | changes.sibling = otherPtr->window; | changes.sibling = otherPtr->window; |
2366 | changes.stack_mode = Below; | changes.stack_mode = Below; |
2367 | mask = CWStackMode|CWSibling; | mask = CWStackMode|CWSibling; |
2368 | break; | break; |
2369 | } | } |
2370 | } | } |
2371 | XConfigureWindow(winPtr->display, winPtr->window, mask, &changes); | XConfigureWindow(winPtr->display, winPtr->window, mask, &changes); |
2372 | } | } |
2373 | return TCL_OK; | return TCL_OK; |
2374 | } | } |
2375 | ||
2376 | /* | /* |
2377 | *---------------------------------------------------------------------- | *---------------------------------------------------------------------- |
2378 | * | * |
2379 | * Tk_MainWindow -- | * Tk_MainWindow -- |
2380 | * | * |
2381 | * Returns the main window for an application. | * Returns the main window for an application. |
2382 | * | * |
2383 | * Results: | * Results: |
2384 | * If interp has a Tk application associated with it, the main | * If interp has a Tk application associated with it, the main |
2385 | * window for the application is returned. Otherwise NULL is | * window for the application is returned. Otherwise NULL is |
2386 | * returned and an error message is left in the interp's result. | * returned and an error message is left in the interp's result. |
2387 | * | * |
2388 | * Side effects: | * Side effects: |
2389 | * None. | * None. |
2390 | * | * |
2391 | *---------------------------------------------------------------------- | *---------------------------------------------------------------------- |
2392 | */ | */ |
2393 | ||
2394 | Tk_Window | Tk_Window |
2395 | Tk_MainWindow(interp) | Tk_MainWindow(interp) |
2396 | Tcl_Interp *interp; /* Interpreter that embodies the | Tcl_Interp *interp; /* Interpreter that embodies the |
2397 | * application. Used for error | * application. Used for error |
2398 | * reporting also. */ | * reporting also. */ |
2399 | { | { |
2400 | TkMainInfo *mainPtr; | TkMainInfo *mainPtr; |
2401 | ThreadSpecificData *tsdPtr = (ThreadSpecificData *) | ThreadSpecificData *tsdPtr = (ThreadSpecificData *) |
2402 | Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); | Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); |
2403 | ||
2404 | for (mainPtr = tsdPtr->mainWindowList; mainPtr != NULL; | for (mainPtr = tsdPtr->mainWindowList; mainPtr != NULL; |
2405 | mainPtr = mainPtr->nextPtr) { | mainPtr = mainPtr->nextPtr) { |
2406 | if (mainPtr->interp == interp) { | if (mainPtr->interp == interp) { |
2407 | return (Tk_Window) mainPtr->winPtr; | return (Tk_Window) mainPtr->winPtr; |
2408 | } | } |
2409 | } | } |
2410 | Tcl_SetResult(interp, "this isn't a Tk application", TCL_STATIC); | Tcl_SetResult(interp, "this isn't a Tk application", TCL_STATIC); |
2411 | return NULL; | return NULL; |
2412 | } | } |
2413 | ||
2414 | /* | /* |
2415 | *---------------------------------------------------------------------- | *---------------------------------------------------------------------- |
2416 | * | * |
2417 | * Tk_StrictMotif -- | * Tk_StrictMotif -- |
2418 | * | * |
2419 | * Indicates whether strict Motif compliance has been specified | * Indicates whether strict Motif compliance has been specified |
2420 | * for the given window. | * for the given window. |
2421 | * | * |
2422 | * Results: | * Results: |
2423 | * The return value is 1 if strict Motif compliance has been | * The return value is 1 if strict Motif compliance has been |
2424 | * requested for tkwin's application by setting the tk_strictMotif | * requested for tkwin's application by setting the tk_strictMotif |
2425 | * variable in its interpreter to a true value. 0 is returned | * variable in its interpreter to a true value. 0 is returned |
2426 | * if tk_strictMotif has a false value. | * if tk_strictMotif has a false value. |
2427 | * | * |
2428 | * Side effects: | * Side effects: |
2429 | * None. | * None. |
2430 | * | * |
2431 | *---------------------------------------------------------------------- | *---------------------------------------------------------------------- |
2432 | */ | */ |
2433 | ||
2434 | int | int |
2435 | Tk_StrictMotif(tkwin) | Tk_StrictMotif(tkwin) |
2436 | Tk_Window tkwin; /* Window whose application is | Tk_Window tkwin; /* Window whose application is |
2437 | * to be checked. */ | * to be checked. */ |
2438 | { | { |
2439 | return ((TkWindow *) tkwin)->mainPtr->strictMotif; | return ((TkWindow *) tkwin)->mainPtr->strictMotif; |
2440 | } | } |
2441 | ||
2442 | /* | /* |
2443 | *-------------------------------------------------------------- | *-------------------------------------------------------------- |
2444 | * | * |
2445 | * OpenIM -- | * OpenIM -- |
2446 | * | * |
2447 | * Tries to open an X input method, associated with the | * Tries to open an X input method, associated with the |
2448 | * given display. Right now we can only deal with a bare-bones | * given display. Right now we can only deal with a bare-bones |
2449 | * input style: no preedit, and no status. | * input style: no preedit, and no status. |
2450 | * | * |
2451 | * Results: | * Results: |
2452 | * Stores the input method in dispPtr->inputMethod; if there isn't | * Stores the input method in dispPtr->inputMethod; if there isn't |
2453 | * a suitable input method, then NULL is stored in dispPtr->inputMethod. | * a suitable input method, then NULL is stored in dispPtr->inputMethod. |
2454 | * | * |
2455 | * Side effects: | * Side effects: |
2456 | * An input method gets opened. | * An input method gets opened. |
2457 | * | * |
2458 | *-------------------------------------------------------------- | *-------------------------------------------------------------- |
2459 | */ | */ |
2460 | ||
2461 | static void | static void |
2462 | OpenIM(dispPtr) | OpenIM(dispPtr) |
2463 | TkDisplay *dispPtr; /* Tk's structure for the display. */ | TkDisplay *dispPtr; /* Tk's structure for the display. */ |
2464 | { | { |
2465 | #ifndef TK_USE_INPUT_METHODS | #ifndef TK_USE_INPUT_METHODS |
2466 | return; | return; |
2467 | #else | #else |
2468 | unsigned short i; | unsigned short i; |
2469 | XIMStyles *stylePtr; | XIMStyles *stylePtr; |
2470 | ||
2471 | dispPtr->inputMethod = XOpenIM(dispPtr->display, NULL, NULL, NULL); | dispPtr->inputMethod = XOpenIM(dispPtr->display, NULL, NULL, NULL); |
2472 | if (dispPtr->inputMethod == NULL) { | if (dispPtr->inputMethod == NULL) { |
2473 | return; | return; |
2474 | } | } |
2475 | ||
2476 | if ((XGetIMValues(dispPtr->inputMethod, XNQueryInputStyle, &stylePtr, | if ((XGetIMValues(dispPtr->inputMethod, XNQueryInputStyle, &stylePtr, |
2477 | NULL) != NULL) || (stylePtr == NULL)) { | NULL) != NULL) || (stylePtr == NULL)) { |
2478 | goto error; | goto error; |
2479 | } | } |
2480 | for (i = 0; i < stylePtr->count_styles; i++) { | for (i = 0; i < stylePtr->count_styles; i++) { |
2481 | if (stylePtr->supported_styles[i] | if (stylePtr->supported_styles[i] |
2482 | == (XIMPreeditNothing|XIMStatusNothing)) { | == (XIMPreeditNothing|XIMStatusNothing)) { |
2483 | XFree(stylePtr); | XFree(stylePtr); |
2484 | return; | return; |
2485 | } | } |
2486 | } | } |
2487 | XFree(stylePtr); | XFree(stylePtr); |
2488 | ||
2489 | error: | error: |
2490 | ||
2491 | /* | /* |
2492 | * Should close the input method, but this causes core dumps on some | * Should close the input method, but this causes core dumps on some |
2493 | * systems (e.g. Solaris 2.3 as of 1/6/95). | * systems (e.g. Solaris 2.3 as of 1/6/95). |
2494 | * XCloseIM(dispPtr->inputMethod); | * XCloseIM(dispPtr->inputMethod); |
2495 | */ | */ |
2496 | dispPtr->inputMethod = NULL; | dispPtr->inputMethod = NULL; |
2497 | return; | return; |
2498 | #endif /* TK_USE_INPUT_METHODS */ | #endif /* TK_USE_INPUT_METHODS */ |
2499 | } | } |
2500 | ||
2501 | /* | /* |
2502 | *---------------------------------------------------------------------- | *---------------------------------------------------------------------- |
2503 | * | * |
2504 | * Tk_GetNumMainWindows -- | * Tk_GetNumMainWindows -- |
2505 | * | * |
2506 | * This procedure returns the number of main windows currently | * This procedure returns the number of main windows currently |
2507 | * open in this process. | * open in this process. |
2508 | * | * |
2509 | * Results: | * Results: |
2510 | * The number of main windows open in this process. | * The number of main windows open in this process. |
2511 | * | * |
2512 | * Side effects: | * Side effects: |
2513 | * None. | * None. |
2514 | * | * |
2515 | *---------------------------------------------------------------------- | *---------------------------------------------------------------------- |
2516 | */ | */ |
2517 | ||
2518 | int | int |
2519 | Tk_GetNumMainWindows() | Tk_GetNumMainWindows() |
2520 | { | { |
2521 | ThreadSpecificData *tsdPtr = (ThreadSpecificData *) | ThreadSpecificData *tsdPtr = (ThreadSpecificData *) |
2522 | Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); | Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); |
2523 | ||
2524 | return tsdPtr->numMainWindows; | return tsdPtr->numMainWindows; |
2525 | } | } |
2526 | ||
2527 | /* | /* |
2528 | *---------------------------------------------------------------------- | *---------------------------------------------------------------------- |
2529 | * | * |
2530 | * DeleteWindowsExitProc -- | * DeleteWindowsExitProc -- |
2531 | * | * |
2532 | * This procedure is invoked as an exit handler. It deletes all | * This procedure is invoked as an exit handler. It deletes all |
2533 | * of the main windows in the process. | * of the main windows in the process. |
2534 | * | * |
2535 | * Results: | * Results: |
2536 | * None. | * None. |
2537 | * | * |
2538 | * Side effects: | * Side effects: |
2539 | * None. | * None. |
2540 | * | * |
2541 | *---------------------------------------------------------------------- | *---------------------------------------------------------------------- |
2542 | */ | */ |
2543 | ||
2544 | static void | static void |
2545 | DeleteWindowsExitProc(clientData) | DeleteWindowsExitProc(clientData) |
2546 | ClientData clientData; /* Not used. */ | ClientData clientData; /* Not used. */ |
2547 | { | { |
2548 | TkDisplay *displayPtr, *nextPtr; | TkDisplay *displayPtr, *nextPtr; |
2549 | Tcl_Interp *interp; | Tcl_Interp *interp; |
2550 | ThreadSpecificData *tsdPtr = (ThreadSpecificData *) | ThreadSpecificData *tsdPtr = (ThreadSpecificData *) |
2551 | Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); | Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); |
2552 | ||
2553 | while (tsdPtr->mainWindowList != NULL) { | while (tsdPtr->mainWindowList != NULL) { |
2554 | /* | /* |
2555 | * We must protect the interpreter while deleting the window, | * We must protect the interpreter while deleting the window, |
2556 | * because of <Destroy> bindings which could destroy the interpreter | * because of <Destroy> bindings which could destroy the interpreter |
2557 | * while the window is being deleted. This would leave frames on | * while the window is being deleted. This would leave frames on |
2558 | * the call stack pointing at deleted memory, causing core dumps. | * the call stack pointing at deleted memory, causing core dumps. |
2559 | */ | */ |
2560 | ||
2561 | interp = tsdPtr->mainWindowList->winPtr->mainPtr->interp; | interp = tsdPtr->mainWindowList->winPtr->mainPtr->interp; |
2562 | Tcl_Preserve((ClientData) interp); | Tcl_Preserve((ClientData) interp); |
2563 | Tk_DestroyWindow((Tk_Window) tsdPtr->mainWindowList->winPtr); | Tk_DestroyWindow((Tk_Window) tsdPtr->mainWindowList->winPtr); |
2564 | Tcl_Release((ClientData) interp); | Tcl_Release((ClientData) interp); |
2565 | } | } |
2566 | ||
2567 | displayPtr = tsdPtr->displayList; | displayPtr = tsdPtr->displayList; |
2568 | tsdPtr->displayList = NULL; | tsdPtr->displayList = NULL; |
2569 | ||
2570 | /* | /* |
2571 | * Iterate destroying the displays until no more displays remain. | * Iterate destroying the displays until no more displays remain. |
2572 | * It is possible for displays to get recreated during exit by any | * It is possible for displays to get recreated during exit by any |
2573 | * code that calls GetScreen, so we must destroy these new displays | * code that calls GetScreen, so we must destroy these new displays |
2574 | * as well as the old ones. | * as well as the old ones. |
2575 | */ | */ |
2576 | ||
2577 | for (displayPtr = tsdPtr->displayList; | for (displayPtr = tsdPtr->displayList; |
2578 | displayPtr != NULL; | displayPtr != NULL; |
2579 | displayPtr = tsdPtr->displayList) { | displayPtr = tsdPtr->displayList) { |
2580 | ||
2581 | /* | /* |
2582 | * Now iterate over the current list of open displays, and first | * Now iterate over the current list of open displays, and first |
2583 | * set the global pointer to NULL so we will be able to notice if | * set the global pointer to NULL so we will be able to notice if |
2584 | * any new displays got created during deletion of the current set. | * any new displays got created during deletion of the current set. |
2585 | * We must also do this to ensure that Tk_IdToWindow does not find | * We must also do this to ensure that Tk_IdToWindow does not find |
2586 | * the old display as it is being destroyed, when it wants to see | * the old display as it is being destroyed, when it wants to see |
2587 | * if it needs to dispatch a message. | * if it needs to dispatch a message. |
2588 | */ | */ |
2589 | ||
2590 | for (tsdPtr->displayList = NULL; displayPtr != NULL; | for (tsdPtr->displayList = NULL; displayPtr != NULL; |
2591 | displayPtr = nextPtr) { | displayPtr = nextPtr) { |
2592 | nextPtr = displayPtr->nextPtr; | nextPtr = displayPtr->nextPtr; |
2593 | if (displayPtr->name != (char *) NULL) { | if (displayPtr->name != (char *) NULL) { |
2594 | ckfree(displayPtr->name); | ckfree(displayPtr->name); |
2595 | } | } |
2596 | Tcl_DeleteHashTable(&(displayPtr->winTable)); | Tcl_DeleteHashTable(&(displayPtr->winTable)); |
2597 | TkpCloseDisplay(displayPtr); | TkpCloseDisplay(displayPtr); |
2598 | } | } |
2599 | } | } |
2600 | ||
2601 | tsdPtr->numMainWindows = 0; | tsdPtr->numMainWindows = 0; |
2602 | tsdPtr->mainWindowList = NULL; | tsdPtr->mainWindowList = NULL; |
2603 | tsdPtr->initialized = 0; | tsdPtr->initialized = 0; |
2604 | } | } |
2605 | ||
2606 | /* | /* |
2607 | *---------------------------------------------------------------------- | *---------------------------------------------------------------------- |
2608 | * | * |