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 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
},
138 {"accept", Tcp_AcceptCmd
},
139 {"shutdown", Tcp_ShutdownCmd
},
140 {"connect", Tcp_ConnectCmd
},
141 {"filehandler", Tcp_FileHandlerCmd
},
144 * Widget-creation commands.
146 {"button", Tk_ButtonCmd
},
147 {"canvas", Tk_CanvasCmd
},
148 {"checkbutton", Tk_ButtonCmd
},
149 {"entry", Tk_EntryCmd
},
150 {"frame", Tk_FrameCmd
},
151 {"label", Tk_ButtonCmd
},
152 {"listbox", Tk_ListboxCmd
},
153 {"menu", Tk_MenuCmd
},
154 {"menubutton", Tk_MenubuttonCmd
},
155 {"message", Tk_MessageCmd
},
156 {"radiobutton", Tk_ButtonCmd
},
157 {"scale", Tk_ScaleCmd
},
158 {"scrollbar", Tk_ScrollbarCmd
},
159 {"text", Tk_TextCmd
},
160 {"toplevel", Tk_FrameCmd
},
161 {(char *) NULL
, (int (*)()) NULL
}
165 * Forward declarations to procedures defined later in this file:
168 static Tk_Window CreateTopLevelWindow
_ANSI_ARGS_((Tcl_Interp
*interp
,
169 Tk_Window parent
, char *name
, char *screenName
));
170 static void DoConfigureNotify
_ANSI_ARGS_((TkWindow
*winPtr
));
171 static TkDisplay
* GetScreen
_ANSI_ARGS_((Tcl_Interp
*interp
,
172 char *screenName
, int *screenPtr
));
173 static int NameWindow
_ANSI_ARGS_((Tcl_Interp
*interp
,
174 TkWindow
*winPtr
, TkWindow
*parentPtr
,
176 static TkWindow
* NewWindow
_ANSI_ARGS_((TkDisplay
*dispPtr
,
180 *----------------------------------------------------------------------
182 * CreateTopLevelWindow --
184 * Make a new window that will be at top-level (its parent will
185 * be the root window of a screen).
188 * The return value is a token for the new window, or NULL if
189 * an error prevented the new window from being created. If
190 * NULL is returned, an error message will be left in
194 * A new window structure is allocated locally. An X
195 * window is NOT initially created, but will be created
196 * the first time the window is mapped.
198 *----------------------------------------------------------------------
202 CreateTopLevelWindow(interp
, parent
, name
, screenName
)
203 Tcl_Interp
*interp
; /* Interpreter to use for error reporting. */
204 Tk_Window parent
; /* Token for logical parent of new window
205 * (used for naming, options, etc.). May
207 char *name
; /* Name for new window; if parent is
208 * non-NULL, must be unique among parent's
210 char *screenName
; /* Name of screen on which to create
211 * window. NULL means use DISPLAY environment
212 * variable to determine. Empty string means
213 * use parent's screen, or DISPLAY if no
216 register TkWindow
*winPtr
;
217 register TkDisplay
*dispPtr
;
222 tkWindowContext
= XUniqueContext();
223 tkActiveUid
= Tk_GetUid("active");
224 tkDisabledUid
= Tk_GetUid("disabled");
225 tkNormalUid
= Tk_GetUid("normal");
228 if ((parent
!= NULL
) && (screenName
!= NULL
) && (screenName
[0] == '\0')) {
229 dispPtr
= ((TkWindow
*) parent
)->dispPtr
;
230 screenId
= Tk_ScreenNumber(parent
);
232 dispPtr
= GetScreen(interp
, screenName
, &screenId
);
233 if (dispPtr
== NULL
) {
234 return (Tk_Window
) NULL
;
238 winPtr
= NewWindow(dispPtr
, screenId
);
241 * Internal windows don't normally ask for StructureNotify events,
242 * since we can generate them internally. However, for top-level
243 * windows we need to as for the events because the window could
244 * be manipulated externally.
247 winPtr
->atts
.event_mask
|= StructureNotifyMask
;
250 * (Need to set the TK_TOP_LEVEL flag immediately here; otherwise
251 * Tk_DestroyWindow will core dump if it is called before the flag
255 winPtr
->flags
|= TK_TOP_LEVEL
;
256 if (parent
!= NULL
) {
257 if (NameWindow(interp
, winPtr
, (TkWindow
*) parent
, name
) != TCL_OK
) {
258 Tk_DestroyWindow((Tk_Window
) winPtr
);
259 return (Tk_Window
) NULL
;
262 TkWmNewWindow(winPtr
);
263 return (Tk_Window
) winPtr
;
267 *----------------------------------------------------------------------
271 * Given a string name for a display-plus-screen, find the
272 * TkDisplay structure for the display and return the screen
276 * The return value is a pointer to information about the display,
277 * or NULL if the display couldn't be opened. In this case, an
278 * error message is left in interp->result. The location at
279 * *screenPtr is overwritten with the screen number parsed from
283 * A new connection is opened to the display if there is no
284 * connection already. A new TkDisplay data structure is also
285 * setup, if necessary.
287 *----------------------------------------------------------------------
291 GetScreen(interp
, screenName
, screenPtr
)
292 Tcl_Interp
*interp
; /* Place to leave error message. */
293 char *screenName
; /* Name for screen. NULL or empty means
294 * use DISPLAY envariable. */
295 int *screenPtr
; /* Where to store screen number. */
297 register TkDisplay
*dispPtr
;
299 int length
, screenId
;
302 * Separate the screen number from the rest of the display
303 * name. ScreenName is assumed to have the syntax
304 * <display>.<screen> with the dot and the screen being
308 if ((screenName
== NULL
) || (screenName
[0] == '\0')) {
309 screenName
= getenv("DISPLAY");
310 if (screenName
== NULL
) {
312 "no display name and no $DISPLAY environment variable";
313 return (TkDisplay
*) NULL
;
316 length
= strlen(screenName
);
318 p
= screenName
+length
-1;
319 while (isdigit(*p
) && (p
!= screenName
)) {
322 if ((*p
== '.') && (p
[1] != '\0')) {
323 length
= p
- screenName
;
324 screenId
= strtoul(p
+1, (char **) NULL
, 10);
328 * See if we already have a connection to this display. If not,
329 * then open a new connection.
332 for (dispPtr
= tkDisplayList
; ; dispPtr
= dispPtr
->nextPtr
) {
333 if (dispPtr
== NULL
) {
334 Display
*display
= NULL
;
336 display
= XOpenDisplay(screenName
);
338 if (display
== NULL
) {
339 Tcl_AppendResult(interp
, "couldn't connect to display \"",
340 screenName
, "\"", (char *) NULL
);
341 return (TkDisplay
*) NULL
;
343 if (getenv("XSYNCHRONIZE") != NULL
) {
344 XSynchronize(display
, 1);
347 dispPtr
= (TkDisplay
*) ckalloc(sizeof(TkDisplay
));
348 dispPtr
->display
= display
;
349 dispPtr
->nextPtr
= tkDisplayList
;
350 dispPtr
->name
= (char *) ckalloc((unsigned) (length
+1));
351 dispPtr
->lastEventTime
= CurrentTime
;
352 strncpy(dispPtr
->name
, screenName
, length
);
353 dispPtr
->mouseMainPtr
= NULL
;
354 dispPtr
->name
[length
] = '\0';
355 dispPtr
->symsPerCode
= 0;
356 dispPtr
->errorPtr
= NULL
;
357 dispPtr
->deleteCount
= 0;
358 dispPtr
->commWindow
= NULL
;
359 dispPtr
->selectionOwner
= NULL
;
360 dispPtr
->selectionSerial
= 0;
361 dispPtr
->multipleAtom
= None
;
362 dispPtr
->atomInit
= 0;
363 dispPtr
->modeModMask
= 0;
364 dispPtr
->metaModMask
= 0;
365 dispPtr
->altModMask
= 0;
366 dispPtr
->cursorFont
= None
;
367 dispPtr
->grabWinPtr
= NULL
;
368 dispPtr
->ungrabWinPtr
= NULL
;
369 dispPtr
->buttonWinPtr
= NULL
;
370 dispPtr
->pointerWinPtr
= NULL
;
371 dispPtr
->serverWinPtr
= NULL
;
372 dispPtr
->grabFlags
= 0;
373 dispPtr
->focusPtr
= NULL
;
374 tkDisplayList
= dispPtr
;
375 Tk_CreateFileHandler(ConnectionNumber(display
),
376 TK_READABLE
, (void (*)()) NULL
,
377 (ClientData
) display
);
380 if ((strncmp(dispPtr
->name
, screenName
, length
) == 0)
381 && (dispPtr
->name
[length
] == '\0')) {
385 if (screenId
>= ScreenCount(dispPtr
->display
)) {
386 sprintf(interp
->result
, "bad screen number \"%d\"", screenId
);
387 return (TkDisplay
*) NULL
;
389 *screenPtr
= screenId
;
394 *--------------------------------------------------------------
398 * This procedure creates and initializes a TkWindow structure.
401 * The return value is a pointer to the new window.
404 * A new window structure is allocated and all its fields are
407 *--------------------------------------------------------------
411 NewWindow(dispPtr
, screenNum
)
412 TkDisplay
*dispPtr
; /* Display associated with new window. */
413 int screenNum
; /* Index of screen for new window. */
415 register TkWindow
*winPtr
;
417 winPtr
= (TkWindow
*) ckalloc(sizeof(TkWindow
));
418 winPtr
->display
= dispPtr
->display
;
419 winPtr
->dispPtr
= dispPtr
;
420 winPtr
->screenNum
= screenNum
;
421 winPtr
->window
= None
;
422 winPtr
->childList
= NULL
;
423 winPtr
->parentPtr
= NULL
;
424 winPtr
->nextPtr
= NULL
;
425 winPtr
->mainPtr
= NULL
;
426 winPtr
->pathName
= NULL
;
427 winPtr
->nameUid
= NULL
;
428 winPtr
->classUid
= NULL
;
429 winPtr
->changes
= defChanges
;
430 winPtr
->dirtyChanges
= CWX
|CWY
|CWWidth
|CWHeight
|CWBorderWidth
;
431 winPtr
->atts
= defAtts
;
432 winPtr
->dirtyAtts
= CWEventMask
;
434 winPtr
->handlerList
= NULL
;
435 winPtr
->focusProc
= NULL
;
436 winPtr
->focusData
= NULL
;
437 winPtr
->optionLevel
= -1;
438 winPtr
->selHandlerList
= NULL
;
439 winPtr
->selClearProc
= NULL
;
440 winPtr
->selClearData
= NULL
;
441 winPtr
->geomProc
= NULL
;
442 winPtr
->geomData
= NULL
;
443 winPtr
->reqWidth
= winPtr
->reqHeight
= 0;
444 winPtr
->internalBorderWidth
= 0;
445 winPtr
->wmInfoPtr
= NULL
;
450 *----------------------------------------------------------------------
454 * This procedure is invoked to give a window a name and insert
455 * the window into the hierarchy associated with a particular
459 * A standard Tcl return value.
464 *----------------------------------------------------------------------
468 NameWindow(interp
, winPtr
, parentPtr
, name
)
469 Tcl_Interp
*interp
; /* Interpreter to use for error reporting. */
470 register TkWindow
*winPtr
; /* Window that is to be named and inserted. */
471 TkWindow
*parentPtr
; /* Pointer to logical parent for winPtr
472 * (used for naming, options, etc.). */
473 char *name
; /* Name for winPtr; must be unique among
474 * parentPtr's children. */
476 #define FIXED_SIZE 200
477 char staticSpace
[FIXED_SIZE
];
481 int length1
, length2
;
484 * Setup all the stuff except name right away, then do the name stuff
485 * last. This is so that if the name stuff fails, everything else
486 * will be properly initialized (needed to destroy the window cleanly
487 * after the naming failure).
489 winPtr
->parentPtr
= parentPtr
;
490 winPtr
->nextPtr
= parentPtr
->childList
;
491 parentPtr
->childList
= winPtr
;
492 winPtr
->mainPtr
= parentPtr
->mainPtr
;
493 winPtr
->nameUid
= Tk_GetUid(name
);
496 * To permit names of arbitrary length, must be prepared to malloc
497 * a buffer to hold the new path name. To run fast in the common
498 * case where names are short, use a fixed-size buffer on the
502 length1
= strlen(parentPtr
->pathName
);
503 length2
= strlen(name
);
504 if ((length1
+length2
+2) <= FIXED_SIZE
) {
505 pathName
= staticSpace
;
507 pathName
= (char *) ckalloc((unsigned) (length1
+length2
+2));
511 strcpy(pathName
+1, name
);
513 strcpy(pathName
, parentPtr
->pathName
);
514 pathName
[length1
] = '.';
515 strcpy(pathName
+length1
+1, name
);
517 hPtr
= Tcl_CreateHashEntry(&parentPtr
->mainPtr
->nameTable
, pathName
, &new);
518 if (pathName
!= staticSpace
) {
522 Tcl_AppendResult(interp
, "window name \"", name
,
523 "\" already exists in parent", (char *) NULL
);
526 Tcl_SetHashValue(hPtr
, winPtr
);
527 winPtr
->pathName
= Tcl_GetHashKey(&parentPtr
->mainPtr
->nameTable
, hPtr
);
532 *----------------------------------------------------------------------
534 * Tk_CreateMainWindow --
536 * Make a new main window. A main window is a special kind of
537 * top-level window used as the outermost window in an
541 * The return value is a token for the new window, or NULL if
542 * an error prevented the new window from being created. If
543 * NULL is returned, an error message will be left in
547 * A new window structure is allocated locally; "interp" is
548 * associated with the window and registered for "send" commands
549 * under "baseName". BaseName may be extended with an instance
550 * number in the form "#2" if necessary to make it globally
551 * unique. Tk-related commands are bound into interp. An X
552 * window is NOT initially created, but will be created the
553 * first time the window is mapped.
555 *----------------------------------------------------------------------
559 Tk_CreateMainWindow(interp
, screenName
, baseName
)
560 Tcl_Interp
*interp
; /* Interpreter to use for error reporting. */
561 char *screenName
; /* Name of screen on which to create
562 * window. Empty or NULL string means
563 * use DISPLAY environment variable. */
564 char *baseName
; /* Base name for application; usually of the
565 * form "prog instance". */
570 register TkMainInfo
*mainPtr
;
571 register TkWindow
*winPtr
;
572 register TkCmd
*cmdPtr
;
575 * Create the basic TkWindow structure.
578 tkwin
= CreateTopLevelWindow(interp
, (Tk_Window
) NULL
, baseName
,
585 * Create the TkMainInfo structure for this application, and set
586 * up name-related information for the new window.
589 winPtr
= (TkWindow
*) tkwin
;
590 mainPtr
= (TkMainInfo
*) ckalloc(sizeof(TkMainInfo
));
591 mainPtr
->winPtr
= winPtr
;
592 mainPtr
->interp
= interp
;
593 Tcl_InitHashTable(&mainPtr
->nameTable
, TCL_STRING_KEYS
);
594 mainPtr
->bindingTable
= Tk_CreateBindingTable(interp
);
596 /* mainPtr->focusPtr = NULL; */
597 mainPtr
->optionRootPtr
= NULL
;
598 winPtr
->mainPtr
= mainPtr
;
599 hPtr
= Tcl_CreateHashEntry(&mainPtr
->nameTable
, ".", &dummy
);
600 Tcl_SetHashValue(hPtr
, winPtr
);
601 winPtr
->pathName
= Tcl_GetHashKey(&mainPtr
->nameTable
, hPtr
);
604 * Register the interpreter for "send" purposes. If baseName isn't
605 * already unique, find a unique suffix to add to it to make it
606 * unique. Change the window's name to contain the suffix.
609 result
= Tk_RegisterInterp(interp
, baseName
, tkwin
);
610 if (result
== TCL_OK
) {
611 winPtr
->nameUid
= Tk_GetUid(baseName
);
617 sprintf(newName
, "%.100s #%d", baseName
, i
);
618 Tcl_SetResult(interp
, (char *) NULL
, TCL_STATIC
);
619 result
= Tk_RegisterInterp(interp
, newName
, tkwin
);
620 if (result
== TCL_OK
) {
624 Tcl_SetResult(interp
,
625 "couldn't generate unique name to register application",
627 Tk_DestroyWindow(tkwin
);
630 winPtr
->nameUid
= Tk_GetUid(newName
);
634 * Bind in Tk's commands.
637 for (cmdPtr
= commands
; cmdPtr
->name
!= NULL
; cmdPtr
++) {
638 Tcl_CreateCommand(interp
, cmdPtr
->name
, cmdPtr
->cmdProc
,
639 (ClientData
) tkwin
, (void (*)()) NULL
);
643 * Set variables for the intepreter.
646 Tcl_SetVar(interp
, "tk_library", TK_Library
, TCL_GLOBAL_ONLY
);
647 Tcl_SetVar(interp
, "tk_version", TK_VERSION
, TCL_GLOBAL_ONLY
);
648 Tcl_SetVar(interp
, "tkVersion", TK_VERSION
, TCL_GLOBAL_ONLY
);
655 *--------------------------------------------------------------
659 * Create a new internal or top-level window as a child of an
663 * The return value is a token for the new window. This
664 * is not the same as X's token for the window. If an error
665 * occurred in creating the window (e.g. no such display or
666 * screen), then an error message is left in interp->result and
670 * A new window structure is allocated locally. An X
671 * window is not initially created, but will be created
672 * the first time the window is mapped.
674 *--------------------------------------------------------------
678 Tk_CreateWindow(interp
, parent
, name
, screenName
)
679 Tcl_Interp
*interp
; /* Interpreter to use for error reporting.
680 * Interp->result is assumed to be
681 * initialized by the caller. */
682 Tk_Window parent
; /* Token for parent of new window. */
683 char *name
; /* Name for new window. Must be unique
684 * among parent's children. */
685 char *screenName
; /* If NULL, new window will be internal on
686 * same screen as its parent. If non-NULL,
687 * gives name of screen on which to create
688 * new window; window will be a top-level
691 TkWindow
*parentPtr
= (TkWindow
*) parent
;
694 if (screenName
== NULL
) {
695 winPtr
= NewWindow(parentPtr
->dispPtr
, parentPtr
->screenNum
);
696 if (NameWindow(interp
, winPtr
, parentPtr
, name
) != TCL_OK
) {
697 Tk_DestroyWindow((Tk_Window
) winPtr
);
700 return (Tk_Window
) winPtr
;
704 * This is a fix for dvx XOpenDisplay... display name conformalization
710 strcpy(dsp
, screenName
);
712 if (len
&& (dsp
[len
-1] == '.'))
715 return CreateTopLevelWindow(interp
, parent
, name
, dsp
);
720 *----------------------------------------------------------------------
722 * Tk_CreateWindowFromPath --
724 * This procedure is similar to Tk_CreateInternalWindow except
725 * that it uses a path name to create the window, rather than
726 * a parent and a child name.
729 * The return value is a token for the new window. This
730 * is not the same as X's token for the window. If an error
731 * occurred in creating the window (e.g. no such display or
732 * screen), then an error message is left in interp->result and
736 * A new window structure is allocated locally. An X
737 * window is not initially created, but will be created
738 * the first time the window is mapped.
740 *----------------------------------------------------------------------
744 Tk_CreateWindowFromPath(interp
, tkwin
, pathName
, screenName
)
745 Tcl_Interp
*interp
; /* Interpreter to use for error reporting.
746 * Interp->result is assumed to be
747 * initialized by the caller. */
748 Tk_Window tkwin
; /* Token for any window in application
749 * that is to contain new window. */
750 char *pathName
; /* Path name for new window within the
751 * application of tkwin. The parent of
752 * this window must already exist, but
753 * the window itself must not exist. */
754 char *screenName
; /* If NULL, new window will be on same
755 * screen as its parent. If non-NULL,
756 * gives name of screen on which to create
757 * new window; window will be a top-level
760 #define FIXED_SPACE 5
761 char fixedSpace
[FIXED_SPACE
+1];
767 * Strip the parent's name out of pathName (it's everything up
768 * to the last dot). There are two tricky parts: (a) must
769 * copy the parent's name somewhere else to avoid modifying
770 * the pathName string (for large names, space for the copy
771 * will have to be malloc'ed); (b) must special-case the
772 * situation where the parent is ".".
775 p
= strrchr(pathName
, '.');
777 Tcl_AppendResult(interp
, "bad window path name \"", pathName
,
778 "\"", (char *) NULL
);
781 numChars
= p
-pathName
;
782 if (numChars
> FIXED_SPACE
) {
783 p
= (char *) ckalloc((unsigned) (numChars
+1));
791 strncpy(p
, pathName
, numChars
);
796 * Find the parent window.
799 parent
= Tk_NameToWindow(interp
, p
, tkwin
);
800 if (p
!= fixedSpace
) {
803 if (parent
== NULL
) {
811 if (screenName
== NULL
) {
812 TkWindow
*parentPtr
= (TkWindow
*) parent
;
815 winPtr
= NewWindow(parentPtr
->dispPtr
, parentPtr
->screenNum
);
816 if (NameWindow(interp
, winPtr
, parentPtr
, pathName
+numChars
+1)
818 Tk_DestroyWindow((Tk_Window
) winPtr
);
821 return (Tk_Window
) winPtr
;
824 return CreateTopLevelWindow(interp
, parent
, pathName
+numChars
+1,
830 *--------------------------------------------------------------
832 * Tk_DestroyWindow --
834 * Destroy an existing window. After this call, the caller
835 * should never again use the token.
841 * The window is deleted, along with all of its children.
842 * Relevant callback procedures are invoked.
844 *--------------------------------------------------------------
848 Tk_DestroyWindow(tkwin
)
849 Tk_Window tkwin
; /* Window to destroy. */
851 register TkWindow
*winPtr
= (TkWindow
*) tkwin
;
855 * Recursively destroy children. The TK_RECURSIVE_DESTROY
856 * flags means that the child's window needn't be explicitly
857 * destroyed (the destroy of the parent already did it), nor
858 * does it need to be removed from its parent's child list,
859 * since the parent is being destroyed too.
862 while (winPtr
->childList
!= NULL
) {
863 winPtr
->childList
->flags
|= TK_RECURSIVE_DESTROY
;
864 Tk_DestroyWindow((Tk_Window
) winPtr
->childList
);
868 * Generate a DestroyNotify event. In order for the DestroyNotify
869 * event to be processed correctly, need to make sure the window
870 * exists. This is a bit of a kludge, and may be unnecessarily
871 * expensive, but without it no event handlers will get called for
872 * windows that don't exist yet.
875 if (winPtr
->window
== None
) {
876 Tk_MakeWindowExist(tkwin
);
878 winPtr
->flags
|= TK_ALREADY_DEAD
;
879 event
.type
= DestroyNotify
;
880 event
.xdestroywindow
.serial
=
881 LastKnownRequestProcessed(winPtr
->display
);
882 event
.xdestroywindow
.send_event
= False
;
883 event
.xdestroywindow
.display
= winPtr
->display
;
884 event
.xdestroywindow
.event
= winPtr
->window
;
885 event
.xdestroywindow
.window
= winPtr
->window
;
886 Tk_HandleEvent(&event
);
889 * Cleanup the data structures associated with this window.
890 * No need to destroy windows during recursive destroys, since
891 * that will happen automatically when the parent window is
892 * destroyed (not true for top-level windows: must destroy
896 if (winPtr
->window
!= None
) {
897 if (!(winPtr
->flags
& TK_RECURSIVE_DESTROY
)
898 || (winPtr
->flags
& TK_TOP_LEVEL
)) {
899 XDestroyWindow(winPtr
->display
, winPtr
->window
);
901 XDeleteContext(winPtr
->display
, winPtr
->window
, tkWindowContext
);
902 winPtr
->window
= None
;
904 if (winPtr
->parentPtr
!= NULL
) {
905 if (winPtr
->parentPtr
->childList
== winPtr
) {
906 winPtr
->parentPtr
->childList
= winPtr
->nextPtr
;
908 register TkWindow
*winPtr2
;
910 for (winPtr2
= winPtr
->parentPtr
->childList
; ;
911 winPtr2
= winPtr2
->nextPtr
) {
912 if (winPtr2
== NULL
) {
913 panic("Tk_DestroyWindow couldn't find child in parent (deleted twice?)");
916 if (winPtr2
->nextPtr
== winPtr
) {
917 winPtr2
->nextPtr
= winPtr
->nextPtr
;
923 TkEventDeadWindow(winPtr
);
924 TkOptionDeadWindow(winPtr
);
925 TkSelDeadWindow(winPtr
);
926 if (winPtr
->flags
& TK_TOP_LEVEL
) {
927 TkWmDeadWindow(winPtr
);
929 TkGrabDeadWindow(winPtr
);
930 if (winPtr
->mainPtr
!= NULL
) {
931 Tk_DeleteAllBindings(winPtr
->mainPtr
->bindingTable
,
932 (ClientData
) winPtr
->pathName
);
933 if (winPtr
->pathName
!= NULL
) {
934 Tcl_DeleteHashEntry(Tcl_FindHashEntry(&winPtr
->mainPtr
->nameTable
,
937 if (winPtr
->mainPtr
->winPtr
== winPtr
) {
938 register TkCmd
*cmdPtr
;
941 * Deleting a main window. Delete the TkMainInfo structure too
942 * and replace all of Tk's commands with dummy commands that
943 * return errors. Also delete the "send" command to unregister
947 for (cmdPtr
= commands
; cmdPtr
->name
!= NULL
; cmdPtr
++) {
948 Tcl_CreateCommand(winPtr
->mainPtr
->interp
, cmdPtr
->name
,
949 TkDeadAppCmd
, (ClientData
) NULL
, (void (*)()) NULL
);
951 Tcl_CreateCommand(winPtr
->mainPtr
->interp
, "send",
952 TkDeadAppCmd
, (ClientData
) NULL
, (void (*)()) NULL
);
953 Tcl_DeleteHashTable(&winPtr
->mainPtr
->nameTable
);
954 Tk_DeleteBindingTable(winPtr
->mainPtr
->bindingTable
);
955 ckfree((char *) winPtr
->mainPtr
);
959 ckfree((char *) winPtr
);
963 *--------------------------------------------------------------
967 * Map a window within its parent. This may require the
968 * window and/or its parents to actually be created.
974 * The given window will be mapped. Windows may also
977 *--------------------------------------------------------------
982 Tk_Window tkwin
; /* Token for window to map. */
984 register TkWindow
*winPtr
= (TkWindow
*) tkwin
;
986 if (winPtr
->flags
& TK_MAPPED
) {
989 if (winPtr
->window
== None
) {
990 Tk_MakeWindowExist(tkwin
);
992 if (winPtr
->flags
& TK_TOP_LEVEL
) {
993 if (!TkWmMapWindow(winPtr
)) {
998 * Don't set the mapped flag for top-level windows: TkWmMapWindow
999 * does it if appropriate (e.g. if the window is going to be non-
1003 winPtr
->flags
|= TK_MAPPED
;
1005 XMapWindow(winPtr
->display
, winPtr
->window
);
1006 if (!(winPtr
->flags
& TK_TOP_LEVEL
)) {
1009 event
.type
= MapNotify
;
1010 event
.xmap
.serial
= LastKnownRequestProcessed(winPtr
->display
);
1011 event
.xmap
.send_event
= False
;
1012 event
.xmap
.display
= winPtr
->display
;
1013 event
.xmap
.event
= winPtr
->window
;
1014 event
.xmap
.window
= winPtr
->window
;
1015 event
.xmap
.override_redirect
= winPtr
->atts
.override_redirect
;
1016 Tk_HandleEvent(&event
);
1021 *--------------------------------------------------------------
1023 * Tk_MakeWindowExist --
1025 * Ensure that a particular window actually exists. This
1026 * procedure shouldn't normally need to be invoked from
1027 * outside the Tk package, but may be needed if someone
1028 * wants to manipulate a window before mapping it.
1034 * When the procedure returns, the X window associated with
1035 * tkwin is guaranteed to exist. This may require the
1036 * window's ancestors to be created also.
1038 *--------------------------------------------------------------
1042 Tk_MakeWindowExist(tkwin
)
1043 Tk_Window tkwin
; /* Token for window. */
1045 register TkWindow
*winPtr
= (TkWindow
*) tkwin
;
1048 if (winPtr
->window
!= None
) {
1052 if (winPtr
->flags
& TK_TOP_LEVEL
) {
1054 * workaround by dhopkins for OLPC Micropolis gtk.Socket integration.
1057 if (tk_RootWindow
) {
1062 XRootWindow(winPtr
->display
, winPtr
->screenNum
);
1066 if (winPtr
->parentPtr
->window
== None
) {
1067 Tk_MakeWindowExist((Tk_Window
) winPtr
->parentPtr
);
1069 parent
= winPtr
->parentPtr
->window
;
1072 /* workaround to support non-default colormaps */
1074 winPtr
->window
= XCreateWindow(winPtr
->display
, parent
,
1075 winPtr
->changes
.x
, winPtr
->changes
.y
,
1076 winPtr
->changes
.width
, winPtr
->changes
.height
,
1077 winPtr
->changes
.border_width
, CopyFromParent
,
1078 InputOutput
, CopyFromParent
, winPtr
->dirtyAtts
,
1081 { Screen
*scr
= ScreenOfDisplay(winPtr
->display
, winPtr
->screenNum
);
1083 winPtr
->dirtyAtts
|= CWColormap
| CWBorderPixmap
;
1084 winPtr
->atts
.colormap
= Tk_DefaultColormap(scr
);
1085 winPtr
->atts
.border_pixmap
= Tk_DefaultPixmap(scr
);
1087 winPtr
->window
= XCreateWindow(winPtr
->display
, parent
,
1088 winPtr
->changes
.x
, winPtr
->changes
.y
,
1089 winPtr
->changes
.width
, winPtr
->changes
.height
,
1090 winPtr
->changes
.border_width
,
1091 Tk_DefaultDepth(scr
),
1093 Tk_DefaultVisual(scr
),
1094 winPtr
->dirtyAtts
, &winPtr
->atts
);
1098 XSaveContext(winPtr
->display
, winPtr
->window
, tkWindowContext
,
1100 winPtr
->dirtyAtts
= 0;
1101 winPtr
->dirtyChanges
&= ~(CWX
|CWY
|CWWidth
|CWHeight
|CWBorderWidth
);
1102 if (winPtr
->dirtyChanges
!= 0) {
1103 XConfigureWindow(winPtr
->display
, winPtr
->window
,
1104 winPtr
->dirtyChanges
, &winPtr
->changes
);
1105 winPtr
->dirtyChanges
= 0;
1109 * Issue a ConfigureNotify event if there were deferred configuration
1113 if (winPtr
->flags
& TK_NEED_CONFIG_NOTIFY
) {
1114 winPtr
->flags
&= ~TK_NEED_CONFIG_NOTIFY
;
1115 DoConfigureNotify(winPtr
);
1120 *--------------------------------------------------------------
1122 * Tk_UnmapWindow, etc. --
1124 * There are several procedures under here, each of which
1125 * mirrors an existing X procedure. In addition to performing
1126 * the functions of the corresponding procedure, each
1127 * procedure also updates the local window structure and
1128 * synthesizes an X event (if the window's structure is being
1129 * managed internally).
1132 * See the manual entries.
1135 * See the manual entries.
1137 *--------------------------------------------------------------
1141 Tk_UnmapWindow(tkwin
)
1142 Tk_Window tkwin
; /* Token for window to unmap. */
1144 register TkWindow
*winPtr
= (TkWindow
*) tkwin
;
1146 if (!(winPtr
->flags
& TK_MAPPED
)) {
1149 winPtr
->flags
&= ~TK_MAPPED
;
1150 XUnmapWindow(winPtr
->display
, winPtr
->window
);
1151 if (!(winPtr
->flags
& TK_TOP_LEVEL
)) {
1154 event
.type
= UnmapNotify
;
1155 event
.xunmap
.serial
= LastKnownRequestProcessed(winPtr
->display
);
1156 event
.xunmap
.send_event
= False
;
1157 event
.xunmap
.display
= winPtr
->display
;
1158 event
.xunmap
.event
= winPtr
->window
;
1159 event
.xunmap
.window
= winPtr
->window
;
1160 event
.xunmap
.from_configure
= False
;
1161 Tk_HandleEvent(&event
);
1166 Tk_ConfigureWindow(tkwin
, valueMask
, valuePtr
)
1167 Tk_Window tkwin
; /* Window to re-configure. */
1168 unsigned int valueMask
; /* Mask indicating which parts of
1169 * *valuePtr are to be used. */
1170 XWindowChanges
*valuePtr
; /* New values. */
1172 register TkWindow
*winPtr
= (TkWindow
*) tkwin
;
1174 if ((winPtr
->window
== None
) || !(winPtr
->flags
& TK_TOP_LEVEL
)) {
1175 if (valueMask
& CWX
) {
1176 winPtr
->changes
.x
= valuePtr
->x
;
1178 if (valueMask
& CWY
) {
1179 winPtr
->changes
.y
= valuePtr
->y
;
1181 if (valueMask
& CWWidth
) {
1182 winPtr
->changes
.width
= valuePtr
->width
;
1184 if (valueMask
& CWHeight
) {
1185 winPtr
->changes
.height
= valuePtr
->height
;
1187 if (valueMask
& CWBorderWidth
) {
1188 winPtr
->changes
.border_width
= valuePtr
->border_width
;
1190 if (valueMask
& CWSibling
) {
1191 winPtr
->changes
.sibling
= valuePtr
->sibling
;
1193 if (valueMask
& CWStackMode
) {
1194 winPtr
->changes
.stack_mode
= valuePtr
->stack_mode
;
1198 if (winPtr
->window
!= None
) {
1199 XConfigureWindow(winPtr
->display
, winPtr
->window
,
1200 valueMask
, valuePtr
);
1201 if (!(winPtr
->flags
& TK_TOP_LEVEL
)) {
1202 DoConfigureNotify(winPtr
);
1205 winPtr
->dirtyChanges
|= valueMask
;
1206 winPtr
->flags
|= TK_NEED_CONFIG_NOTIFY
;
1211 Tk_MoveWindow(tkwin
, x
, y
)
1212 Tk_Window tkwin
; /* Window to move. */
1213 int x
, y
; /* New location for window (within
1216 register TkWindow
*winPtr
= (TkWindow
*) tkwin
;
1218 if (winPtr
->window
!= None
) {
1219 XMoveWindow(winPtr
->display
, winPtr
->window
, x
, y
);
1220 if (!(winPtr
->flags
& TK_TOP_LEVEL
)) {
1221 winPtr
->changes
.x
= x
;
1222 winPtr
->changes
.y
= y
;
1223 DoConfigureNotify(winPtr
);
1226 winPtr
->changes
.x
= x
;
1227 winPtr
->changes
.y
= y
;
1228 winPtr
->dirtyChanges
|= CWX
|CWY
;
1229 winPtr
->flags
|= TK_NEED_CONFIG_NOTIFY
;
1234 Tk_ResizeWindow(tkwin
, width
, height
)
1235 Tk_Window tkwin
; /* Window to resize. */
1236 unsigned int width
, height
; /* New dimensions for window. */
1238 register TkWindow
*winPtr
= (TkWindow
*) tkwin
;
1240 if (winPtr
->window
!= None
) {
1241 XResizeWindow(winPtr
->display
, winPtr
->window
, width
, height
);
1242 if (!(winPtr
->flags
& TK_TOP_LEVEL
)) {
1243 winPtr
->changes
.width
= width
;
1244 winPtr
->changes
.height
= height
;
1245 DoConfigureNotify(winPtr
);
1248 winPtr
->changes
.width
= width
;
1249 winPtr
->changes
.height
= height
;
1250 winPtr
->dirtyChanges
|= CWWidth
|CWHeight
;
1251 winPtr
->flags
|= TK_NEED_CONFIG_NOTIFY
;
1256 Tk_MoveResizeWindow(tkwin
, x
, y
, width
, height
)
1257 Tk_Window tkwin
; /* Window to move and resize. */
1258 int x
, y
; /* New location for window (within
1260 unsigned int width
, height
; /* New dimensions for window. */
1262 register TkWindow
*winPtr
= (TkWindow
*) tkwin
;
1264 if (winPtr
->window
!= None
) {
1265 XMoveResizeWindow(winPtr
->display
, winPtr
->window
,
1266 x
, y
, width
, height
);
1267 if (!(winPtr
->flags
& TK_TOP_LEVEL
)) {
1268 winPtr
->changes
.x
= x
;
1269 winPtr
->changes
.y
= y
;
1270 winPtr
->changes
.width
= width
;
1271 winPtr
->changes
.height
= height
;
1272 DoConfigureNotify(winPtr
);
1275 winPtr
->changes
.x
= x
;
1276 winPtr
->changes
.y
= y
;
1277 winPtr
->changes
.width
= width
;
1278 winPtr
->changes
.height
= height
;
1279 winPtr
->dirtyChanges
|= CWX
|CWY
|CWWidth
|CWHeight
;
1280 winPtr
->flags
|= TK_NEED_CONFIG_NOTIFY
;
1285 Tk_SetWindowBorderWidth(tkwin
, width
)
1286 Tk_Window tkwin
; /* Window to modify. */
1287 int width
; /* New border width for window. */
1289 register TkWindow
*winPtr
= (TkWindow
*) tkwin
;
1291 winPtr
->changes
.border_width
= width
;
1292 if (winPtr
->window
!= None
) {
1293 XSetWindowBorderWidth(winPtr
->display
, winPtr
->window
, width
);
1294 if (!(winPtr
->flags
& TK_TOP_LEVEL
)) {
1295 DoConfigureNotify(winPtr
);
1298 winPtr
->dirtyChanges
|= CWBorderWidth
;
1299 winPtr
->flags
|= TK_NEED_CONFIG_NOTIFY
;
1304 Tk_ChangeWindowAttributes(tkwin
, valueMask
, attsPtr
)
1305 Tk_Window tkwin
; /* Window to manipulate. */
1306 unsigned long valueMask
; /* OR'ed combination of bits,
1307 * indicating which fields of
1308 * *attsPtr are to be used. */
1309 register XSetWindowAttributes
*attsPtr
;
1310 /* New values for some attributes. */
1312 register TkWindow
*winPtr
= (TkWindow
*) tkwin
;
1314 if (valueMask
& CWBackPixmap
) {
1315 winPtr
->atts
.background_pixmap
= attsPtr
->background_pixmap
;
1317 if (valueMask
& CWBackPixel
) {
1318 winPtr
->atts
.background_pixel
= attsPtr
->background_pixel
;
1320 if (valueMask
& CWBorderPixmap
) {
1321 winPtr
->atts
.border_pixmap
= attsPtr
->border_pixmap
;
1323 if (valueMask
& CWBorderPixel
) {
1324 winPtr
->atts
.border_pixel
= attsPtr
->border_pixel
;
1326 if (valueMask
& CWBitGravity
) {
1327 winPtr
->atts
.bit_gravity
= attsPtr
->bit_gravity
;
1329 if (valueMask
& CWWinGravity
) {
1330 winPtr
->atts
.win_gravity
= attsPtr
->win_gravity
;
1332 if (valueMask
& CWBackingStore
) {
1333 winPtr
->atts
.backing_store
= attsPtr
->backing_store
;
1335 if (valueMask
& CWBackingPlanes
) {
1336 winPtr
->atts
.backing_planes
= attsPtr
->backing_planes
;
1338 if (valueMask
& CWBackingPixel
) {
1339 winPtr
->atts
.backing_pixel
= attsPtr
->backing_pixel
;
1341 if (valueMask
& CWOverrideRedirect
) {
1342 winPtr
->atts
.override_redirect
= attsPtr
->override_redirect
;
1344 if (valueMask
& CWSaveUnder
) {
1345 winPtr
->atts
.save_under
= attsPtr
->save_under
;
1347 if (valueMask
& CWEventMask
) {
1348 winPtr
->atts
.event_mask
= attsPtr
->event_mask
;
1350 if (valueMask
& CWDontPropagate
) {
1351 winPtr
->atts
.do_not_propagate_mask
1352 = attsPtr
->do_not_propagate_mask
;
1354 if (valueMask
& CWColormap
) {
1355 winPtr
->atts
.colormap
= attsPtr
->colormap
;
1357 if (valueMask
& CWCursor
) {
1358 winPtr
->atts
.cursor
= attsPtr
->cursor
;
1361 if (winPtr
->window
!= None
) {
1362 XChangeWindowAttributes(winPtr
->display
, winPtr
->window
,
1363 valueMask
, attsPtr
);
1365 winPtr
->dirtyAtts
|= valueMask
;
1370 Tk_SetWindowBackground(tkwin
, pixel
)
1371 Tk_Window tkwin
; /* Window to manipulate. */
1372 unsigned long pixel
; /* Pixel value to use for
1373 * window's background. */
1375 register TkWindow
*winPtr
= (TkWindow
*) tkwin
;
1377 winPtr
->atts
.background_pixel
= pixel
;
1379 if (winPtr
->window
!= None
) {
1380 XSetWindowBackground(winPtr
->display
, winPtr
->window
, pixel
);
1382 winPtr
->dirtyAtts
= (winPtr
->dirtyAtts
& ~CWBackPixmap
)
1388 Tk_SetWindowBackgroundPixmap(tkwin
, pixmap
)
1389 Tk_Window tkwin
; /* Window to manipulate. */
1390 Pixmap pixmap
; /* Pixmap to use for window's
1393 register TkWindow
*winPtr
= (TkWindow
*) tkwin
;
1395 winPtr
->atts
.background_pixmap
= pixmap
;
1397 if (winPtr
->window
!= None
) {
1398 XSetWindowBackgroundPixmap(winPtr
->display
,
1399 winPtr
->window
, pixmap
);
1401 winPtr
->dirtyAtts
= (winPtr
->dirtyAtts
& ~CWBackPixel
)
1407 Tk_SetWindowBorder(tkwin
, pixel
)
1408 Tk_Window tkwin
; /* Window to manipulate. */
1409 unsigned long pixel
; /* Pixel value to use for
1410 * window's border. */
1412 register TkWindow
*winPtr
= (TkWindow
*) tkwin
;
1414 winPtr
->atts
.border_pixel
= pixel
;
1416 if (winPtr
->window
!= None
) {
1417 XSetWindowBorder(winPtr
->display
, winPtr
->window
, pixel
);
1419 winPtr
->dirtyAtts
= (winPtr
->dirtyAtts
& ~CWBorderPixmap
)
1425 Tk_SetWindowBorderPixmap(tkwin
, pixmap
)
1426 Tk_Window tkwin
; /* Window to manipulate. */
1427 Pixmap pixmap
; /* Pixmap to use for window's
1430 register TkWindow
*winPtr
= (TkWindow
*) tkwin
;
1432 winPtr
->atts
.border_pixmap
= pixmap
;
1434 if (winPtr
->window
!= None
) {
1435 XSetWindowBorderPixmap(winPtr
->display
,
1436 winPtr
->window
, pixmap
);
1438 winPtr
->dirtyAtts
= (winPtr
->dirtyAtts
& ~CWBorderPixel
)
1444 Tk_DefineCursor(tkwin
, cursor
)
1445 Tk_Window tkwin
; /* Window to manipulate. */
1446 Cursor cursor
; /* Cursor to use for window (may be None). */
1448 register TkWindow
*winPtr
= (TkWindow
*) tkwin
;
1450 winPtr
->atts
.cursor
= cursor
;
1452 if (winPtr
->window
!= None
) {
1453 XDefineCursor(winPtr
->display
, winPtr
->window
, cursor
);
1455 winPtr
->dirtyAtts
= winPtr
->dirtyAtts
| CWCursor
;
1460 Tk_UndefineCursor(tkwin
)
1461 Tk_Window tkwin
; /* Window to manipulate. */
1463 Tk_DefineCursor(tkwin
, None
);
1467 *----------------------------------------------------------------------
1469 * DoConfigureNotify --
1471 * Generate a ConfigureNotify event describing the current
1472 * configuration of a window.
1478 * An event is generated and processed by Tk_HandleEvent.
1480 *----------------------------------------------------------------------
1484 DoConfigureNotify(winPtr
)
1485 register TkWindow
*winPtr
; /* Window whose configuration
1486 * was just changed. */
1490 event
.type
= ConfigureNotify
;
1491 event
.xconfigure
.serial
= LastKnownRequestProcessed(winPtr
->display
);
1492 event
.xconfigure
.send_event
= False
;
1493 event
.xconfigure
.display
= winPtr
->display
;
1494 event
.xconfigure
.event
= winPtr
->window
;
1495 event
.xconfigure
.window
= winPtr
->window
;
1496 event
.xconfigure
.x
= winPtr
->changes
.x
;
1497 event
.xconfigure
.y
= winPtr
->changes
.y
;
1498 event
.xconfigure
.width
= winPtr
->changes
.width
;
1499 event
.xconfigure
.height
= winPtr
->changes
.height
;
1500 event
.xconfigure
.border_width
= winPtr
->changes
.border_width
;
1501 if (winPtr
->changes
.stack_mode
== Above
) {
1502 event
.xconfigure
.above
= winPtr
->changes
.sibling
;
1504 event
.xconfigure
.above
= None
;
1506 event
.xconfigure
.override_redirect
= winPtr
->atts
.override_redirect
;
1507 Tk_HandleEvent(&event
);
1511 *----------------------------------------------------------------------
1515 * This procedure is used to give a window a class.
1521 * A new class is stored for tkwin, replacing any existing
1524 *----------------------------------------------------------------------
1528 Tk_SetClass(tkwin
, className
)
1529 Tk_Window tkwin
; /* Token for window to assign class. */
1530 char *className
; /* New class for tkwin. */
1532 register TkWindow
*winPtr
= (TkWindow
*) tkwin
;
1534 winPtr
->classUid
= Tk_GetUid(className
);
1535 if (winPtr
->flags
& TK_TOP_LEVEL
) {
1536 TkWmSetClass(winPtr
);
1541 *----------------------------------------------------------------------
1543 * Tk_NameToWindow --
1545 * Given a string name for a window, this procedure
1546 * returns the token for the window, if there exists a
1547 * window corresponding to the given name.
1550 * The return result is either a token for the window corresponding
1551 * to "name", or else NULL to indicate that there is no such
1552 * window. In this case, an error message is left in interp->result.
1557 *----------------------------------------------------------------------
1561 Tk_NameToWindow(interp
, pathName
, tkwin
)
1562 Tcl_Interp
*interp
; /* Where to report errors. */
1563 char *pathName
; /* Path name of window. */
1564 Tk_Window tkwin
; /* Token for window: name is assumed to
1565 * belong to the same main window as tkwin. */
1567 Tcl_HashEntry
*hPtr
;
1569 hPtr
= Tcl_FindHashEntry(&((TkWindow
*) tkwin
)->mainPtr
->nameTable
,
1572 Tcl_AppendResult(interp
, "bad window path name \"",
1573 pathName
, "\"", (char *) NULL
);
1576 return (Tk_Window
) Tcl_GetHashValue(hPtr
);
1580 *----------------------------------------------------------------------
1584 * Return the textual name of a window's display.
1587 * The return value is the string name of the display associated
1593 *----------------------------------------------------------------------
1597 Tk_DisplayName(tkwin
)
1598 Tk_Window tkwin
; /* Window whose display name is desired. */
1600 return ((TkWindow
*) tkwin
)->dispPtr
->name
;