|
|
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.