|
|
1.1 root 1: /*
2: * tkWindow.c --
3: *
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
7: * structure.
8: *
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.
17: */
18:
19: #ifndef lint
20: static char rcsid[] = "$Header: /user6/ouster/wish/RCS/tkWindow.c,v 1.92 92/08/21 11:42:44 ouster Exp $ SPRITE (Berkeley)";
21: #endif
22:
23: #include "tkconfig.h"
24: #include "tkint.h"
25:
26: /*
27: * Global absolute file name:
28: */
29: char *TK_Library = TK_LIBRARY;
30:
31: /*
32: * Count of open displays.
33: */
34: int tk_Displays;
35:
36: /*
37: * Count of number of main windows currently open in this process.
38: */
39:
40: int tk_NumMainWindows;
41:
42: /*
43: * Added by dhopkins for OLPC Micropolis gtk.Socket integration.
44: */
45:
46: Window tk_RootWindow = 0;
47:
48: /*
49: * List of all displays currently in use.
50: */
51:
52: TkDisplay *tkDisplayList = NULL;
53:
54: /*
55: * Have statics in this module been initialized?
56: */
57:
58: static initialized = 0;
59:
60: /*
61: * Context information used to map from X window id's to
62: * TkWindow structures (during event handling, for example):
63: */
64:
65: XContext tkWindowContext;
66:
67: /*
68: * The variables below hold several uid's that are used in many places
69: * in the toolkit.
70: */
71:
72: Tk_Uid tkDisabledUid = NULL;
73: Tk_Uid tkActiveUid = NULL;
74: Tk_Uid tkNormalUid = NULL;
75:
76: /*
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.
80: */
81:
82: static XWindowChanges defChanges = {
83: 0, 0, 1, 1, 0, 0, Above
84: };
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 */
94: 0, /* border_pixel */
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 */
105: None /* cursor */
106: };
107:
108: /*
109: * The following structure defines all of the commands supported by
110: * Tk, and the C procedures that execute them.
111: */
112:
113: typedef struct {
114: char *name; /* Name of command. */
115: int (*cmdProc) _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp,
116: int argc, char **argv));
117: /* Command procedure. */
118: } TkCmd;
119:
120: TkCmd commands[] = {
121: /*
122: * Commands that are part of the intrinsics:
123: */
124:
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: {"wm", Tk_WmCmd},
138: {"accept", Tcp_AcceptCmd},
139: {"shutdown", Tcp_ShutdownCmd},
140: {"connect", Tcp_ConnectCmd},
141: {"filehandler", Tcp_FileHandlerCmd},
142:
143: /*
144: * Widget-creation commands.
145: */
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}
162: };
163:
164: /*
165: * Forward declarations to procedures defined later in this file:
166: */
167:
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,
175: char *name));
176: static TkWindow * NewWindow _ANSI_ARGS_((TkDisplay *dispPtr,
177: int screenNum));
178:
179: /*
180: *----------------------------------------------------------------------
181: *
182: * CreateTopLevelWindow --
183: *
184: * Make a new window that will be at top-level (its parent will
185: * be the root window of a screen).
186: *
187: * Results:
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
191: * interp->result.
192: *
193: * Side effects:
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.
197: *
198: *----------------------------------------------------------------------
199: */
200:
201: static Tk_Window
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
206: * be NULL. */
207: char *name; /* Name for new window; if parent is
208: * non-NULL, must be unique among parent's
209: * children. */
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
214: * parent. */
215: {
216: register TkWindow *winPtr;
217: register TkDisplay *dispPtr;
218: int screenId;
219:
220: if (!initialized) {
221: initialized = 1;
222: tkWindowContext = XUniqueContext();
223: tkActiveUid = Tk_GetUid("active");
224: tkDisabledUid = Tk_GetUid("disabled");
225: tkNormalUid = Tk_GetUid("normal");
226: }
227:
228: if ((parent != NULL) && (screenName != NULL) && (screenName[0] == '\0')) {
229: dispPtr = ((TkWindow *) parent)->dispPtr;
230: screenId = Tk_ScreenNumber(parent);
231: } else {
232: dispPtr = GetScreen(interp, screenName, &screenId);
233: if (dispPtr == NULL) {
234: return (Tk_Window) NULL;
235: }
236: }
237:
238: winPtr = NewWindow(dispPtr, screenId);
239:
240: /*
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.
245: */
246:
247: winPtr->atts.event_mask |= StructureNotifyMask;
248:
249: /*
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
252: * has been set.)
253: */
254:
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;
260: }
261: }
262: TkWmNewWindow(winPtr);
263: return (Tk_Window) winPtr;
264: }
265:
266: /*
267: *----------------------------------------------------------------------
268: *
269: * GetScreen --
270: *
271: * Given a string name for a display-plus-screen, find the
272: * TkDisplay structure for the display and return the screen
273: * number too.
274: *
275: * Results:
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
280: * screenName.
281: *
282: * Side effects:
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.
286: *
287: *----------------------------------------------------------------------
288: */
289:
290: static TkDisplay *
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. */
296: {
297: register TkDisplay *dispPtr;
298: char *p;
299: int length, screenId;
300:
301: /*
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
305: * optional.
306: */
307:
308: if ((screenName == NULL) || (screenName[0] == '\0')) {
309: screenName = getenv("DISPLAY");
310: if (screenName == NULL) {
311: interp->result =
312: "no display name and no $DISPLAY environment variable";
313: return (TkDisplay *) NULL;
314: }
315: }
316: length = strlen(screenName);
317: screenId = 0;
318: p = screenName+length-1;
319: while (isdigit(*p) && (p != screenName)) {
320: p--;
321: }
322: if ((*p == '.') && (p[1] != '\0')) {
323: length = p - screenName;
324: screenId = strtoul(p+1, (char **) NULL, 10);
325: }
326:
327: /*
328: * See if we already have a connection to this display. If not,
329: * then open a new connection.
330: */
331:
332: for (dispPtr = tkDisplayList; ; dispPtr = dispPtr->nextPtr) {
333: if (dispPtr == NULL) {
334: Display *display = NULL;
335:
336: display = XOpenDisplay(screenName);
337:
338: if (display == NULL) {
339: Tcl_AppendResult(interp, "couldn't connect to display \"",
340: screenName, "\"", (char *) NULL);
341: return (TkDisplay *) NULL;
342: }
343: if (getenv("XSYNCHRONIZE") != NULL) {
344: XSynchronize(display, 1);
345: }
346: tk_Displays++;
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->cursorFont = None;
364: dispPtr->grabWinPtr = NULL;
365: dispPtr->ungrabWinPtr = NULL;
366: dispPtr->buttonWinPtr = NULL;
367: dispPtr->pointerWinPtr = NULL;
368: dispPtr->serverWinPtr = NULL;
369: dispPtr->grabFlags = 0;
370: dispPtr->focusPtr = NULL;
371: tkDisplayList = dispPtr;
372: Tk_CreateFileHandler(ConnectionNumber(display),
373: TK_READABLE, (void (*)()) NULL,
374: (ClientData) display);
375: break;
376: }
377: if ((strncmp(dispPtr->name, screenName, length) == 0)
378: && (dispPtr->name[length] == '\0')) {
379: break;
380: }
381: }
382: if (screenId >= ScreenCount(dispPtr->display)) {
383: sprintf(interp->result, "bad screen number \"%d\"", screenId);
384: return (TkDisplay *) NULL;
385: }
386: *screenPtr = screenId;
387: return dispPtr;
388: }
389:
390: /*
391: *--------------------------------------------------------------
392: *
393: * NewWindow --
394: *
395: * This procedure creates and initializes a TkWindow structure.
396: *
397: * Results:
398: * The return value is a pointer to the new window.
399: *
400: * Side effects:
401: * A new window structure is allocated and all its fields are
402: * initialized.
403: *
404: *--------------------------------------------------------------
405: */
406:
407: static TkWindow *
408: NewWindow(dispPtr, screenNum)
409: TkDisplay *dispPtr; /* Display associated with new window. */
410: int screenNum; /* Index of screen for new window. */
411: {
412: register TkWindow *winPtr;
413:
414: winPtr = (TkWindow *) ckalloc(sizeof(TkWindow));
415: winPtr->display = dispPtr->display;
416: winPtr->dispPtr = dispPtr;
417: winPtr->screenNum = screenNum;
418: winPtr->window = None;
419: winPtr->childList = NULL;
420: winPtr->parentPtr = NULL;
421: winPtr->nextPtr = NULL;
422: winPtr->mainPtr = NULL;
423: winPtr->pathName = NULL;
424: winPtr->nameUid = NULL;
425: winPtr->classUid = NULL;
426: winPtr->changes = defChanges;
427: winPtr->dirtyChanges = CWX|CWY|CWWidth|CWHeight|CWBorderWidth;
428: winPtr->atts = defAtts;
429: winPtr->dirtyAtts = CWEventMask;
430: winPtr->flags = 0;
431: winPtr->handlerList = NULL;
432: winPtr->focusProc = NULL;
433: winPtr->focusData = NULL;
434: winPtr->optionLevel = -1;
435: winPtr->selHandlerList = NULL;
436: winPtr->selClearProc = NULL;
437: winPtr->selClearData = NULL;
438: winPtr->geomProc = NULL;
439: winPtr->geomData = NULL;
440: winPtr->reqWidth = winPtr->reqHeight = 0;
441: winPtr->internalBorderWidth = 0;
442: winPtr->wmInfoPtr = NULL;
443: return winPtr;
444: }
445:
446: /*
447: *----------------------------------------------------------------------
448: *
449: * NameWindow --
450: *
451: * This procedure is invoked to give a window a name and insert
452: * the window into the hierarchy associated with a particular
453: * application.
454: *
455: * Results:
456: * A standard Tcl return value.
457: *
458: * Side effects:
459: * See above.
460: *
461: *----------------------------------------------------------------------
462: */
463:
464: static int
465: NameWindow(interp, winPtr, parentPtr, name)
466: Tcl_Interp *interp; /* Interpreter to use for error reporting. */
467: register TkWindow *winPtr; /* Window that is to be named and inserted. */
468: TkWindow *parentPtr; /* Pointer to logical parent for winPtr
469: * (used for naming, options, etc.). */
470: char *name; /* Name for winPtr; must be unique among
471: * parentPtr's children. */
472: {
473: #define FIXED_SIZE 200
474: char staticSpace[FIXED_SIZE];
475: char *pathName;
476: int new;
477: Tcl_HashEntry *hPtr;
478: int length1, length2;
479:
480: /*
481: * Setup all the stuff except name right away, then do the name stuff
482: * last. This is so that if the name stuff fails, everything else
483: * will be properly initialized (needed to destroy the window cleanly
484: * after the naming failure).
485: */
486: winPtr->parentPtr = parentPtr;
487: winPtr->nextPtr = parentPtr->childList;
488: parentPtr->childList = winPtr;
489: winPtr->mainPtr = parentPtr->mainPtr;
490: winPtr->nameUid = Tk_GetUid(name);
491:
492: /*
493: * To permit names of arbitrary length, must be prepared to malloc
494: * a buffer to hold the new path name. To run fast in the common
495: * case where names are short, use a fixed-size buffer on the
496: * stack.
497: */
498:
499: length1 = strlen(parentPtr->pathName);
500: length2 = strlen(name);
501: if ((length1+length2+2) <= FIXED_SIZE) {
502: pathName = staticSpace;
503: } else {
504: pathName = (char *) ckalloc((unsigned) (length1+length2+2));
505: }
506: if (length1 == 1) {
507: pathName[0] = '.';
508: strcpy(pathName+1, name);
509: } else {
510: strcpy(pathName, parentPtr->pathName);
511: pathName[length1] = '.';
512: strcpy(pathName+length1+1, name);
513: }
514: hPtr = Tcl_CreateHashEntry(&parentPtr->mainPtr->nameTable, pathName, &new);
515: if (pathName != staticSpace) {
516: ckfree(pathName);
517: }
518: if (!new) {
519: Tcl_AppendResult(interp, "window name \"", name,
520: "\" already exists in parent", (char *) NULL);
521: return TCL_ERROR;
522: }
523: Tcl_SetHashValue(hPtr, winPtr);
524: winPtr->pathName = Tcl_GetHashKey(&parentPtr->mainPtr->nameTable, hPtr);
525: return TCL_OK;
526: }
527:
528: /*
529: *----------------------------------------------------------------------
530: *
531: * Tk_CreateMainWindow --
532: *
533: * Make a new main window. A main window is a special kind of
534: * top-level window used as the outermost window in an
535: * application.
536: *
537: * Results:
538: * The return value is a token for the new window, or NULL if
539: * an error prevented the new window from being created. If
540: * NULL is returned, an error message will be left in
541: * interp->result.
542: *
543: * Side effects:
544: * A new window structure is allocated locally; "interp" is
545: * associated with the window and registered for "send" commands
546: * under "baseName". BaseName may be extended with an instance
547: * number in the form "#2" if necessary to make it globally
548: * unique. Tk-related commands are bound into interp. An X
549: * window is NOT initially created, but will be created the
550: * first time the window is mapped.
551: *
552: *----------------------------------------------------------------------
553: */
554:
555: Tk_Window
556: Tk_CreateMainWindow(interp, screenName, baseName)
557: Tcl_Interp *interp; /* Interpreter to use for error reporting. */
558: char *screenName; /* Name of screen on which to create
559: * window. Empty or NULL string means
560: * use DISPLAY environment variable. */
561: char *baseName; /* Base name for application; usually of the
562: * form "prog instance". */
563: {
564: Tk_Window tkwin;
565: int result, dummy;
566: Tcl_HashEntry *hPtr;
567: register TkMainInfo *mainPtr;
568: register TkWindow *winPtr;
569: register TkCmd *cmdPtr;
570:
571: /*
572: * Create the basic TkWindow structure.
573: */
574:
575: tkwin = CreateTopLevelWindow(interp, (Tk_Window) NULL, baseName,
576: screenName);
577: if (tkwin == NULL) {
578: return NULL;
579: }
580:
581: /*
582: * Create the TkMainInfo structure for this application, and set
583: * up name-related information for the new window.
584: */
585:
586: winPtr = (TkWindow *) tkwin;
587: mainPtr = (TkMainInfo *) ckalloc(sizeof(TkMainInfo));
588: mainPtr->winPtr = winPtr;
589: mainPtr->interp = interp;
590: Tcl_InitHashTable(&mainPtr->nameTable, TCL_STRING_KEYS);
591: mainPtr->bindingTable = Tk_CreateBindingTable(interp);
592: /* XXX: FOCUS */
593: /* mainPtr->focusPtr = NULL; */
594: mainPtr->optionRootPtr = NULL;
595: winPtr->mainPtr = mainPtr;
596: hPtr = Tcl_CreateHashEntry(&mainPtr->nameTable, ".", &dummy);
597: Tcl_SetHashValue(hPtr, winPtr);
598: winPtr->pathName = Tcl_GetHashKey(&mainPtr->nameTable, hPtr);
599:
600: /*
601: * Register the interpreter for "send" purposes. If baseName isn't
602: * already unique, find a unique suffix to add to it to make it
603: * unique. Change the window's name to contain the suffix.
604: */
605:
606: result = Tk_RegisterInterp(interp, baseName, tkwin);
607: if (result == TCL_OK) {
608: winPtr->nameUid = Tk_GetUid(baseName);
609: } else {
610: char newName[110];
611: int i;
612:
613: for (i = 2; ; i++) {
614: sprintf(newName, "%.100s #%d", baseName, i);
615: Tcl_SetResult(interp, (char *) NULL, TCL_STATIC);
616: result = Tk_RegisterInterp(interp, newName, tkwin);
617: if (result == TCL_OK) {
618: break;
619: }
620: if (i >= 100) {
621: Tcl_SetResult(interp,
622: "couldn't generate unique name to register application",
623: TCL_STATIC);
624: Tk_DestroyWindow(tkwin);
625: }
626: }
627: winPtr->nameUid = Tk_GetUid(newName);
628: }
629:
630: /*
631: * Bind in Tk's commands.
632: */
633:
634: for (cmdPtr = commands; cmdPtr->name != NULL; cmdPtr++) {
635: Tcl_CreateCommand(interp, cmdPtr->name, cmdPtr->cmdProc,
636: (ClientData) tkwin, (void (*)()) NULL);
637: }
638:
639: /*
640: * Set variables for the intepreter.
641: */
642:
643: Tcl_SetVar(interp, "tk_library", TK_Library, TCL_GLOBAL_ONLY);
644: Tcl_SetVar(interp, "tk_version", TK_VERSION, TCL_GLOBAL_ONLY);
645: Tcl_SetVar(interp, "tkVersion", TK_VERSION, TCL_GLOBAL_ONLY);
646:
647: tk_NumMainWindows++;
648: return tkwin;
649: }
650:
651: /*
652: *--------------------------------------------------------------
653: *
654: * Tk_CreateWindow --
655: *
656: * Create a new internal or top-level window as a child of an
657: * existing window.
658: *
659: * Results:
660: * The return value is a token for the new window. This
661: * is not the same as X's token for the window. If an error
662: * occurred in creating the window (e.g. no such display or
663: * screen), then an error message is left in interp->result and
664: * NULL is returned.
665: *
666: * Side effects:
667: * A new window structure is allocated locally. An X
668: * window is not initially created, but will be created
669: * the first time the window is mapped.
670: *
671: *--------------------------------------------------------------
672: */
673:
674: Tk_Window
675: Tk_CreateWindow(interp, parent, name, screenName)
676: Tcl_Interp *interp; /* Interpreter to use for error reporting.
677: * Interp->result is assumed to be
678: * initialized by the caller. */
679: Tk_Window parent; /* Token for parent of new window. */
680: char *name; /* Name for new window. Must be unique
681: * among parent's children. */
682: char *screenName; /* If NULL, new window will be internal on
683: * same screen as its parent. If non-NULL,
684: * gives name of screen on which to create
685: * new window; window will be a top-level
686: * window. */
687: {
688: TkWindow *parentPtr = (TkWindow *) parent;
689: TkWindow *winPtr;
690:
691: if (screenName == NULL) {
692: winPtr = NewWindow(parentPtr->dispPtr, parentPtr->screenNum);
693: if (NameWindow(interp, winPtr, parentPtr, name) != TCL_OK) {
694: Tk_DestroyWindow((Tk_Window) winPtr);
695: return NULL;
696: } else {
697: return (Tk_Window) winPtr;
698: }
699: } else {
700: /*
701: * This is a fix for dvx XOpenDisplay... display name conformalization
702: * bugs...
703: */
704: char dsp[256];
705: int len;
706:
707: strcpy(dsp, screenName);
708: len = strlen(dsp);
709: if (len && (dsp[len -1] == '.'))
710: dsp[len -1] = '\0';
711:
712: return CreateTopLevelWindow(interp, parent, name, dsp);
713: }
714: }
715:
716: /*
717: *----------------------------------------------------------------------
718: *
719: * Tk_CreateWindowFromPath --
720: *
721: * This procedure is similar to Tk_CreateInternalWindow except
722: * that it uses a path name to create the window, rather than
723: * a parent and a child name.
724: *
725: * Results:
726: * The return value is a token for the new window. This
727: * is not the same as X's token for the window. If an error
728: * occurred in creating the window (e.g. no such display or
729: * screen), then an error message is left in interp->result and
730: * NULL is returned.
731: *
732: * Side effects:
733: * A new window structure is allocated locally. An X
734: * window is not initially created, but will be created
735: * the first time the window is mapped.
736: *
737: *----------------------------------------------------------------------
738: */
739:
740: Tk_Window
741: Tk_CreateWindowFromPath(interp, tkwin, pathName, screenName)
742: Tcl_Interp *interp; /* Interpreter to use for error reporting.
743: * Interp->result is assumed to be
744: * initialized by the caller. */
745: Tk_Window tkwin; /* Token for any window in application
746: * that is to contain new window. */
747: char *pathName; /* Path name for new window within the
748: * application of tkwin. The parent of
749: * this window must already exist, but
750: * the window itself must not exist. */
751: char *screenName; /* If NULL, new window will be on same
752: * screen as its parent. If non-NULL,
753: * gives name of screen on which to create
754: * new window; window will be a top-level
755: * window. */
756: {
757: #define FIXED_SPACE 5
758: char fixedSpace[FIXED_SPACE+1];
759: char *p;
760: Tk_Window parent;
761: int numChars;
762:
763: /*
764: * Strip the parent's name out of pathName (it's everything up
765: * to the last dot). There are two tricky parts: (a) must
766: * copy the parent's name somewhere else to avoid modifying
767: * the pathName string (for large names, space for the copy
768: * will have to be malloc'ed); (b) must special-case the
769: * situation where the parent is ".".
770: */
771:
772: p = strrchr(pathName, '.');
773: if (p == NULL) {
774: Tcl_AppendResult(interp, "bad window path name \"", pathName,
775: "\"", (char *) NULL);
776: return NULL;
777: }
778: numChars = p-pathName;
779: if (numChars > FIXED_SPACE) {
780: p = (char *) ckalloc((unsigned) (numChars+1));
781: } else {
782: p = fixedSpace;
783: }
784: if (numChars == 0) {
785: *p = '.';
786: p[1] = '\0';
787: } else {
788: strncpy(p, pathName, numChars);
789: p[numChars] = '\0';
790: }
791:
792: /*
793: * Find the parent window.
794: */
795:
796: parent = Tk_NameToWindow(interp, p, tkwin);
797: if (p != fixedSpace) {
798: ckfree(p);
799: }
800: if (parent == NULL) {
801: return NULL;
802: }
803:
804: /*
805: * Create the window.
806: */
807:
808: if (screenName == NULL) {
809: TkWindow *parentPtr = (TkWindow *) parent;
810: TkWindow *winPtr;
811:
812: winPtr = NewWindow(parentPtr->dispPtr, parentPtr->screenNum);
813: if (NameWindow(interp, winPtr, parentPtr, pathName+numChars+1)
814: != TCL_OK) {
815: Tk_DestroyWindow((Tk_Window) winPtr);
816: return NULL;
817: } else {
818: return (Tk_Window) winPtr;
819: }
820: } else {
821: return CreateTopLevelWindow(interp, parent, pathName+numChars+1,
822: screenName);
823: }
824: }
825:
826: /*
827: *--------------------------------------------------------------
828: *
829: * Tk_DestroyWindow --
830: *
831: * Destroy an existing window. After this call, the caller
832: * should never again use the token.
833: *
834: * Results:
835: * None.
836: *
837: * Side effects:
838: * The window is deleted, along with all of its children.
839: * Relevant callback procedures are invoked.
840: *
841: *--------------------------------------------------------------
842: */
843:
844: void
845: Tk_DestroyWindow(tkwin)
846: Tk_Window tkwin; /* Window to destroy. */
847: {
848: register TkWindow *winPtr = (TkWindow *) tkwin;
849: XEvent event;
850:
851: /*
852: * Recursively destroy children. The TK_RECURSIVE_DESTROY
853: * flags means that the child's window needn't be explicitly
854: * destroyed (the destroy of the parent already did it), nor
855: * does it need to be removed from its parent's child list,
856: * since the parent is being destroyed too.
857: */
858:
859: while (winPtr->childList != NULL) {
860: winPtr->childList->flags |= TK_RECURSIVE_DESTROY;
861: Tk_DestroyWindow((Tk_Window) winPtr->childList);
862: }
863:
864: /*
865: * Generate a DestroyNotify event. In order for the DestroyNotify
866: * event to be processed correctly, need to make sure the window
867: * exists. This is a bit of a kludge, and may be unnecessarily
868: * expensive, but without it no event handlers will get called for
869: * windows that don't exist yet.
870: */
871:
872: if (winPtr->window == None) {
873: Tk_MakeWindowExist(tkwin);
874: }
875: winPtr->flags |= TK_ALREADY_DEAD;
876: event.type = DestroyNotify;
877: event.xdestroywindow.serial =
878: LastKnownRequestProcessed(winPtr->display);
879: event.xdestroywindow.send_event = False;
880: event.xdestroywindow.display = winPtr->display;
881: event.xdestroywindow.event = winPtr->window;
882: event.xdestroywindow.window = winPtr->window;
883: Tk_HandleEvent(&event);
884:
885: /*
886: * Cleanup the data structures associated with this window.
887: * No need to destroy windows during recursive destroys, since
888: * that will happen automatically when the parent window is
889: * destroyed (not true for top-level windows: must destroy
890: * them explicitly).
891: */
892:
893: if (winPtr->window != None) {
894: if (!(winPtr->flags & TK_RECURSIVE_DESTROY)
895: || (winPtr->flags & TK_TOP_LEVEL)) {
896: XDestroyWindow(winPtr->display, winPtr->window);
897: }
898: XDeleteContext(winPtr->display, winPtr->window, tkWindowContext);
899: winPtr->window = None;
900: }
901: if (winPtr->parentPtr != NULL) {
902: if (winPtr->parentPtr->childList == winPtr) {
903: winPtr->parentPtr->childList = winPtr->nextPtr;
904: } else {
905: register TkWindow *winPtr2;
906:
907: for (winPtr2 = winPtr->parentPtr->childList; ;
908: winPtr2 = winPtr2->nextPtr) {
909: if (winPtr2 == NULL) {
910: panic("Tk_DestroyWindow couldn't find child in parent (deleted twice?)");
911: break;
912: }
913: if (winPtr2->nextPtr == winPtr) {
914: winPtr2->nextPtr = winPtr->nextPtr;
915: break;
916: }
917: }
918: }
919: }
920: TkEventDeadWindow(winPtr);
921: TkOptionDeadWindow(winPtr);
922: TkSelDeadWindow(winPtr);
923: if (winPtr->flags & TK_TOP_LEVEL) {
924: TkWmDeadWindow(winPtr);
925: }
926: TkGrabDeadWindow(winPtr);
927: if (winPtr->mainPtr != NULL) {
928: Tk_DeleteAllBindings(winPtr->mainPtr->bindingTable,
929: (ClientData) winPtr->pathName);
930: if (winPtr->pathName != NULL) {
931: Tcl_DeleteHashEntry(Tcl_FindHashEntry(&winPtr->mainPtr->nameTable,
932: winPtr->pathName));
933: }
934: if (winPtr->mainPtr->winPtr == winPtr) {
935: register TkCmd *cmdPtr;
936:
937: /*
938: * Deleting a main window. Delete the TkMainInfo structure too
939: * and replace all of Tk's commands with dummy commands that
940: * return errors. Also delete the "send" command to unregister
941: * the interpreter.
942: */
943:
944: for (cmdPtr = commands; cmdPtr->name != NULL; cmdPtr++) {
945: Tcl_CreateCommand(winPtr->mainPtr->interp, cmdPtr->name,
946: TkDeadAppCmd, (ClientData) NULL, (void (*)()) NULL);
947: }
948: Tcl_CreateCommand(winPtr->mainPtr->interp, "send",
949: TkDeadAppCmd, (ClientData) NULL, (void (*)()) NULL);
950: Tcl_DeleteHashTable(&winPtr->mainPtr->nameTable);
951: Tk_DeleteBindingTable(winPtr->mainPtr->bindingTable);
952: ckfree((char *) winPtr->mainPtr);
953: tk_NumMainWindows--;
954: }
955: }
956: ckfree((char *) winPtr);
957: }
958:
959: /*
960: *--------------------------------------------------------------
961: *
962: * Tk_MapWindow --
963: *
964: * Map a window within its parent. This may require the
965: * window and/or its parents to actually be created.
966: *
967: * Results:
968: * None.
969: *
970: * Side effects:
971: * The given window will be mapped. Windows may also
972: * be created.
973: *
974: *--------------------------------------------------------------
975: */
976:
977: void
978: Tk_MapWindow(tkwin)
979: Tk_Window tkwin; /* Token for window to map. */
980: {
981: register TkWindow *winPtr = (TkWindow *) tkwin;
982:
983: if (winPtr->flags & TK_MAPPED) {
984: return;
985: }
986: if (winPtr->window == None) {
987: Tk_MakeWindowExist(tkwin);
988: }
989: if (winPtr->flags & TK_TOP_LEVEL) {
990: if (!TkWmMapWindow(winPtr)) {
991: return;
992: }
993: } else {
994: /*
995: * Don't set the mapped flag for top-level windows: TkWmMapWindow
996: * does it if appropriate (e.g. if the window is going to be non-
997: * iconic).
998: */
999:
1000: winPtr->flags |= TK_MAPPED;
1001: }
1002: XMapWindow(winPtr->display, winPtr->window);
1003: if (!(winPtr->flags & TK_TOP_LEVEL)) {
1004: XEvent event;
1005:
1006: event.type = MapNotify;
1007: event.xmap.serial = LastKnownRequestProcessed(winPtr->display);
1008: event.xmap.send_event = False;
1009: event.xmap.display = winPtr->display;
1010: event.xmap.event = winPtr->window;
1011: event.xmap.window = winPtr->window;
1012: event.xmap.override_redirect = winPtr->atts.override_redirect;
1013: Tk_HandleEvent(&event);
1014: }
1015: }
1016:
1017: /*
1018: *--------------------------------------------------------------
1019: *
1020: * Tk_MakeWindowExist --
1021: *
1022: * Ensure that a particular window actually exists. This
1023: * procedure shouldn't normally need to be invoked from
1024: * outside the Tk package, but may be needed if someone
1025: * wants to manipulate a window before mapping it.
1026: *
1027: * Results:
1028: * None.
1029: *
1030: * Side effects:
1031: * When the procedure returns, the X window associated with
1032: * tkwin is guaranteed to exist. This may require the
1033: * window's ancestors to be created also.
1034: *
1035: *--------------------------------------------------------------
1036: */
1037:
1038: void
1039: Tk_MakeWindowExist(tkwin)
1040: Tk_Window tkwin; /* Token for window. */
1041: {
1042: register TkWindow *winPtr = (TkWindow *) tkwin;
1043: Window parent;
1044:
1045: if (winPtr->window != None) {
1046: return;
1047: }
1048:
1049: if (winPtr->flags & TK_TOP_LEVEL) {
1050: /*
1051: * workaround by dhopkins for OLPC Micropolis gtk.Socket integration.
1052: */
1053:
1054: if (tk_RootWindow) {
1055: parent =
1056: tk_RootWindow;
1057: } else {
1058: parent =
1059: XRootWindow(winPtr->display, winPtr->screenNum);
1060: }
1061:
1062: } else {
1063: if (winPtr->parentPtr->window == None) {
1064: Tk_MakeWindowExist((Tk_Window) winPtr->parentPtr);
1065: }
1066: parent = winPtr->parentPtr->window;
1067: }
1068:
1069: /* workaround to support non-default colormaps */
1070: #if 0
1071: winPtr->window = XCreateWindow(winPtr->display, parent,
1072: winPtr->changes.x, winPtr->changes.y,
1073: winPtr->changes.width, winPtr->changes.height,
1074: winPtr->changes.border_width, CopyFromParent,
1075: InputOutput, CopyFromParent, winPtr->dirtyAtts,
1076: &winPtr->atts);
1077: #else
1078: { Screen *scr = ScreenOfDisplay(winPtr->display, winPtr->screenNum);
1079:
1080: winPtr->dirtyAtts |= CWColormap | CWBorderPixmap;
1081: winPtr->atts.colormap = Tk_DefaultColormap(scr);
1082: winPtr->atts.border_pixmap = Tk_DefaultPixmap(scr);
1083:
1084: winPtr->window = XCreateWindow(winPtr->display, parent,
1085: winPtr->changes.x, winPtr->changes.y,
1086: winPtr->changes.width, winPtr->changes.height,
1087: winPtr->changes.border_width,
1088: Tk_DefaultDepth(scr),
1089: InputOutput,
1090: Tk_DefaultVisual(scr),
1091: winPtr->dirtyAtts, &winPtr->atts);
1092: }
1093: #endif
1094:
1095: XSaveContext(winPtr->display, winPtr->window, tkWindowContext,
1096: (void *) winPtr);
1097: winPtr->dirtyAtts = 0;
1098: winPtr->dirtyChanges &= ~(CWX|CWY|CWWidth|CWHeight|CWBorderWidth);
1099: if (winPtr->dirtyChanges != 0) {
1100: XConfigureWindow(winPtr->display, winPtr->window,
1101: winPtr->dirtyChanges, &winPtr->changes);
1102: winPtr->dirtyChanges = 0;
1103: }
1104:
1105: /*
1106: * Issue a ConfigureNotify event if there were deferred configuration
1107: * changes.
1108: */
1109:
1110: if (winPtr->flags & TK_NEED_CONFIG_NOTIFY) {
1111: winPtr->flags &= ~TK_NEED_CONFIG_NOTIFY;
1112: DoConfigureNotify(winPtr);
1113: }
1114: }
1115:
1116: /*
1117: *--------------------------------------------------------------
1118: *
1119: * Tk_UnmapWindow, etc. --
1120: *
1121: * There are several procedures under here, each of which
1122: * mirrors an existing X procedure. In addition to performing
1123: * the functions of the corresponding procedure, each
1124: * procedure also updates the local window structure and
1125: * synthesizes an X event (if the window's structure is being
1126: * managed internally).
1127: *
1128: * Results:
1129: * See the manual entries.
1130: *
1131: * Side effects:
1132: * See the manual entries.
1133: *
1134: *--------------------------------------------------------------
1135: */
1136:
1137: void
1138: Tk_UnmapWindow(tkwin)
1139: Tk_Window tkwin; /* Token for window to unmap. */
1140: {
1141: register TkWindow *winPtr = (TkWindow *) tkwin;
1142:
1143: if (!(winPtr->flags & TK_MAPPED)) {
1144: return;
1145: }
1146: winPtr->flags &= ~TK_MAPPED;
1147: XUnmapWindow(winPtr->display, winPtr->window);
1148: if (!(winPtr->flags & TK_TOP_LEVEL)) {
1149: XEvent event;
1150:
1151: event.type = UnmapNotify;
1152: event.xunmap.serial = LastKnownRequestProcessed(winPtr->display);
1153: event.xunmap.send_event = False;
1154: event.xunmap.display = winPtr->display;
1155: event.xunmap.event = winPtr->window;
1156: event.xunmap.window = winPtr->window;
1157: event.xunmap.from_configure = False;
1158: Tk_HandleEvent(&event);
1159: }
1160: }
1161:
1162: void
1163: Tk_ConfigureWindow(tkwin, valueMask, valuePtr)
1164: Tk_Window tkwin; /* Window to re-configure. */
1165: unsigned int valueMask; /* Mask indicating which parts of
1166: * *valuePtr are to be used. */
1167: XWindowChanges *valuePtr; /* New values. */
1168: {
1169: register TkWindow *winPtr = (TkWindow *) tkwin;
1170:
1171: if ((winPtr->window == None) || !(winPtr->flags & TK_TOP_LEVEL)) {
1172: if (valueMask & CWX) {
1173: winPtr->changes.x = valuePtr->x;
1174: }
1175: if (valueMask & CWY) {
1176: winPtr->changes.y = valuePtr->y;
1177: }
1178: if (valueMask & CWWidth) {
1179: winPtr->changes.width = valuePtr->width;
1180: }
1181: if (valueMask & CWHeight) {
1182: winPtr->changes.height = valuePtr->height;
1183: }
1184: if (valueMask & CWBorderWidth) {
1185: winPtr->changes.border_width = valuePtr->border_width;
1186: }
1187: if (valueMask & CWSibling) {
1188: winPtr->changes.sibling = valuePtr->sibling;
1189: }
1190: if (valueMask & CWStackMode) {
1191: winPtr->changes.stack_mode = valuePtr->stack_mode;
1192: }
1193: }
1194:
1195: if (winPtr->window != None) {
1196: XConfigureWindow(winPtr->display, winPtr->window,
1197: valueMask, valuePtr);
1198: if (!(winPtr->flags & TK_TOP_LEVEL)) {
1199: DoConfigureNotify(winPtr);
1200: }
1201: } else {
1202: winPtr->dirtyChanges |= valueMask;
1203: winPtr->flags |= TK_NEED_CONFIG_NOTIFY;
1204: }
1205: }
1206:
1207: void
1208: Tk_MoveWindow(tkwin, x, y)
1209: Tk_Window tkwin; /* Window to move. */
1210: int x, y; /* New location for window (within
1211: * parent). */
1212: {
1213: register TkWindow *winPtr = (TkWindow *) tkwin;
1214:
1215: if (winPtr->window != None) {
1216: XMoveWindow(winPtr->display, winPtr->window, x, y);
1217: if (!(winPtr->flags & TK_TOP_LEVEL)) {
1218: winPtr->changes.x = x;
1219: winPtr->changes.y = y;
1220: DoConfigureNotify(winPtr);
1221: }
1222: } else {
1223: winPtr->changes.x = x;
1224: winPtr->changes.y = y;
1225: winPtr->dirtyChanges |= CWX|CWY;
1226: winPtr->flags |= TK_NEED_CONFIG_NOTIFY;
1227: }
1228: }
1229:
1230: void
1231: Tk_ResizeWindow(tkwin, width, height)
1232: Tk_Window tkwin; /* Window to resize. */
1233: unsigned int width, height; /* New dimensions for window. */
1234: {
1235: register TkWindow *winPtr = (TkWindow *) tkwin;
1236:
1237: if (winPtr->window != None) {
1238: XResizeWindow(winPtr->display, winPtr->window, width, height);
1239: if (!(winPtr->flags & TK_TOP_LEVEL)) {
1240: winPtr->changes.width = width;
1241: winPtr->changes.height = height;
1242: DoConfigureNotify(winPtr);
1243: }
1244: } else {
1245: winPtr->changes.width = width;
1246: winPtr->changes.height = height;
1247: winPtr->dirtyChanges |= CWWidth|CWHeight;
1248: winPtr->flags |= TK_NEED_CONFIG_NOTIFY;
1249: }
1250: }
1251:
1252: void
1253: Tk_MoveResizeWindow(tkwin, x, y, width, height)
1254: Tk_Window tkwin; /* Window to move and resize. */
1255: int x, y; /* New location for window (within
1256: * parent). */
1257: unsigned int width, height; /* New dimensions for window. */
1258: {
1259: register TkWindow *winPtr = (TkWindow *) tkwin;
1260:
1261: if (winPtr->window != None) {
1262: XMoveResizeWindow(winPtr->display, winPtr->window,
1263: x, y, width, height);
1264: if (!(winPtr->flags & TK_TOP_LEVEL)) {
1265: winPtr->changes.x = x;
1266: winPtr->changes.y = y;
1267: winPtr->changes.width = width;
1268: winPtr->changes.height = height;
1269: DoConfigureNotify(winPtr);
1270: }
1271: } else {
1272: winPtr->changes.x = x;
1273: winPtr->changes.y = y;
1274: winPtr->changes.width = width;
1275: winPtr->changes.height = height;
1276: winPtr->dirtyChanges |= CWX|CWY|CWWidth|CWHeight;
1277: winPtr->flags |= TK_NEED_CONFIG_NOTIFY;
1278: }
1279: }
1280:
1281: void
1282: Tk_SetWindowBorderWidth(tkwin, width)
1283: Tk_Window tkwin; /* Window to modify. */
1284: int width; /* New border width for window. */
1285: {
1286: register TkWindow *winPtr = (TkWindow *) tkwin;
1287:
1288: winPtr->changes.border_width = width;
1289: if (winPtr->window != None) {
1290: XSetWindowBorderWidth(winPtr->display, winPtr->window, width);
1291: if (!(winPtr->flags & TK_TOP_LEVEL)) {
1292: DoConfigureNotify(winPtr);
1293: }
1294: } else {
1295: winPtr->dirtyChanges |= CWBorderWidth;
1296: winPtr->flags |= TK_NEED_CONFIG_NOTIFY;
1297: }
1298: }
1299:
1300: void
1301: Tk_ChangeWindowAttributes(tkwin, valueMask, attsPtr)
1302: Tk_Window tkwin; /* Window to manipulate. */
1303: unsigned long valueMask; /* OR'ed combination of bits,
1304: * indicating which fields of
1305: * *attsPtr are to be used. */
1306: register XSetWindowAttributes *attsPtr;
1307: /* New values for some attributes. */
1308: {
1309: register TkWindow *winPtr = (TkWindow *) tkwin;
1310:
1311: if (valueMask & CWBackPixmap) {
1312: winPtr->atts.background_pixmap = attsPtr->background_pixmap;
1313: }
1314: if (valueMask & CWBackPixel) {
1315: winPtr->atts.background_pixel = attsPtr->background_pixel;
1316: }
1317: if (valueMask & CWBorderPixmap) {
1318: winPtr->atts.border_pixmap = attsPtr->border_pixmap;
1319: }
1320: if (valueMask & CWBorderPixel) {
1321: winPtr->atts.border_pixel = attsPtr->border_pixel;
1322: }
1323: if (valueMask & CWBitGravity) {
1324: winPtr->atts.bit_gravity = attsPtr->bit_gravity;
1325: }
1326: if (valueMask & CWWinGravity) {
1327: winPtr->atts.win_gravity = attsPtr->win_gravity;
1328: }
1329: if (valueMask & CWBackingStore) {
1330: winPtr->atts.backing_store = attsPtr->backing_store;
1331: }
1332: if (valueMask & CWBackingPlanes) {
1333: winPtr->atts.backing_planes = attsPtr->backing_planes;
1334: }
1335: if (valueMask & CWBackingPixel) {
1336: winPtr->atts.backing_pixel = attsPtr->backing_pixel;
1337: }
1338: if (valueMask & CWOverrideRedirect) {
1339: winPtr->atts.override_redirect = attsPtr->override_redirect;
1340: }
1341: if (valueMask & CWSaveUnder) {
1342: winPtr->atts.save_under = attsPtr->save_under;
1343: }
1344: if (valueMask & CWEventMask) {
1345: winPtr->atts.event_mask = attsPtr->event_mask;
1346: }
1347: if (valueMask & CWDontPropagate) {
1348: winPtr->atts.do_not_propagate_mask
1349: = attsPtr->do_not_propagate_mask;
1350: }
1351: if (valueMask & CWColormap) {
1352: winPtr->atts.colormap = attsPtr->colormap;
1353: }
1354: if (valueMask & CWCursor) {
1355: winPtr->atts.cursor = attsPtr->cursor;
1356: }
1357:
1358: if (winPtr->window != None) {
1359: XChangeWindowAttributes(winPtr->display, winPtr->window,
1360: valueMask, attsPtr);
1361: } else {
1362: winPtr->dirtyAtts |= valueMask;
1363: }
1364: }
1365:
1366: void
1367: Tk_SetWindowBackground(tkwin, pixel)
1368: Tk_Window tkwin; /* Window to manipulate. */
1369: unsigned long pixel; /* Pixel value to use for
1370: * window's background. */
1371: {
1372: register TkWindow *winPtr = (TkWindow *) tkwin;
1373:
1374: winPtr->atts.background_pixel = pixel;
1375:
1376: if (winPtr->window != None) {
1377: XSetWindowBackground(winPtr->display, winPtr->window, pixel);
1378: } else {
1379: winPtr->dirtyAtts = (winPtr->dirtyAtts & ~CWBackPixmap)
1380: | CWBackPixel;
1381: }
1382: }
1383:
1384: void
1385: Tk_SetWindowBackgroundPixmap(tkwin, pixmap)
1386: Tk_Window tkwin; /* Window to manipulate. */
1387: Pixmap pixmap; /* Pixmap to use for window's
1388: * background. */
1389: {
1390: register TkWindow *winPtr = (TkWindow *) tkwin;
1391:
1392: winPtr->atts.background_pixmap = pixmap;
1393:
1394: if (winPtr->window != None) {
1395: XSetWindowBackgroundPixmap(winPtr->display,
1396: winPtr->window, pixmap);
1397: } else {
1398: winPtr->dirtyAtts = (winPtr->dirtyAtts & ~CWBackPixel)
1399: | CWBackPixmap;
1400: }
1401: }
1402:
1403: void
1404: Tk_SetWindowBorder(tkwin, pixel)
1405: Tk_Window tkwin; /* Window to manipulate. */
1406: unsigned long pixel; /* Pixel value to use for
1407: * window's border. */
1408: {
1409: register TkWindow *winPtr = (TkWindow *) tkwin;
1410:
1411: winPtr->atts.border_pixel = pixel;
1412:
1413: if (winPtr->window != None) {
1414: XSetWindowBorder(winPtr->display, winPtr->window, pixel);
1415: } else {
1416: winPtr->dirtyAtts = (winPtr->dirtyAtts & ~CWBorderPixmap)
1417: | CWBorderPixel;
1418: }
1419: }
1420:
1421: void
1422: Tk_SetWindowBorderPixmap(tkwin, pixmap)
1423: Tk_Window tkwin; /* Window to manipulate. */
1424: Pixmap pixmap; /* Pixmap to use for window's
1425: * border. */
1426: {
1427: register TkWindow *winPtr = (TkWindow *) tkwin;
1428:
1429: winPtr->atts.border_pixmap = pixmap;
1430:
1431: if (winPtr->window != None) {
1432: XSetWindowBorderPixmap(winPtr->display,
1433: winPtr->window, pixmap);
1434: } else {
1435: winPtr->dirtyAtts = (winPtr->dirtyAtts & ~CWBorderPixel)
1436: | CWBorderPixmap;
1437: }
1438: }
1439:
1440: void
1441: Tk_DefineCursor(tkwin, cursor)
1442: Tk_Window tkwin; /* Window to manipulate. */
1443: Cursor cursor; /* Cursor to use for window (may be None). */
1444: {
1445: register TkWindow *winPtr = (TkWindow *) tkwin;
1446:
1447: winPtr->atts.cursor = cursor;
1448:
1449: if (winPtr->window != None) {
1450: XDefineCursor(winPtr->display, winPtr->window, cursor);
1451: } else {
1452: winPtr->dirtyAtts = winPtr->dirtyAtts | CWCursor;
1453: }
1454: }
1455:
1456: void
1457: Tk_UndefineCursor(tkwin)
1458: Tk_Window tkwin; /* Window to manipulate. */
1459: {
1460: Tk_DefineCursor(tkwin, None);
1461: }
1462:
1463: /*
1464: *----------------------------------------------------------------------
1465: *
1466: * DoConfigureNotify --
1467: *
1468: * Generate a ConfigureNotify event describing the current
1469: * configuration of a window.
1470: *
1471: * Results:
1472: * None.
1473: *
1474: * Side effects:
1475: * An event is generated and processed by Tk_HandleEvent.
1476: *
1477: *----------------------------------------------------------------------
1478: */
1479:
1480: static void
1481: DoConfigureNotify(winPtr)
1482: register TkWindow *winPtr; /* Window whose configuration
1483: * was just changed. */
1484: {
1485: XEvent event;
1486:
1487: event.type = ConfigureNotify;
1488: event.xconfigure.serial = LastKnownRequestProcessed(winPtr->display);
1489: event.xconfigure.send_event = False;
1490: event.xconfigure.display = winPtr->display;
1491: event.xconfigure.event = winPtr->window;
1492: event.xconfigure.window = winPtr->window;
1493: event.xconfigure.x = winPtr->changes.x;
1494: event.xconfigure.y = winPtr->changes.y;
1495: event.xconfigure.width = winPtr->changes.width;
1496: event.xconfigure.height = winPtr->changes.height;
1497: event.xconfigure.border_width = winPtr->changes.border_width;
1498: if (winPtr->changes.stack_mode == Above) {
1499: event.xconfigure.above = winPtr->changes.sibling;
1500: } else {
1501: event.xconfigure.above = None;
1502: }
1503: event.xconfigure.override_redirect = winPtr->atts.override_redirect;
1504: Tk_HandleEvent(&event);
1505: }
1506:
1507: /*
1508: *----------------------------------------------------------------------
1509: *
1510: * Tk_SetClass --
1511: *
1512: * This procedure is used to give a window a class.
1513: *
1514: * Results:
1515: * None.
1516: *
1517: * Side effects:
1518: * A new class is stored for tkwin, replacing any existing
1519: * class for it.
1520: *
1521: *----------------------------------------------------------------------
1522: */
1523:
1524: void
1525: Tk_SetClass(tkwin, className)
1526: Tk_Window tkwin; /* Token for window to assign class. */
1527: char *className; /* New class for tkwin. */
1528: {
1529: register TkWindow *winPtr = (TkWindow *) tkwin;
1530:
1531: winPtr->classUid = Tk_GetUid(className);
1532: if (winPtr->flags & TK_TOP_LEVEL) {
1533: TkWmSetClass(winPtr);
1534: }
1535: }
1536:
1537: /*
1538: *----------------------------------------------------------------------
1539: *
1540: * Tk_NameToWindow --
1541: *
1542: * Given a string name for a window, this procedure
1543: * returns the token for the window, if there exists a
1544: * window corresponding to the given name.
1545: *
1546: * Results:
1547: * The return result is either a token for the window corresponding
1548: * to "name", or else NULL to indicate that there is no such
1549: * window. In this case, an error message is left in interp->result.
1550: *
1551: * Side effects:
1552: * None.
1553: *
1554: *----------------------------------------------------------------------
1555: */
1556:
1557: Tk_Window
1558: Tk_NameToWindow(interp, pathName, tkwin)
1559: Tcl_Interp *interp; /* Where to report errors. */
1560: char *pathName; /* Path name of window. */
1561: Tk_Window tkwin; /* Token for window: name is assumed to
1562: * belong to the same main window as tkwin. */
1563: {
1564: Tcl_HashEntry *hPtr;
1565:
1566: hPtr = Tcl_FindHashEntry(&((TkWindow *) tkwin)->mainPtr->nameTable,
1567: pathName);
1568: if (hPtr == NULL) {
1569: Tcl_AppendResult(interp, "bad window path name \"",
1570: pathName, "\"", (char *) NULL);
1571: return NULL;
1572: }
1573: return (Tk_Window) Tcl_GetHashValue(hPtr);
1574: }
1575:
1576: /*
1577: *----------------------------------------------------------------------
1578: *
1579: * Tk_DisplayName --
1580: *
1581: * Return the textual name of a window's display.
1582: *
1583: * Results:
1584: * The return value is the string name of the display associated
1585: * with tkwin.
1586: *
1587: * Side effects:
1588: * None.
1589: *
1590: *----------------------------------------------------------------------
1591: */
1592:
1593: char *
1594: Tk_DisplayName(tkwin)
1595: Tk_Window tkwin; /* Window whose display name is desired. */
1596: {
1597: return ((TkWindow *) tkwin)->dispPtr->name;
1598: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.