home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / lib / Xt / Display.c.orig < prev    next >
Encoding:
Text File  |  1993-07-21  |  15.0 KB  |  570 lines

  1. /* $XConsortium: Display.c,v 1.86 92/11/23 15:32:29 converse Exp $ */
  2.  
  3. /***********************************************************
  4. Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
  5. and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
  6.  
  7.                         All Rights Reserved
  8.  
  9. Permission to use, copy, modify, and distribute this software and its 
  10. documentation for any purpose and without fee is hereby granted, 
  11. provided that the above copyright notice appear in all copies and that
  12. both that copyright notice and this permission notice appear in 
  13. supporting documentation, and that the names of Digital or MIT not be
  14. used in advertising or publicity pertaining to distribution of the
  15. software without specific, written prior permission.  
  16.  
  17. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  18. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  19. DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  20. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  21. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  22. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  23. SOFTWARE.
  24.  
  25. ******************************************************************/
  26.  
  27. #include "IntrinsicI.h"
  28.  
  29. #ifndef X_NOT_STDC_ENV
  30. #include <stdlib.h>
  31. #else
  32. extern char* getenv();
  33. #endif
  34.  
  35. static String XtNnoPerDisplay = "noPerDisplay";
  36.  
  37. extern void _XtHeapInit();
  38. extern void _XtHeapFree();
  39. extern XrmDatabase _XtPreparseCommandLine();
  40.  
  41. ProcessContext _XtGetProcessContext()
  42. {
  43.     static ProcessContextRec processContextRec = {
  44.     (XtAppContext)NULL,
  45.     (XtAppContext)NULL,
  46.     (ConverterTable)NULL,
  47.     {(XtLanguageProc)NULL, (XtPointer)NULL}
  48.     };
  49.  
  50.     return &processContextRec;
  51. }
  52.  
  53.  
  54. XtAppContext _XtDefaultAppContext()
  55. {
  56.     register ProcessContext process = _XtGetProcessContext();
  57.     if (process->defaultAppContext == NULL) {
  58.     process->defaultAppContext = XtCreateApplicationContext();
  59.     }
  60.     return process->defaultAppContext;
  61. }
  62.  
  63. static void XtAddToAppContext(d, app)
  64.     Display *d;
  65.     XtAppContext app;
  66. {
  67. #define DISPLAYS_TO_ADD 4
  68.  
  69.     if (app->count >= app->max) {
  70.         app->max += DISPLAYS_TO_ADD;
  71.         app->list = (Display **) XtRealloc((char *)app->list,
  72.             (unsigned) app->max * sizeof(Display *));
  73.     }
  74.  
  75.     app->list[app->count++] = d;
  76.     if (ConnectionNumber(d) + 1 > app->fds.nfds) {
  77.         app->fds.nfds = ConnectionNumber(d) + 1;
  78.     }
  79. #undef DISPLAYS_TO_ADD
  80. }
  81.  
  82. static void XtDeleteFromAppContext(d, app)
  83.     Display *d;
  84.     register XtAppContext app;
  85. {
  86.     register int i;
  87.  
  88.     for (i = 0; i < app->count; i++) if (app->list[i] == d) break;
  89.  
  90.     if (i < app->count) {
  91.         if (i <= app->last && app->last > 0) app->last--;
  92.         for (i++; i < app->count; i++) app->list[i-1] = app->list[i];
  93.         app->count--;
  94.     }
  95. }
  96.  
  97. static XtPerDisplay NewPerDisplay();
  98.  
  99. static XtPerDisplay InitPerDisplay(dpy, app, name, classname)
  100.     Display *dpy;
  101.     XtAppContext app;
  102.     String name;
  103.     String classname;
  104. {
  105.     XtPerDisplay pd;
  106.     extern void _XtAllocWWTable(), _XtAllocTMContext();
  107.  
  108.     XtAddToAppContext(dpy, app);
  109.  
  110.     pd = NewPerDisplay(dpy);
  111.     _XtHeapInit(&pd->heap);
  112.     pd->destroy_callbacks = NULL;
  113.     pd->region = XCreateRegion();
  114.     pd->case_cvt = NULL;
  115.     pd->defaultKeycodeTranslator = XtTranslateKey;
  116.     pd->keysyms_serial = 0;
  117.     pd->keysyms = NULL;
  118.     XDisplayKeycodes(dpy, &pd->min_keycode, &pd->max_keycode);
  119.     pd->modKeysyms = NULL;
  120.     pd->modsToKeysyms = NULL;
  121.     pd->appContext = app;
  122.     pd->name = XrmStringToName(name);
  123.     pd->class = XrmStringToClass(classname);
  124.     pd->being_destroyed = False;
  125.     pd->GClist = NULL;
  126.     pd->pixmap_tab = NULL;
  127.     pd->language = NULL;
  128.     pd->rv = False;
  129.     pd->last_timestamp = 0;
  130.     _XtAllocTMContext(pd);
  131.     pd->mapping_callbacks = NULL;
  132.  
  133.     pd->pdi.grabList = NULL;
  134.     pd->pdi.trace = NULL;
  135.     pd->pdi.traceDepth = 0;
  136.     pd->pdi.traceMax = 0;
  137.     pd->pdi.focusWidget = NULL;
  138.     pd->pdi.activatingKey = 0;
  139.     pd->pdi.keyboard.grabType = XtNoServerGrab;
  140.     pd->pdi.pointer.grabType  = XtNoServerGrab;
  141.     _XtAllocWWTable(pd);
  142.     pd->per_screen_db = (XrmDatabase *)XtCalloc(ScreenCount(dpy),
  143.                         sizeof(XrmDatabase));
  144.     pd->cmd_db = (XrmDatabase)NULL;
  145.     pd->server_db = (XrmDatabase)NULL;
  146.     return pd;
  147. }
  148.  
  149. /* kludge, for private communication to _XtAppInit */
  150. static char display_name_tried[100];
  151.  
  152. #if NeedFunctionPrototypes
  153. Display *XtOpenDisplay(
  154.     XtAppContext app,
  155.     _Xconst char* displayName,
  156.     _Xconst char* applName,
  157.     _Xconst char* className,
  158.     XrmOptionDescRec *urlist,
  159.     Cardinal num_urs,
  160.     int *argc,
  161.     String *argv
  162.     )
  163. #else
  164. Display *XtOpenDisplay(app, displayName, applName, className,
  165.         urlist, num_urs, argc, argv)
  166.     XtAppContext app;
  167.     String displayName, applName, className;
  168.     XrmOptionDescRec *urlist;
  169.     Cardinal num_urs;
  170.     int *argc;
  171.     String *argv;
  172. #endif
  173. {
  174.     Display *d;
  175.     XrmDatabase db = 0;
  176.     XtPerDisplay pd;
  177.     String language = NULL;
  178.  
  179.     /* parse the command line for name, display, and/or language */
  180.     db = _XtPreparseCommandLine(urlist, num_urs, *argc, argv, &applName,
  181.                     (displayName ? NULL : &displayName),
  182.                     (app->process->globalLangProcRec.proc ?
  183.                      &language : NULL));
  184.     d = XOpenDisplay(displayName);
  185.  
  186.     if (! applName && !(applName = getenv("RESOURCE_NAME"))) {
  187.         if (*argc > 0 && argv[0] && *argv[0]) {
  188.         char *ptr = rindex(argv[0], '/');
  189.         if (ptr) applName = ++ptr;
  190.         else applName = argv[0];
  191.         } else
  192.         applName = "main";
  193.     }
  194.  
  195.     if (d) {
  196.         pd = InitPerDisplay(d, app, applName, className);
  197.         pd->language = language;
  198.         _XtDisplayInitialize(d, pd, applName, urlist, num_urs, argc, argv);
  199.     } else {
  200.         displayName = XDisplayName(displayName);
  201.         strncpy(display_name_tried, displayName,
  202.             sizeof(display_name_tried));
  203.         display_name_tried[sizeof(display_name_tried)-1] = '\0';
  204.     }
  205.     if (db) XrmDestroyDatabase(db);
  206.     return d;
  207. }
  208.  
  209. Display *
  210. _XtAppInit(app_context_return, application_class, options, num_options,
  211.        argc_in_out, argv_in_out, fallback_resources)
  212. XtAppContext * app_context_return;
  213. String application_class;
  214. XrmOptionDescRec *options;
  215. Cardinal num_options;
  216. int *argc_in_out;
  217. String **argv_in_out, * fallback_resources;
  218. {
  219.     String *saved_argv;
  220.     int i;
  221.     Display *dpy;
  222.  
  223. /*
  224.  * Save away argv and argc so we can set the properties later 
  225.  */
  226.     
  227.     saved_argv = (String *)
  228.     XtMalloc( (Cardinal)((*argc_in_out + 1) * sizeof(String)) );
  229.  
  230.     for (i = 0 ; i < *argc_in_out ; i++) saved_argv[i] = (*argv_in_out)[i];
  231.     saved_argv[i] = NULL;    /* NULL terminate that sucker. */
  232.  
  233.  
  234.     *app_context_return = XtCreateApplicationContext();
  235.  
  236.     if (fallback_resources) /* save a procedure call */
  237.     XtAppSetFallbackResources(*app_context_return, fallback_resources);
  238.  
  239.     dpy = XtOpenDisplay(*app_context_return, (String) NULL, NULL,
  240.             application_class,
  241.             options, num_options, argc_in_out, *argv_in_out);
  242.  
  243.     if (!dpy) {
  244.     String param = display_name_tried;
  245.     Cardinal param_count = 1;
  246.     XtErrorMsg("invalidDisplay","xtInitialize",XtCXtToolkitError,
  247.                    "Can't open display: %s", ¶m, ¶m_count);
  248.     }
  249.     *argv_in_out = saved_argv;
  250.     return dpy;
  251. }
  252.  
  253. #if NeedFunctionPrototypes
  254. void
  255. XtDisplayInitialize(
  256.     XtAppContext app,
  257.     Display *dpy,
  258.     _Xconst char* name,
  259.     _Xconst char* classname,
  260.     XrmOptionDescRec *urlist,
  261.     Cardinal num_urs,
  262.     int *argc,
  263.     String *argv
  264.     )
  265. #else
  266. void
  267. XtDisplayInitialize(app, dpy, name, classname, urlist, num_urs, argc, argv)
  268.     XtAppContext app;
  269.     Display *dpy;
  270.     String name, classname;
  271.     XrmOptionDescRec *urlist;
  272.     Cardinal num_urs;
  273.     int *argc;
  274.     String *argv;
  275. #endif
  276. {
  277.     XtPerDisplay pd;
  278.     XrmDatabase db = 0;
  279.  
  280.     pd = InitPerDisplay(dpy, app, name, classname);
  281.     if (app->process->globalLangProcRec.proc)
  282.     /* pre-parse the command line for the language resource */
  283.     db = _XtPreparseCommandLine(urlist, num_urs, *argc, argv, NULL, NULL,
  284.                     &pd->language);
  285.     _XtDisplayInitialize(dpy, pd, name, urlist, num_urs, argc, argv);
  286.     if (db) XrmDestroyDatabase(db);
  287. }
  288.  
  289. XtAppContext XtCreateApplicationContext()
  290. {
  291.     XtAppContext app = XtNew(XtAppStruct);
  292.  
  293.     app->process = _XtGetProcessContext();
  294.     app->next = app->process->appContextList;
  295.     app->process->appContextList = app;
  296.     app->langProcRec.proc = app->process->globalLangProcRec.proc;
  297.     app->langProcRec.closure = app->process->globalLangProcRec.closure;
  298.     app->destroy_callbacks = NULL;
  299.     app->list = NULL;
  300.     app->count = app->max = app->last = 0;
  301.     app->timerQueue = NULL;
  302.     app->workQueue = NULL;
  303.     app->input_list = NULL;
  304.     app->outstandingQueue = NULL;
  305.     app->errorDB = NULL;
  306.     _XtSetDefaultErrorHandlers(&app->errorMsgHandler, 
  307.         &app->warningMsgHandler, &app->errorHandler, 
  308.         &app->warningHandler);
  309.     app->action_table = NULL;
  310.     _XtSetDefaultSelectionTimeout(&app->selectionTimeout);
  311.     _XtSetDefaultConverterTable(&app->converterTable);
  312.     app->sync = app->being_destroyed = app->error_inited = FALSE;
  313.     app->in_phase2_destroy = NULL;
  314.     app->fds.nfds = app->fds.count = 0;
  315.     FD_ZERO(&app->fds.rmask);
  316.     FD_ZERO(&app->fds.wmask);
  317.     FD_ZERO(&app->fds.emask);
  318.     _XtHeapInit(&app->heap);
  319.     app->fallback_resources = NULL;
  320.     _XtPopupInitialize(app);
  321.     app->action_hook_list = NULL;
  322.     app->destroy_list_size = app->destroy_count = app->dispatch_level = 0;
  323.     app->destroy_list = NULL;
  324. #ifndef NO_IDENTIFY_WINDOWS
  325.     app->identify_windows = False;
  326. #endif
  327.     return app;
  328. }
  329.  
  330. static XtAppContext *appDestroyList = NULL;
  331. int _XtAppDestroyCount = 0;
  332.  
  333. static void DestroyAppContext(app)
  334.     XtAppContext app;
  335. {
  336.     XtAppContext* prev_app = &app->process->appContextList;
  337.     while (app->count-- > 0) XtCloseDisplay(app->list[app->count]);
  338.     if (app->list != NULL) XtFree((char *)app->list);
  339.     _XtFreeConverterTable(app->converterTable);
  340.     _XtCacheFlushTag(app, (XtPointer)&app->heap);
  341.     _XtFreeActions(app->action_table);
  342.     if (app->destroy_callbacks != NULL) {
  343.         XtCallCallbackList((Widget) NULL,
  344.                    (XtCallbackList)app->destroy_callbacks, 
  345.                    (XtPointer)app);
  346.         _XtRemoveAllCallbacks(&app->destroy_callbacks);
  347.     }
  348.     while (app->timerQueue) XtRemoveTimeOut((XtIntervalId)app->timerQueue);
  349.     while (app->workQueue) XtRemoveWorkProc((XtWorkProcId)app->workQueue);
  350.     if (app->input_list) _XtRemoveAllInputs(app);
  351.     XtFree((char*)app->destroy_list);
  352.     _XtHeapFree(&app->heap);
  353.     while (*prev_app != app) prev_app = &(*prev_app)->next;
  354.     *prev_app = app->next;
  355.     if (app->process->defaultAppContext == app)
  356.         app->process->defaultAppContext = NULL;
  357.     XtFree((char *)app);
  358. }
  359.  
  360. void XtDestroyApplicationContext(app)
  361.     XtAppContext app;
  362. {
  363.     if (app->being_destroyed) return;
  364.  
  365.     if (_XtSafeToDestroy(app)) DestroyAppContext(app);
  366.     else {
  367.         app->being_destroyed = TRUE;
  368.         _XtAppDestroyCount++;
  369.         appDestroyList =
  370.             (XtAppContext *) XtRealloc((char *) appDestroyList,
  371.             (unsigned) (_XtAppDestroyCount * sizeof(XtAppContext)));
  372.         appDestroyList[_XtAppDestroyCount-1] = app;
  373.     }
  374. }
  375.  
  376. void _XtDestroyAppContexts()
  377. {
  378.     int i;
  379.  
  380.     for (i = 0; i < _XtAppDestroyCount; i++) {
  381.         DestroyAppContext(appDestroyList[i]);
  382.     }
  383.     _XtAppDestroyCount = 0;
  384.     XtFree((char *) appDestroyList);
  385.     appDestroyList = NULL;
  386. }
  387.  
  388. XrmDatabase XtDatabase(dpy)
  389.     Display *dpy;
  390. {
  391.     return XrmGetDatabase(dpy);
  392. }
  393.  
  394. PerDisplayTablePtr _XtperDisplayList = NULL;
  395.  
  396. XtPerDisplay _XtSortPerDisplayList(dpy)
  397.     Display *dpy;
  398. {
  399.     register PerDisplayTablePtr pd, opd;
  400.  
  401. #ifdef lint
  402.     opd = NULL;
  403. #endif
  404.  
  405.     for (pd = _XtperDisplayList;
  406.          pd != NULL && pd->dpy != dpy;
  407.          pd = pd->next) {
  408.         opd = pd;
  409.     }
  410.  
  411.     if (pd == NULL) {
  412.         XtErrorMsg(XtNnoPerDisplay, "getPerDisplay", XtCXtToolkitError,
  413.             "Couldn't find per display information",
  414.             (String *) NULL, (Cardinal *)NULL);
  415.     }
  416.  
  417.     if (pd != _XtperDisplayList) {    /* move it to the front */
  418.         /* opd points to the previous one... */
  419.  
  420.         opd->next = pd->next;
  421.         pd->next = _XtperDisplayList;
  422.         _XtperDisplayList = pd;
  423.     }
  424.  
  425.     return &(pd->perDpy);
  426. }
  427.  
  428. XtAppContext XtDisplayToApplicationContext(dpy)
  429.     Display *dpy;
  430. {
  431.     return _XtGetPerDisplay(dpy)->appContext;
  432. }
  433.  
  434. static XtPerDisplay NewPerDisplay(dpy)
  435.     Display *dpy;
  436. {
  437.     PerDisplayTablePtr pd;
  438.  
  439.     pd = XtNew(PerDisplayTable);
  440.  
  441.     pd->dpy = dpy;
  442.     pd->next = _XtperDisplayList;
  443.     _XtperDisplayList = pd;
  444.  
  445.     return &(pd->perDpy);
  446. }
  447.  
  448. static Display **dpyDestroyList = NULL;
  449. int _XtDpyDestroyCount = 0;
  450.  
  451. static void CloseDisplay(dpy)
  452.     Display *dpy;
  453. {
  454.         register XtPerDisplay xtpd;
  455.     register PerDisplayTablePtr pd, opd;
  456.     XrmDatabase def_db, db;
  457.     int i;
  458.     
  459. #ifdef lint
  460.     opd = NULL;
  461. #endif
  462.  
  463.     for (pd = _XtperDisplayList;
  464.          pd != NULL && pd->dpy != dpy;
  465.          pd = pd->next){
  466.         opd = pd;
  467.     }
  468.  
  469.     if (pd == NULL) {
  470.         XtErrorMsg(XtNnoPerDisplay, "closeDisplay", XtCXtToolkitError,
  471.             "Couldn't find per display information",
  472.             (String *) NULL, (Cardinal *)NULL);
  473.     }
  474.  
  475.     if (pd == _XtperDisplayList) _XtperDisplayList = pd->next;
  476.     else opd->next = pd->next;
  477.  
  478.     xtpd = &(pd->perDpy);
  479.  
  480.         if (xtpd != NULL) {
  481.         extern void _XtGClistFree(), _XtFreeWWTable();
  482.         if (xtpd->destroy_callbacks != NULL) {
  483.         XtCallCallbackList((Widget) NULL,
  484.                    (XtCallbackList)xtpd->destroy_callbacks,
  485.                    (XtPointer)xtpd);
  486.         _XtRemoveAllCallbacks(&xtpd->destroy_callbacks);
  487.         }
  488.         if (xtpd->mapping_callbacks != NULL)
  489.         _XtRemoveAllCallbacks(&xtpd->mapping_callbacks);
  490.         XtDeleteFromAppContext(dpy, xtpd->appContext);
  491.         if (xtpd->keysyms)
  492.         XFree((char *) xtpd->keysyms);
  493.             XtFree((char *) xtpd->modKeysyms);
  494.             XtFree((char *) xtpd->modsToKeysyms);
  495.             xtpd->keysyms_per_keycode = 0;
  496.             xtpd->being_destroyed = FALSE;
  497.             xtpd->keysyms = NULL;
  498.             xtpd->modKeysyms = NULL;
  499.             xtpd->modsToKeysyms = NULL;
  500.         XDestroyRegion(xtpd->region);
  501.         _XtCacheFlushTag(xtpd->appContext, (XtPointer)&xtpd->heap);
  502.         _XtGClistFree(dpy, xtpd);
  503.         XtFree((char*)xtpd->pdi.trace);
  504.         _XtHeapFree(&xtpd->heap);
  505.         _XtFreeWWTable(xtpd);
  506.         def_db = XrmGetDatabase(dpy);
  507.         for (i = ScreenCount(dpy); --i >= 0; ) {
  508.         db = xtpd->per_screen_db[i];
  509.         if (db && db != def_db)
  510.             XrmDestroyDatabase(db);
  511.         }
  512.         XtFree((char *)xtpd->per_screen_db);
  513.         XrmDestroyDatabase(def_db);
  514.         if (xtpd->cmd_db)
  515.         XrmDestroyDatabase(xtpd->cmd_db);
  516.         if (xtpd->server_db)
  517.         XrmDestroyDatabase(xtpd->server_db);
  518.         XtFree(xtpd->language);
  519.         }
  520.     XtFree((char*)pd);
  521.     XrmSetDatabase(dpy, (XrmDatabase)NULL);
  522.     XCloseDisplay(dpy);
  523. }
  524.  
  525. void XtCloseDisplay(dpy)
  526.     Display *dpy;
  527. {
  528.     XtPerDisplay pd = _XtGetPerDisplay(dpy);
  529.     
  530.     if (pd->being_destroyed) return;
  531.  
  532.     if (_XtSafeToDestroy(pd->appContext)) CloseDisplay(dpy);
  533.     else {
  534.         pd->being_destroyed = TRUE;
  535.         _XtDpyDestroyCount++;
  536.         dpyDestroyList = (Display **) XtRealloc((char *) dpyDestroyList,
  537.             (unsigned) (_XtDpyDestroyCount * sizeof(Display *)));
  538.         dpyDestroyList[_XtDpyDestroyCount-1] = dpy;
  539.     }
  540. }
  541.  
  542. void _XtCloseDisplays()
  543. {
  544.     int i;
  545.  
  546.     for (i = 0; i < _XtDpyDestroyCount; i++) {
  547.         CloseDisplay(dpyDestroyList[i]);
  548.     }
  549.     _XtDpyDestroyCount = 0;
  550.     XtFree((char *) dpyDestroyList);
  551.     dpyDestroyList = NULL;
  552. }
  553.  
  554. XtAppContext XtWidgetToApplicationContext(w)
  555.     Widget w;
  556. {
  557.     return _XtGetPerDisplay(XtDisplayOfObject(w))->appContext;
  558. }
  559.  
  560.  
  561. void XtGetApplicationNameAndClass(dpy, name_return, class_return)
  562.     Display *dpy;
  563.     String *name_return;
  564.     String *class_return;
  565. {
  566.     XtPerDisplay pd = _XtGetPerDisplay(dpy);
  567.     *name_return = XrmQuarkToString(pd->name);
  568.     *class_return = XrmQuarkToString(pd->class);
  569. }
  570.