4 * This file provides basic window-manipulation procedures,
5 * which are equivalent to procedures in Xlib (and even
6 * invoke them) but also maintain the local Tk_Window
9 * Copyright 1989-1992 Regents of the University of California.
10 * Permission to use, copy, modify, and distribute this
11 * software and its documentation for any purpose and without
12 * fee is hereby granted, provided that the above copyright
13 * notice appear in all copies. The University of California
14 * makes no representations about the suitability of this
15 * software for any purpose. It is provided "as is" without
16 * express or implied warranty.
20 static char rcsid
[] = "$Header: /user6/ouster/wish/RCS/tkWindow.c,v 1.92 92/08/21 11:42:44 ouster Exp $ SPRITE (Berkeley)";
27 * Global absolute file name:
29 char *TK_Library
= TK_LIBRARY
;
32 * Count of open displays.
37 * Count of number of main windows currently open in this process.
40 int tk_NumMainWindows
;
43 * Added by dhopkins for OLPC Micropolis gtk.Socket integration.
46 Window tk_RootWindow
= 0;
49 * List of all displays currently in use.
52 TkDisplay
*tkDisplayList
= NULL
;
55 * Have statics in this module been initialized?
58 static int initialized
= 0;
61 * Context information used to map from X window id's to
62 * TkWindow structures (during event handling, for example):
65 XContext tkWindowContext
;
68 * The variables below hold several uid's that are used in many places
72 Tk_Uid tkDisabledUid
= NULL
;
73 Tk_Uid tkActiveUid
= NULL
;
74 Tk_Uid tkNormalUid
= NULL
;
77 * Default values for "changes" and "atts" fields of TkWindows. Note
78 * that Tk always requests all events for all windows, except StructureNotify
79 * events on internal windows: these events are generated internally.
82 static XWindowChanges defChanges
= {
83 0, 0, 1, 1, 0, 0, Above
85 #define ALL_EVENTS_MASK \
86 KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask| \
87 EnterWindowMask|LeaveWindowMask|PointerMotionMask|ExposureMask| \
88 VisibilityChangeMask|SubstructureNotifyMask| \
89 FocusChangeMask|PropertyChangeMask|ColormapChangeMask
90 static XSetWindowAttributes defAtts
= {
91 None
, /* background_pixmap */
92 0, /* background_pixel */
93 CopyFromParent
, /* border_pixmap */
95 ForgetGravity
, /* bit_gravity */
96 NorthWestGravity
, /* win_gravity */
97 NotUseful
, /* backing_store */
98 ~0, /* backing_planes */
99 0, /* backing_pixel */
100 False
, /* save_under */
101 ALL_EVENTS_MASK
, /* event_mask */
102 0, /* do_not_propagate_mask */
103 False
, /* override_redirect */
104 CopyFromParent
, /* colormap */
109 * The following structure defines all of the commands supported by
110 * Tk, and the C procedures that execute them.
114 char *name
; /* Name of command. */
115 int (*cmdProc
) _ANSI_ARGS_((ClientData clientData
, Tcl_Interp
*interp
,
116 int argc
, char **argv
));
117 /* Command procedure. */
122 * Commands that are part of the intrinsics:
125 {"after", Tk_AfterCmd
},
126 {"bind", Tk_BindCmd
},
127 {"destroy", Tk_DestroyCmd
},
128 {"focus", Tk_FocusCmd
},
129 {"grab", Tk_GrabCmd
},
130 {"option", Tk_OptionCmd
},
131 {"pack", Tk_PackCmd
},
132 {"place", Tk_PlaceCmd
},
133 {"selection", Tk_SelectionCmd
},
134 {"tkwait", Tk_TkwaitCmd
},
135 {"update", Tk_UpdateCmd
},
136 {"winfo", Tk_WinfoCmd
},
137 {"winfo-setlegacy", Tk_WinfoCmdSetLegacy
},
139 {"accept", Tcp_AcceptCmd
},
140 {"shutdown", Tcp_ShutdownCmd
},
141 {"connect", Tcp_ConnectCmd
},
142 {"filehandler", Tcp_FileHandlerCmd
},
145 * Widget-creation commands.
147 {"button", Tk_ButtonCmd
},
148 {"canvas", Tk_CanvasCmd
},
149 {"checkbutton", Tk_ButtonCmd
},
150 {"entry", Tk_EntryCmd
},
151 {"frame", Tk_FrameCmd
},
152 {"label", Tk_ButtonCmd
},
153 {"listbox", Tk_ListboxCmd
},
154 {"menu", Tk_MenuCmd
},
155 {"menubutton", Tk_MenubuttonCmd
},
156 {"message", Tk_MessageCmd
},
157 {"radiobutton", Tk_ButtonCmd
},
158 {"scale", Tk_ScaleCmd
},
159 {"scrollbar", Tk_ScrollbarCmd
},
160 {"text", Tk_TextCmd
},
161 {"toplevel", Tk_FrameCmd
},
162 {(char *) NULL
, (int (*)(int *, Tcl_Interp
*, int, char **)) NULL
}
166 * Forward declarations to procedures defined later in this file:
169 static Tk_Window CreateTopLevelWindow
_ANSI_ARGS_((Tcl_Interp
*interp
,
170 Tk_Window parent
, char *name
, char *screenName
));
171 static void DoConfigureNotify
_ANSI_ARGS_((TkWindow
*winPtr
));
172 static TkDisplay
* GetScreen
_ANSI_ARGS_((Tcl_Interp
*interp
,
173 char *screenName
, int *screenPtr
));
174 static int NameWindow
_ANSI_ARGS_((Tcl_Interp
*interp
,
175 TkWindow
*winPtr
, TkWindow
*parentPtr
,
177 static TkWindow
* NewWindow
_ANSI_ARGS_((TkDisplay
*dispPtr
,
181 *----------------------------------------------------------------------
183 * CreateTopLevelWindow --
185 * Make a new window that will be at top-level (its parent will
186 * be the root window of a screen).
189 * The return value is a token for the new window, or NULL if
190 * an error prevented the new window from being created. If
191 * NULL is returned, an error message will be left in
195 * A new window structure is allocated locally. An X
196 * window is NOT initially created, but will be created
197 * the first time the window is mapped.
199 *----------------------------------------------------------------------
203 CreateTopLevelWindow (
204 Tcl_Interp
*interp
, /* Interpreter to use for error reporting. */
205 Tk_Window parent
, /* Token for logical parent of new window
206 * (used for naming, options, etc.). May
208 char *name
, /* Name for new window; if parent is
209 * non-NULL, must be unique among parent's
211 char *screenName
/* Name of screen on which to create
212 * window. NULL means use DISPLAY environment
213 * variable to determine. Empty string means
214 * use parent's screen, or DISPLAY if no
218 register TkWindow
*winPtr
;
219 register TkDisplay
*dispPtr
;
224 tkWindowContext
= XUniqueContext();
225 tkActiveUid
= Tk_GetUid("active");
226 tkDisabledUid
= Tk_GetUid("disabled");
227 tkNormalUid
= Tk_GetUid("normal");
230 if ((parent
!= NULL
) && (screenName
!= NULL
) && (screenName
[0] == '\0')) {
231 dispPtr
= ((TkWindow
*) parent
)->dispPtr
;
232 screenId
= Tk_ScreenNumber(parent
);
234 dispPtr
= GetScreen(interp
, screenName
, &screenId
);
235 if (dispPtr
== NULL
) {
236 return (Tk_Window
) NULL
;
240 winPtr
= NewWindow(dispPtr
, screenId
);
243 * Internal windows don't normally ask for StructureNotify events,
244 * since we can generate them internally. However, for top-level
245 * windows we need to as for the events because the window could
246 * be manipulated externally.
249 winPtr
->atts
.event_mask
|= StructureNotifyMask
;
252 * (Need to set the TK_TOP_LEVEL flag immediately here; otherwise
253 * Tk_DestroyWindow will core dump if it is called before the flag
257 winPtr
->flags
|= TK_TOP_LEVEL
;
258 if (parent
!= NULL
) {
259 if (NameWindow(interp
, winPtr
, (TkWindow
*) parent
, name
) != TCL_OK
) {
260 Tk_DestroyWindow((Tk_Window
) winPtr
);
261 return (Tk_Window
) NULL
;
264 TkWmNewWindow(winPtr
);
265 return (Tk_Window
) winPtr
;
269 *----------------------------------------------------------------------
273 * Given a string name for a display-plus-screen, find the
274 * TkDisplay structure for the display and return the screen
278 * The return value is a pointer to information about the display,
279 * or NULL if the display couldn't be opened. In this case, an
280 * error message is left in interp->result. The location at
281 * *screenPtr is overwritten with the screen number parsed from
285 * A new connection is opened to the display if there is no
286 * connection already. A new TkDisplay data structure is also
287 * setup, if necessary.
289 *----------------------------------------------------------------------
294 Tcl_Interp
*interp
, /* Place to leave error message. */
295 char *screenName
, /* Name for screen. NULL or empty means
296 * use DISPLAY envariable. */
297 int *screenPtr
/* Where to store screen number. */
300 register TkDisplay
*dispPtr
;
302 int length
, screenId
;
305 * Separate the screen number from the rest of the display
306 * name. ScreenName is assumed to have the syntax
307 * <display>.<screen> with the dot and the screen being
311 if ((screenName
== NULL
) || (screenName
[0] == '\0')) {
312 screenName
= getenv("DISPLAY");
313 if (screenName
== NULL
) {
315 "no display name and no $DISPLAY environment variable";
316 return (TkDisplay
*) NULL
;
319 length
= strlen(screenName
);
321 p
= screenName
+length
-1;
322 while (isdigit(*p
) && (p
!= screenName
)) {
325 if ((*p
== '.') && (p
[1] != '\0')) {
326 length
= p
- screenName
;
327 screenId
= strtoul(p
+1, (char **) NULL
, 10);
331 * See if we already have a connection to this display. If not,
332 * then open a new connection.
335 for (dispPtr
= tkDisplayList
; ; dispPtr
= dispPtr
->nextPtr
) {
336 if (dispPtr
== NULL
) {
337 Display
*display
= NULL
;
339 display
= XOpenDisplay(screenName
);
341 if (display
== NULL
) {
342 Tcl_AppendResult(interp
, "couldn't connect to display \"",
343 screenName
, "\"", (char *) NULL
);
344 return (TkDisplay
*) NULL
;
346 if (getenv("XSYNCHRONIZE") != NULL
) {
347 XSynchronize(display
, 1);
350 dispPtr
= (TkDisplay
*) ckalloc(sizeof(TkDisplay
));
351 dispPtr
->display
= display
;
352 dispPtr
->nextPtr
= tkDisplayList
;
353 dispPtr
->name
= (char *) ckalloc((unsigned) (length
+1));
354 dispPtr
->lastEventTime
= CurrentTime
;
355 strncpy(dispPtr
->name
, screenName
, length
);
356 dispPtr
->mouseMainPtr
= NULL
;
357 dispPtr
->name
[length
] = '\0';
358 dispPtr
->symsPerCode
= 0;
359 dispPtr
->errorPtr
= NULL
;
360 dispPtr
->deleteCount
= 0;
361 dispPtr
->commWindow
= NULL
;
362 dispPtr
->selectionOwner
= NULL
;
363 dispPtr
->selectionSerial
= 0;
364 dispPtr
->multipleAtom
= None
;
365 dispPtr
->atomInit
= 0;
366 dispPtr
->modeModMask
= 0;
367 dispPtr
->metaModMask
= 0;
368 dispPtr
->altModMask
= 0;
369 dispPtr
->cursorFont
= None
;
370 dispPtr
->grabWinPtr
= NULL
;
371 dispPtr
->ungrabWinPtr
= NULL
;
372 dispPtr
->buttonWinPtr
= NULL
;
373 dispPtr
->pointerWinPtr
= NULL
;
374 dispPtr
->serverWinPtr
= NULL
;
375 dispPtr
->grabFlags
= 0;
376 dispPtr
->focusPtr
= NULL
;
377 tkDisplayList
= dispPtr
;
378 Tk_CreateFileHandler(ConnectionNumber(display
),
379 TK_READABLE
, (void (*)(int *, int)) NULL
,
380 (ClientData
) display
);
383 if ((strncmp(dispPtr
->name
, screenName
, length
) == 0)
384 && (dispPtr
->name
[length
] == '\0')) {
388 if (screenId
>= ScreenCount(dispPtr
->display
)) {
389 sprintf(interp
->result
, "bad screen number \"%d\"", screenId
);
390 return (TkDisplay
*) NULL
;
392 *screenPtr
= screenId
;
397 *--------------------------------------------------------------
401 * This procedure creates and initializes a TkWindow structure.
404 * The return value is a pointer to the new window.
407 * A new window structure is allocated and all its fields are
410 *--------------------------------------------------------------
415 TkDisplay
*dispPtr
, /* Display associated with new window. */
416 int screenNum
/* Index of screen for new window. */
419 register TkWindow
*winPtr
;
421 winPtr
= (TkWindow
*) ckalloc(sizeof(TkWindow
));
422 winPtr
->display
= dispPtr
->display
;
423 winPtr
->dispPtr
= dispPtr
;
424 winPtr
->screenNum
= screenNum
;
425 winPtr
->window
= None
;
426 winPtr
->childList
= NULL
;
427 winPtr
->parentPtr
= NULL
;
428 winPtr
->nextPtr
= NULL
;
429 winPtr
->mainPtr
= NULL
;
430 winPtr
->pathName
= NULL
;
431 winPtr
->nameUid
= NULL
;
432 winPtr
->classUid
= NULL
;
433 winPtr
->changes
= defChanges
;
434 winPtr
->dirtyChanges
= CWX
|CWY
|CWWidth
|CWHeight
|CWBorderWidth
;
435 winPtr
->atts
= defAtts
;
436 winPtr
->dirtyAtts
= CWEventMask
;
438 winPtr
->handlerList
= NULL
;
439 winPtr
->focusProc
= NULL
;
440 winPtr
->focusData
= NULL
;
441 winPtr
->optionLevel
= -1;
442 winPtr
->selHandlerList
= NULL
;
443 winPtr
->selClearProc
= NULL
;
444 winPtr
->selClearData
= NULL
;
445 winPtr
->geomProc
= NULL
;
446 winPtr
->geomData
= NULL
;
447 winPtr
->reqWidth
= winPtr
->reqHeight
= 0;
448 winPtr
->internalBorderWidth
= 0;
449 winPtr
->wmInfoPtr
= NULL
;
454 *----------------------------------------------------------------------
458 * This procedure is invoked to give a window a name and insert
459 * the window into the hierarchy associated with a particular
463 * A standard Tcl return value.
468 *----------------------------------------------------------------------
473 Tcl_Interp
*interp
, /* Interpreter to use for error reporting. */
474 register TkWindow
*winPtr
, /* Window that is to be named and inserted. */
475 TkWindow
*parentPtr
, /* Pointer to logical parent for winPtr
476 * (used for naming, options, etc.). */
477 char *name
/* Name for winPtr; must be unique among
478 * parentPtr's children. */
481 #define FIXED_SIZE 200
482 char staticSpace
[FIXED_SIZE
];
486 int length1
, length2
;
489 * Setup all the stuff except name right away, then do the name stuff
490 * last. This is so that if the name stuff fails, everything else
491 * will be properly initialized (needed to destroy the window cleanly
492 * after the naming failure).
494 winPtr
->parentPtr
= parentPtr
;
495 winPtr
->nextPtr
= parentPtr
->childList
;
496 parentPtr
->childList
= winPtr
;
497 winPtr
->mainPtr
= parentPtr
->mainPtr
;
498 winPtr
->nameUid
= Tk_GetUid(name
);
501 * To permit names of arbitrary length, must be prepared to malloc
502 * a buffer to hold the new path name. To run fast in the common
503 * case where names are short, use a fixed-size buffer on the
507 length1
= strlen(parentPtr
->pathName
);
508 length2
= strlen(name
);
509 if ((length1
+length2
+2) <= FIXED_SIZE
) {
510 pathName
= staticSpace
;
512 pathName
= (char *) ckalloc((unsigned) (length1
+length2
+2));
516 strcpy(pathName
+1, name
);
518 strcpy(pathName
, parentPtr
->pathName
);
519 pathName
[length1
] = '.';
520 strcpy(pathName
+length1
+1, name
);
522 hPtr
= Tcl_CreateHashEntry(&parentPtr
->mainPtr
->nameTable
, pathName
, &new);
523 if (pathName
!= staticSpace
) {
527 Tcl_AppendResult(interp
, "window name \"", name
,
528 "\" already exists in parent", (char *) NULL
);
531 Tcl_SetHashValue(hPtr
, winPtr
);
532 winPtr
->pathName
= Tcl_GetHashKey(&parentPtr
->mainPtr
->nameTable
, hPtr
);
537 *----------------------------------------------------------------------
539 * Tk_CreateMainWindow --
541 * Make a new main window. A main window is a special kind of
542 * top-level window used as the outermost window in an
546 * The return value is a token for the new window, or NULL if
547 * an error prevented the new window from being created. If
548 * NULL is returned, an error message will be left in
552 * A new window structure is allocated locally; "interp" is
553 * associated with the window and registered for "send" commands
554 * under "baseName". BaseName may be extended with an instance
555 * number in the form "#2" if necessary to make it globally
556 * unique. Tk-related commands are bound into interp. An X
557 * window is NOT initially created, but will be created the
558 * first time the window is mapped.
560 *----------------------------------------------------------------------
564 Tk_CreateMainWindow (
565 Tcl_Interp
*interp
, /* Interpreter to use for error reporting. */
566 char *screenName
, /* Name of screen on which to create
567 * window. Empty or NULL string means
568 * use DISPLAY environment variable. */
569 char *baseName
/* Base name for application; usually of the
570 * form "prog instance". */
576 register TkMainInfo
*mainPtr
;
577 register TkWindow
*winPtr
;
578 register TkCmd
*cmdPtr
;
581 * Create the basic TkWindow structure.
584 tkwin
= CreateTopLevelWindow(interp
, (Tk_Window
) NULL
, baseName
,
591 * Create the TkMainInfo structure for this application, and set
592 * up name-related information for the new window.
595 winPtr
= (TkWindow
*) tkwin
;
596 mainPtr
= (TkMainInfo
*) ckalloc(sizeof(TkMainInfo
));
597 mainPtr
->winPtr
= winPtr
;
598 mainPtr
->interp
= interp
;
599 Tcl_InitHashTable(&mainPtr
->nameTable
, TCL_STRING_KEYS
);
600 mainPtr
->bindingTable
= Tk_CreateBindingTable(interp
);
602 /* mainPtr->focusPtr = NULL; */
603 mainPtr
->optionRootPtr
= NULL
;
604 winPtr
->mainPtr
= mainPtr
;
605 hPtr
= Tcl_CreateHashEntry(&mainPtr
->nameTable
, ".", &dummy
);
606 Tcl_SetHashValue(hPtr
, winPtr
);
607 winPtr
->pathName
= Tcl_GetHashKey(&mainPtr
->nameTable
, hPtr
);
610 * Register the interpreter for "send" purposes. If baseName isn't
611 * already unique, find a unique suffix to add to it to make it
612 * unique. Change the window's name to contain the suffix.
615 result
= Tk_RegisterInterp(interp
, baseName
, tkwin
);
616 if (result
== TCL_OK
) {
617 winPtr
->nameUid
= Tk_GetUid(baseName
);
623 sprintf(newName
, "%.100s #%d", baseName
, i
);
624 Tcl_SetResult(interp
, (char *) NULL
, TCL_STATIC
);
625 result
= Tk_RegisterInterp(interp
, newName
, tkwin
);
626 if (result
== TCL_OK
) {
630 Tcl_SetResult(interp
,
631 "couldn't generate unique name to register application",
633 Tk_DestroyWindow(tkwin
);
636 winPtr
->nameUid
= Tk_GetUid(newName
);
640 * Bind in Tk's commands.
643 for (cmdPtr
= commands
; cmdPtr
->name
!= NULL
; cmdPtr
++) {
644 Tcl_CreateCommand(interp
, cmdPtr
->name
, cmdPtr
->cmdProc
,
645 (ClientData
) tkwin
, (void (*)(int *)) NULL
);
649 * Set variables for the intepreter.
652 Tcl_SetVar(interp
, "tk_library", TK_Library
, TCL_GLOBAL_ONLY
);
653 Tcl_SetVar(interp
, "tk_version", TK_VERSION
, TCL_GLOBAL_ONLY
);
654 Tcl_SetVar(interp
, "tkVersion", TK_VERSION
, TCL_GLOBAL_ONLY
);
661 *--------------------------------------------------------------
665 * Create a new internal or top-level window as a child of an
669 * The return value is a token for the new window. This
670 * is not the same as X's token for the window. If an error
671 * occurred in creating the window (e.g. no such display or
672 * screen), then an error message is left in interp->result and
676 * A new window structure is allocated locally. An X
677 * window is not initially created, but will be created
678 * the first time the window is mapped.
680 *--------------------------------------------------------------
685 Tcl_Interp
*interp
, /* Interpreter to use for error reporting.
686 * Interp->result is assumed to be
687 * initialized by the caller. */
688 Tk_Window parent
, /* Token for parent of new window. */
689 char *name
, /* Name for new window. Must be unique
690 * among parent's children. */
691 char *screenName
/* If NULL, new window will be internal on
692 * same screen as its parent. If non-NULL,
693 * gives name of screen on which to create
694 * new window; window will be a top-level
698 TkWindow
*parentPtr
= (TkWindow
*) parent
;
701 if (screenName
== NULL
) {
702 winPtr
= NewWindow(parentPtr
->dispPtr
, parentPtr
->screenNum
);
703 if (NameWindow(interp
, winPtr
, parentPtr
, name
) != TCL_OK
) {
704 Tk_DestroyWindow((Tk_Window
) winPtr
);
707 return (Tk_Window
) winPtr
;
711 * This is a fix for dvx XOpenDisplay... display name conformalization
717 strcpy(dsp
, screenName
);
719 if (len
&& (dsp
[len
-1] == '.'))
722 return CreateTopLevelWindow(interp
, parent
, name
, dsp
);
727 *----------------------------------------------------------------------
729 * Tk_CreateWindowFromPath --
731 * This procedure is similar to Tk_CreateInternalWindow except
732 * that it uses a path name to create the window, rather than
733 * a parent and a child name.
736 * The return value is a token for the new window. This
737 * is not the same as X's token for the window. If an error
738 * occurred in creating the window (e.g. no such display or
739 * screen), then an error message is left in interp->result and
743 * A new window structure is allocated locally. An X
744 * window is not initially created, but will be created
745 * the first time the window is mapped.
747 *----------------------------------------------------------------------
751 Tk_CreateWindowFromPath (
752 Tcl_Interp
*interp
, /* Interpreter to use for error reporting.
753 * Interp->result is assumed to be
754 * initialized by the caller. */
755 Tk_Window tkwin
, /* Token for any window in application
756 * that is to contain new window. */
757 char *pathName
, /* Path name for new window within the
758 * application of tkwin. The parent of
759 * this window must already exist, but
760 * the window itself must not exist. */
761 char *screenName
/* If NULL, new window will be on same
762 * screen as its parent. If non-NULL,
763 * gives name of screen on which to create
764 * new window; window will be a top-level
768 #define FIXED_SPACE 5
769 char fixedSpace
[FIXED_SPACE
+1];
775 * Strip the parent's name out of pathName (it's everything up
776 * to the last dot). There are two tricky parts: (a) must
777 * copy the parent's name somewhere else to avoid modifying
778 * the pathName string (for large names, space for the copy
779 * will have to be malloc'ed); (b) must special-case the
780 * situation where the parent is ".".
783 p
= strrchr(pathName
, '.');
785 Tcl_AppendResult(interp
, "bad window path name \"", pathName
,
786 "\"", (char *) NULL
);
789 numChars
= p
-pathName
;
790 if (numChars
> FIXED_SPACE
) {
791 p
= (char *) ckalloc((unsigned) (numChars
+1));
799 strncpy(p
, pathName
, numChars
);
804 * Find the parent window.
807 parent
= Tk_NameToWindow(interp
, p
, tkwin
);
808 if (p
!= fixedSpace
) {
811 if (parent
== NULL
) {
819 if (screenName
== NULL
) {
820 TkWindow
*parentPtr
= (TkWindow
*) parent
;
823 winPtr
= NewWindow(parentPtr
->dispPtr
, parentPtr
->screenNum
);
824 if (NameWindow(interp
, winPtr
, parentPtr
, pathName
+numChars
+1)
826 Tk_DestroyWindow((Tk_Window
) winPtr
);
829 return (Tk_Window
) winPtr
;
832 return CreateTopLevelWindow(interp
, parent
, pathName
+numChars
+1,
838 *--------------------------------------------------------------
840 * Tk_DestroyWindow --
842 * Destroy an existing window. After this call, the caller
843 * should never again use the token.
849 * The window is deleted, along with all of its children.
850 * Relevant callback procedures are invoked.
852 *--------------------------------------------------------------
857 Tk_Window tkwin
/* Window to destroy. */
860 register TkWindow
*winPtr
= (TkWindow
*) tkwin
;
864 * Recursively destroy children. The TK_RECURSIVE_DESTROY
865 * flags means that the child's window needn't be explicitly
866 * destroyed (the destroy of the parent already did it), nor
867 * does it need to be removed from its parent's child list,
868 * since the parent is being destroyed too.
871 while (winPtr
->childList
!= NULL
) {
872 winPtr
->childList
->flags
|= TK_RECURSIVE_DESTROY
;
873 Tk_DestroyWindow((Tk_Window
) winPtr
->childList
);
877 * Generate a DestroyNotify event. In order for the DestroyNotify
878 * event to be processed correctly, need to make sure the window
879 * exists. This is a bit of a kludge, and may be unnecessarily
880 * expensive, but without it no event handlers will get called for
881 * windows that don't exist yet.
884 if (winPtr
->window
== None
) {
885 Tk_MakeWindowExist(tkwin
);
887 winPtr
->flags
|= TK_ALREADY_DEAD
;
888 event
.type
= DestroyNotify
;
889 event
.xdestroywindow
.serial
=
890 LastKnownRequestProcessed(winPtr
->display
);
891 event
.xdestroywindow
.send_event
= False
;
892 event
.xdestroywindow
.display
= winPtr
->display
;
893 event
.xdestroywindow
.event
= winPtr
->window
;
894 event
.xdestroywindow
.window
= winPtr
->window
;
895 Tk_HandleEvent(&event
);
898 * Cleanup the data structures associated with this window.
899 * No need to destroy windows during recursive destroys, since
900 * that will happen automatically when the parent window is
901 * destroyed (not true for top-level windows: must destroy
905 if (winPtr
->window
!= None
) {
906 if (!(winPtr
->flags
& TK_RECURSIVE_DESTROY
)
907 || (winPtr
->flags
& TK_TOP_LEVEL
)) {
908 XDestroyWindow(winPtr
->display
, winPtr
->window
);
910 XDeleteContext(winPtr
->display
, winPtr
->window
, tkWindowContext
);
911 winPtr
->window
= None
;
913 if (winPtr
->parentPtr
!= NULL
) {
914 if (winPtr
->parentPtr
->childList
== winPtr
) {
915 winPtr
->parentPtr
->childList
= winPtr
->nextPtr
;
917 register TkWindow
*winPtr2
;
919 for (winPtr2
= winPtr
->parentPtr
->childList
; ;
920 winPtr2
= winPtr2
->nextPtr
) {
921 if (winPtr2
== NULL
) {
922 panic("Tk_DestroyWindow couldn't find child in parent (deleted twice?)");
925 if (winPtr2
->nextPtr
== winPtr
) {
926 winPtr2
->nextPtr
= winPtr
->nextPtr
;
932 TkEventDeadWindow(winPtr
);
933 TkOptionDeadWindow(winPtr
);
934 TkSelDeadWindow(winPtr
);
935 if (winPtr
->flags
& TK_TOP_LEVEL
) {
936 TkWmDeadWindow(winPtr
);
938 TkGrabDeadWindow(winPtr
);
939 if (winPtr
->mainPtr
!= NULL
) {
940 Tk_DeleteAllBindings(winPtr
->mainPtr
->bindingTable
,
941 (ClientData
) winPtr
->pathName
);
942 if (winPtr
->pathName
!= NULL
) {
943 Tcl_DeleteHashEntry(Tcl_FindHashEntry(&winPtr
->mainPtr
->nameTable
,
946 if (winPtr
->mainPtr
->winPtr
== winPtr
) {
947 register TkCmd
*cmdPtr
;
950 * Deleting a main window. Delete the TkMainInfo structure too
951 * and replace all of Tk's commands with dummy commands that
952 * return errors. Also delete the "send" command to unregister
956 for (cmdPtr
= commands
; cmdPtr
->name
!= NULL
; cmdPtr
++) {
957 Tcl_CreateCommand(winPtr
->mainPtr
->interp
, cmdPtr
->name
,
958 TkDeadAppCmd
, (ClientData
) NULL
, (void (*)(int *)) NULL
);
960 Tcl_CreateCommand(winPtr
->mainPtr
->interp
, "send",
961 TkDeadAppCmd
, (ClientData
) NULL
, (void (*)(int *)) NULL
);
962 Tcl_DeleteHashTable(&winPtr
->mainPtr
->nameTable
);
963 Tk_DeleteBindingTable(winPtr
->mainPtr
->bindingTable
);
964 ckfree((char *) winPtr
->mainPtr
);
968 ckfree((char *) winPtr
);
972 *--------------------------------------------------------------
976 * Map a window within its parent. This may require the
977 * window and/or its parents to actually be created.
983 * The given window will be mapped. Windows may also
986 *--------------------------------------------------------------
991 Tk_Window tkwin
/* Token for window to map. */
994 register TkWindow
*winPtr
= (TkWindow
*) tkwin
;
996 if (winPtr
->flags
& TK_MAPPED
) {
999 if (winPtr
->window
== None
) {
1000 Tk_MakeWindowExist(tkwin
);
1002 if (winPtr
->flags
& TK_TOP_LEVEL
) {
1003 if (!TkWmMapWindow(winPtr
)) {
1008 * Don't set the mapped flag for top-level windows: TkWmMapWindow
1009 * does it if appropriate (e.g. if the window is going to be non-
1013 winPtr
->flags
|= TK_MAPPED
;
1015 XMapWindow(winPtr
->display
, winPtr
->window
);
1016 if (!(winPtr
->flags
& TK_TOP_LEVEL
)) {
1019 event
.type
= MapNotify
;
1020 event
.xmap
.serial
= LastKnownRequestProcessed(winPtr
->display
);
1021 event
.xmap
.send_event
= False
;
1022 event
.xmap
.display
= winPtr
->display
;
1023 event
.xmap
.event
= winPtr
->window
;
1024 event
.xmap
.window
= winPtr
->window
;
1025 event
.xmap
.override_redirect
= winPtr
->atts
.override_redirect
;
1026 Tk_HandleEvent(&event
);
1031 *--------------------------------------------------------------
1033 * Tk_MakeWindowExist --
1035 * Ensure that a particular window actually exists. This
1036 * procedure shouldn't normally need to be invoked from
1037 * outside the Tk package, but may be needed if someone
1038 * wants to manipulate a window before mapping it.
1044 * When the procedure returns, the X window associated with
1045 * tkwin is guaranteed to exist. This may require the
1046 * window's ancestors to be created also.
1048 *--------------------------------------------------------------
1052 Tk_MakeWindowExist (
1053 Tk_Window tkwin
/* Token for window. */
1056 register TkWindow
*winPtr
= (TkWindow
*) tkwin
;
1059 if (winPtr
->window
!= None
) {
1063 if (winPtr
->flags
& TK_TOP_LEVEL
) {
1065 * workaround by dhopkins for OLPC Micropolis gtk.Socket integration.
1068 if (tk_RootWindow
) {
1073 XRootWindow(winPtr
->display
, winPtr
->screenNum
);
1077 if (winPtr
->parentPtr
->window
== None
) {
1078 Tk_MakeWindowExist((Tk_Window
) winPtr
->parentPtr
);
1080 parent
= winPtr
->parentPtr
->window
;
1083 /* workaround to support non-default colormaps */
1085 winPtr
->window
= XCreateWindow(winPtr
->display
, parent
,
1086 winPtr
->changes
.x
, winPtr
->changes
.y
,
1087 winPtr
->changes
.width
, winPtr
->changes
.height
,
1088 winPtr
->changes
.border_width
, CopyFromParent
,
1089 InputOutput
, CopyFromParent
, winPtr
->dirtyAtts
,
1092 { Screen
*scr
= ScreenOfDisplay(winPtr
->display
, winPtr
->screenNum
);
1094 winPtr
->dirtyAtts
|= CWColormap
| CWBorderPixmap
;
1095 winPtr
->atts
.colormap
= Tk_DefaultColormap(scr
);
1096 winPtr
->atts
.border_pixmap
= Tk_DefaultPixmap(scr
);
1098 winPtr
->window
= XCreateWindow(winPtr
->display
, parent
,
1099 winPtr
->changes
.x
, winPtr
->changes
.y
,
1100 winPtr
->changes
.width
, winPtr
->changes
.height
,
1101 winPtr
->changes
.border_width
,
1102 Tk_DefaultDepth(scr
),
1104 Tk_DefaultVisual(scr
),
1105 winPtr
->dirtyAtts
, &winPtr
->atts
);
1109 XSaveContext(winPtr
->display
, winPtr
->window
, tkWindowContext
,
1111 winPtr
->dirtyAtts
= 0;
1112 winPtr
->dirtyChanges
&= ~(CWX
|CWY
|CWWidth
|CWHeight
|CWBorderWidth
);
1113 if (winPtr
->dirtyChanges
!= 0) {
1114 XConfigureWindow(winPtr
->display
, winPtr
->window
,
1115 winPtr
->dirtyChanges
, &winPtr
->changes
);
1116 winPtr
->dirtyChanges
= 0;
1120 * Issue a ConfigureNotify event if there were deferred configuration
1124 if (winPtr
->flags
& TK_NEED_CONFIG_NOTIFY
) {
1125 winPtr
->flags
&= ~TK_NEED_CONFIG_NOTIFY
;
1126 DoConfigureNotify(winPtr
);
1131 *--------------------------------------------------------------
1133 * Tk_UnmapWindow, etc. --
1135 * There are several procedures under here, each of which
1136 * mirrors an existing X procedure. In addition to performing
1137 * the functions of the corresponding procedure, each
1138 * procedure also updates the local window structure and
1139 * synthesizes an X event (if the window's structure is being
1140 * managed internally).
1143 * See the manual entries.
1146 * See the manual entries.
1148 *--------------------------------------------------------------
1153 Tk_Window tkwin
/* Token for window to unmap. */
1156 register TkWindow
*winPtr
= (TkWindow
*) tkwin
;
1158 if (!(winPtr
->flags
& TK_MAPPED
)) {
1161 winPtr
->flags
&= ~TK_MAPPED
;
1162 XUnmapWindow(winPtr
->display
, winPtr
->window
);
1163 if (!(winPtr
->flags
& TK_TOP_LEVEL
)) {
1166 event
.type
= UnmapNotify
;
1167 event
.xunmap
.serial
= LastKnownRequestProcessed(winPtr
->display
);
1168 event
.xunmap
.send_event
= False
;
1169 event
.xunmap
.display
= winPtr
->display
;
1170 event
.xunmap
.event
= winPtr
->window
;
1171 event
.xunmap
.window
= winPtr
->window
;
1172 event
.xunmap
.from_configure
= False
;
1173 Tk_HandleEvent(&event
);
1178 Tk_ConfigureWindow (
1179 Tk_Window tkwin
, /* Window to re-configure. */
1180 unsigned int valueMask
, /* Mask indicating which parts of
1181 * *valuePtr are to be used. */
1182 XWindowChanges
*valuePtr
/* New values. */
1185 register TkWindow
*winPtr
= (TkWindow
*) tkwin
;
1187 if ((winPtr
->window
== None
) || !(winPtr
->flags
& TK_TOP_LEVEL
)) {
1188 if (valueMask
& CWX
) {
1189 winPtr
->changes
.x
= valuePtr
->x
;
1191 if (valueMask
& CWY
) {
1192 winPtr
->changes
.y
= valuePtr
->y
;
1194 if (valueMask
& CWWidth
) {
1195 winPtr
->changes
.width
= valuePtr
->width
;
1197 if (valueMask
& CWHeight
) {
1198 winPtr
->changes
.height
= valuePtr
->height
;
1200 if (valueMask
& CWBorderWidth
) {
1201 winPtr
->changes
.border_width
= valuePtr
->border_width
;
1203 if (valueMask
& CWSibling
) {
1204 winPtr
->changes
.sibling
= valuePtr
->sibling
;
1206 if (valueMask
& CWStackMode
) {
1207 winPtr
->changes
.stack_mode
= valuePtr
->stack_mode
;
1211 if (winPtr
->window
!= None
) {
1212 XConfigureWindow(winPtr
->display
, winPtr
->window
,
1213 valueMask
, valuePtr
);
1214 if (!(winPtr
->flags
& TK_TOP_LEVEL
)) {
1215 DoConfigureNotify(winPtr
);
1218 winPtr
->dirtyChanges
|= valueMask
;
1219 winPtr
->flags
|= TK_NEED_CONFIG_NOTIFY
;
1225 Tk_Window tkwin
, /* Window to move. */
1227 int y
/* New location for window (within
1231 register TkWindow
*winPtr
= (TkWindow
*) tkwin
;
1233 if (winPtr
->window
!= None
) {
1234 XMoveWindow(winPtr
->display
, winPtr
->window
, x
, y
);
1235 if (!(winPtr
->flags
& TK_TOP_LEVEL
)) {
1236 winPtr
->changes
.x
= x
;
1237 winPtr
->changes
.y
= y
;
1238 DoConfigureNotify(winPtr
);
1241 winPtr
->changes
.x
= x
;
1242 winPtr
->changes
.y
= y
;
1243 winPtr
->dirtyChanges
|= CWX
|CWY
;
1244 winPtr
->flags
|= TK_NEED_CONFIG_NOTIFY
;
1250 Tk_Window tkwin
, /* Window to resize. */
1252 unsigned int height
/* New dimensions for window. */
1255 register TkWindow
*winPtr
= (TkWindow
*) tkwin
;
1257 if (winPtr
->window
!= None
) {
1258 XResizeWindow(winPtr
->display
, winPtr
->window
, width
, height
);
1259 if (!(winPtr
->flags
& TK_TOP_LEVEL
)) {
1260 winPtr
->changes
.width
= width
;
1261 winPtr
->changes
.height
= height
;
1262 DoConfigureNotify(winPtr
);
1265 winPtr
->changes
.width
= width
;
1266 winPtr
->changes
.height
= height
;
1267 winPtr
->dirtyChanges
|= CWWidth
|CWHeight
;
1268 winPtr
->flags
|= TK_NEED_CONFIG_NOTIFY
;
1273 Tk_MoveResizeWindow (
1274 Tk_Window tkwin
, /* Window to move and resize. */
1276 int y
, /* New location for window (within
1279 unsigned int height
/* New dimensions for window. */
1282 register TkWindow
*winPtr
= (TkWindow
*) tkwin
;
1284 if (winPtr
->window
!= None
) {
1285 XMoveResizeWindow(winPtr
->display
, winPtr
->window
,
1286 x
, y
, width
, height
);
1287 if (!(winPtr
->flags
& TK_TOP_LEVEL
)) {
1288 winPtr
->changes
.x
= x
;
1289 winPtr
->changes
.y
= y
;
1290 winPtr
->changes
.width
= width
;
1291 winPtr
->changes
.height
= height
;
1292 DoConfigureNotify(winPtr
);
1295 winPtr
->changes
.x
= x
;
1296 winPtr
->changes
.y
= y
;
1297 winPtr
->changes
.width
= width
;
1298 winPtr
->changes
.height
= height
;
1299 winPtr
->dirtyChanges
|= CWX
|CWY
|CWWidth
|CWHeight
;
1300 winPtr
->flags
|= TK_NEED_CONFIG_NOTIFY
;
1305 Tk_SetWindowBorderWidth (
1306 Tk_Window tkwin
, /* Window to modify. */
1307 int width
/* New border width for window. */
1310 register TkWindow
*winPtr
= (TkWindow
*) tkwin
;
1312 winPtr
->changes
.border_width
= width
;
1313 if (winPtr
->window
!= None
) {
1314 XSetWindowBorderWidth(winPtr
->display
, winPtr
->window
, width
);
1315 if (!(winPtr
->flags
& TK_TOP_LEVEL
)) {
1316 DoConfigureNotify(winPtr
);
1319 winPtr
->dirtyChanges
|= CWBorderWidth
;
1320 winPtr
->flags
|= TK_NEED_CONFIG_NOTIFY
;
1325 Tk_ChangeWindowAttributes (
1326 Tk_Window tkwin
, /* Window to manipulate. */
1327 unsigned long valueMask
, /* OR'ed combination of bits,
1328 * indicating which fields of
1329 * *attsPtr are to be used. */
1330 register XSetWindowAttributes
*attsPtr
1332 /* New values for some attributes. */
1334 register TkWindow
*winPtr
= (TkWindow
*) tkwin
;
1336 if (valueMask
& CWBackPixmap
) {
1337 winPtr
->atts
.background_pixmap
= attsPtr
->background_pixmap
;
1339 if (valueMask
& CWBackPixel
) {
1340 winPtr
->atts
.background_pixel
= attsPtr
->background_pixel
;
1342 if (valueMask
& CWBorderPixmap
) {
1343 winPtr
->atts
.border_pixmap
= attsPtr
->border_pixmap
;
1345 if (valueMask
& CWBorderPixel
) {
1346 winPtr
->atts
.border_pixel
= attsPtr
->border_pixel
;
1348 if (valueMask
& CWBitGravity
) {
1349 winPtr
->atts
.bit_gravity
= attsPtr
->bit_gravity
;
1351 if (valueMask
& CWWinGravity
) {
1352 winPtr
->atts
.win_gravity
= attsPtr
->win_gravity
;
1354 if (valueMask
& CWBackingStore
) {
1355 winPtr
->atts
.backing_store
= attsPtr
->backing_store
;
1357 if (valueMask
& CWBackingPlanes
) {
1358 winPtr
->atts
.backing_planes
= attsPtr
->backing_planes
;
1360 if (valueMask
& CWBackingPixel
) {
1361 winPtr
->atts
.backing_pixel
= attsPtr
->backing_pixel
;
1363 if (valueMask
& CWOverrideRedirect
) {
1364 winPtr
->atts
.override_redirect
= attsPtr
->override_redirect
;
1366 if (valueMask
& CWSaveUnder
) {
1367 winPtr
->atts
.save_under
= attsPtr
->save_under
;
1369 if (valueMask
& CWEventMask
) {
1370 winPtr
->atts
.event_mask
= attsPtr
->event_mask
;
1372 if (valueMask
& CWDontPropagate
) {
1373 winPtr
->atts
.do_not_propagate_mask
1374 = attsPtr
->do_not_propagate_mask
;
1376 if (valueMask
& CWColormap
) {
1377 winPtr
->atts
.colormap
= attsPtr
->colormap
;
1379 if (valueMask
& CWCursor
) {
1380 winPtr
->atts
.cursor
= attsPtr
->cursor
;
1383 if (winPtr
->window
!= None
) {
1384 XChangeWindowAttributes(winPtr
->display
, winPtr
->window
,
1385 valueMask
, attsPtr
);
1387 winPtr
->dirtyAtts
|= valueMask
;
1392 Tk_SetWindowBackground (
1393 Tk_Window tkwin
, /* Window to manipulate. */
1394 unsigned long pixel
/* Pixel value to use for
1395 * window's background. */
1398 register TkWindow
*winPtr
= (TkWindow
*) tkwin
;
1400 winPtr
->atts
.background_pixel
= pixel
;
1402 if (winPtr
->window
!= None
) {
1403 XSetWindowBackground(winPtr
->display
, winPtr
->window
, pixel
);
1405 winPtr
->dirtyAtts
= (winPtr
->dirtyAtts
& ~CWBackPixmap
)
1411 Tk_SetWindowBackgroundPixmap (
1412 Tk_Window tkwin
, /* Window to manipulate. */
1413 Pixmap pixmap
/* Pixmap to use for window's
1417 register TkWindow
*winPtr
= (TkWindow
*) tkwin
;
1419 winPtr
->atts
.background_pixmap
= pixmap
;
1421 if (winPtr
->window
!= None
) {
1422 XSetWindowBackgroundPixmap(winPtr
->display
,
1423 winPtr
->window
, pixmap
);
1425 winPtr
->dirtyAtts
= (winPtr
->dirtyAtts
& ~CWBackPixel
)
1431 Tk_SetWindowBorder (
1432 Tk_Window tkwin
, /* Window to manipulate. */
1433 unsigned long pixel
/* Pixel value to use for
1434 * window's border. */
1437 register TkWindow
*winPtr
= (TkWindow
*) tkwin
;
1439 winPtr
->atts
.border_pixel
= pixel
;
1441 if (winPtr
->window
!= None
) {
1442 XSetWindowBorder(winPtr
->display
, winPtr
->window
, pixel
);
1444 winPtr
->dirtyAtts
= (winPtr
->dirtyAtts
& ~CWBorderPixmap
)
1450 Tk_SetWindowBorderPixmap (
1451 Tk_Window tkwin
, /* Window to manipulate. */
1452 Pixmap pixmap
/* Pixmap to use for window's
1456 register TkWindow
*winPtr
= (TkWindow
*) tkwin
;
1458 winPtr
->atts
.border_pixmap
= pixmap
;
1460 if (winPtr
->window
!= None
) {
1461 XSetWindowBorderPixmap(winPtr
->display
,
1462 winPtr
->window
, pixmap
);
1464 winPtr
->dirtyAtts
= (winPtr
->dirtyAtts
& ~CWBorderPixel
)
1471 Tk_Window tkwin
, /* Window to manipulate. */
1472 Cursor cursor
/* Cursor to use for window (may be None). */
1475 register TkWindow
*winPtr
= (TkWindow
*) tkwin
;
1477 winPtr
->atts
.cursor
= cursor
;
1479 if (winPtr
->window
!= None
) {
1480 XDefineCursor(winPtr
->display
, winPtr
->window
, cursor
);
1482 winPtr
->dirtyAtts
= winPtr
->dirtyAtts
| CWCursor
;
1488 Tk_Window tkwin
/* Window to manipulate. */
1491 Tk_DefineCursor(tkwin
, None
);
1495 *----------------------------------------------------------------------
1497 * DoConfigureNotify --
1499 * Generate a ConfigureNotify event describing the current
1500 * configuration of a window.
1506 * An event is generated and processed by Tk_HandleEvent.
1508 *----------------------------------------------------------------------
1513 register TkWindow
*winPtr
/* Window whose configuration
1514 * was just changed. */
1519 event
.type
= ConfigureNotify
;
1520 event
.xconfigure
.serial
= LastKnownRequestProcessed(winPtr
->display
);
1521 event
.xconfigure
.send_event
= False
;
1522 event
.xconfigure
.display
= winPtr
->display
;
1523 event
.xconfigure
.event
= winPtr
->window
;
1524 event
.xconfigure
.window
= winPtr
->window
;
1525 event
.xconfigure
.x
= winPtr
->changes
.x
;
1526 event
.xconfigure
.y
= winPtr
->changes
.y
;
1527 event
.xconfigure
.width
= winPtr
->changes
.width
;
1528 event
.xconfigure
.height
= winPtr
->changes
.height
;
1529 event
.xconfigure
.border_width
= winPtr
->changes
.border_width
;
1530 if (winPtr
->changes
.stack_mode
== Above
) {
1531 event
.xconfigure
.above
= winPtr
->changes
.sibling
;
1533 event
.xconfigure
.above
= None
;
1535 event
.xconfigure
.override_redirect
= winPtr
->atts
.override_redirect
;
1536 Tk_HandleEvent(&event
);
1540 *----------------------------------------------------------------------
1544 * This procedure is used to give a window a class.
1550 * A new class is stored for tkwin, replacing any existing
1553 *----------------------------------------------------------------------
1558 Tk_Window tkwin
, /* Token for window to assign class. */
1559 char *className
/* New class for tkwin. */
1562 register TkWindow
*winPtr
= (TkWindow
*) tkwin
;
1564 winPtr
->classUid
= Tk_GetUid(className
);
1565 if (winPtr
->flags
& TK_TOP_LEVEL
) {
1566 TkWmSetClass(winPtr
);
1571 *----------------------------------------------------------------------
1573 * Tk_NameToWindow --
1575 * Given a string name for a window, this procedure
1576 * returns the token for the window, if there exists a
1577 * window corresponding to the given name.
1580 * The return result is either a token for the window corresponding
1581 * to "name", or else NULL to indicate that there is no such
1582 * window. In this case, an error message is left in interp->result.
1587 *----------------------------------------------------------------------
1592 Tcl_Interp
*interp
, /* Where to report errors. */
1593 char *pathName
, /* Path name of window. */
1594 Tk_Window tkwin
/* Token for window: name is assumed to
1595 * belong to the same main window as tkwin. */
1598 Tcl_HashEntry
*hPtr
;
1600 hPtr
= Tcl_FindHashEntry(&((TkWindow
*) tkwin
)->mainPtr
->nameTable
,
1603 Tcl_AppendResult(interp
, "bad window path name \"",
1604 pathName
, "\"", (char *) NULL
);
1607 return (Tk_Window
) Tcl_GetHashValue(hPtr
);
1611 *----------------------------------------------------------------------
1615 * Return the textual name of a window's display.
1618 * The return value is the string name of the display associated
1624 *----------------------------------------------------------------------
1629 Tk_Window tkwin
/* Window whose display name is desired. */
1632 return ((TkWindow
*) tkwin
)->dispPtr
->name
;