home *** CD-ROM | disk | FTP | other *** search
/ ftp.pasteur.org/FAQ/ / ftp-pasteur-org-FAQ.zip / FAQ / x-faq / part7 < prev    next >
Internet Message Format  |  1997-01-13  |  56KB

  1. Path: senator-bedfellow.mit.edu!bloom-beacon.mit.edu!bone.think.com!paperboy.osf.org!june.osf.org!dbl
  2. From: dbl@osf.org (David Lewis)
  3. Newsgroups: comp.windows.x,news.answers,comp.answers
  4. Subject: comp.windows.x Frequently Asked Questions (FAQ) 7/7
  5. Followup-To: poster
  6. Date: 2 Oct 1996 20:16:57 GMT
  7. Organization: Open Software Foundation
  8. Lines: 1160
  9. Approved: news-answers-request@MIT.Edu
  10. Distribution: world
  11. Expires: Sun, 27 Oct 1996 00:00:00 GMT
  12. Message-ID: <52uijp$bs0@paperboy.osf.org>
  13. Reply-To: faq%craft@uunet.uu.net (X FAQ maintenance address)
  14. NNTP-Posting-Host: june.osf.org
  15. Summary: useful information about the X Window System
  16. Xref: senator-bedfellow.mit.edu comp.windows.x:110959 news.answers:83419 comp.answers:21530
  17.  
  18. Archive-name: x-faq/part7
  19. Last-modified: 1996/09/26
  20.  
  21. ----------------------------------------------------------------------
  22. Subject: 149)  I'm writing a widget and can't use a float as a resource value.
  23.  
  24. Float resources are not portable; the size of the value may be larger than
  25. the size of an XtPointer. Try using a pointer to a float instead; the Xaw
  26. Scrollbar float resources are handled in this way. 
  27.  
  28. ----------------------------------------------------------------------
  29. Subject: 150)  Is this a memory leak in the X11R4 XtDestroyWidget()?!
  30.  
  31. Yes. This is the "unofficial" fix-19 for the X11R4 Destroy.c:
  32.  
  33. *** Destroy.c.1.37    Thu Jul 11 15:41:25 1991
  34. --- lib/Xt/Destroy.c    Thu Jul 11 15:42:23 1991
  35. ***************
  36. *** 1,4 ****
  37. --- 1,5 ----
  38.   /* $XConsortium: Destroy.c,v 1.37 90/09/28 10:21:32 swick Exp $ */
  39. + /* Plus unofficial patches in revisions 1.40 and 1.41 */
  40.   
  41.   /***********************************************************
  42.   Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
  43. ***************
  44. *** 221,239 ****
  45.        */
  46.   
  47.       int i = 0;
  48. !     DestroyRec* dr = app->destroy_list;
  49.       while (i < app->destroy_count) {
  50.       if (dr->dispatch_level >= dispatch_level)  {
  51.           Widget w = dr->widget;
  52.           if (--app->destroy_count)
  53.           bcopy( (char*)(dr+1), (char*)dr,
  54. !                app->destroy_count*sizeof(DestroyRec)
  55.                 );
  56.           XtPhase2Destroy(w);
  57.       }
  58.       else {
  59.           i++;
  60. -         dr++;
  61.       }
  62.       }
  63.   }
  64. --- 222,245 ----
  65.        */
  66.   
  67.       int i = 0;
  68. !     DestroyRec* dr;
  69.       while (i < app->destroy_count) {
  70. +     /* XtPhase2Destroy can result in calls to XtDestroyWidget,
  71. +      * and these could cause app->destroy_list to be reallocated.
  72. +      */
  73. +     dr = app->destroy_list + i;
  74.       if (dr->dispatch_level >= dispatch_level)  {
  75.           Widget w = dr->widget;
  76.           if (--app->destroy_count)
  77.           bcopy( (char*)(dr+1), (char*)dr,
  78. !                (app->destroy_count - i) * sizeof(DestroyRec)
  79.                 );
  80.           XtPhase2Destroy(w);
  81.       }
  82.       else {
  83.           i++;
  84.       }
  85.       }
  86.   }
  87.  
  88. [from Donna Converse, converse@x.org]
  89.  
  90. ----------------------------------------------------------------------
  91. Subject: 151)  Is this a memory leak in the X11R4 deletion of work procs?!
  92.  
  93. Apparently the X11R4 NextEvent.c`CallWorkProc fails to properly replace
  94. the work proc record back on the free list correctly.
  95.  
  96.         if (delete) {
  97.             w->next = freeWorkRecs;
  98.             freeWorkRecs = w->next;    /* should be  =w; */
  99.         }
  100.  
  101. ----------------------------------------------------------------------
  102. Subject: 152)  Why does the process size of my X programs go up,up,up?
  103.  
  104. Using "ps" may not show any decrease in memory size after a malloc/free pair. 
  105. With most vendors' implementations of memory managers, the call to free does 
  106. not return memory to the operating system; it is probably maintained on a free 
  107. list for the process. In addition, ps may not be an accurate report of current
  108. memory usage requirements.
  109.  
  110. ----------------------------------------------------------------------
  111. Subject: 153)  Are callbacks guaranteed to be called in the order registered?
  112.  
  113. Although some books demonstrate that the current implementation of Xt happens
  114. to call callback procedures in the order in which they are registered, the
  115. specification does not guarantee such a sequence, and supplemental
  116. authoritative documents (i.e. the Asente/Swick volume) do say that the order
  117. is undefined.  Because the callback list can be manipulated by both the
  118. widget and the application, Xt cannot guarantee the order of execution.
  119.  
  120. In general, the callback procedures should be thought of as operating
  121. independently of one another and should not depend on side-effects of other
  122. callbacks operating; if a seqence is needed, then the single callback to be
  123. registered can explicitly call other functions necessary.
  124.  
  125. [4/92; thanks to converse@x.org]
  126.  
  127. ----------------------------------------------------------------------
  128. Subject: 154)  Why doesn't XtDestroyWidget() actually destroy the widget?
  129.  
  130. XtDestroyWidget() operates in two passes, in order to avoid leaving dangling
  131. data structures; the function-call marks the widget, which is not actually
  132. destroyed until your program returns to its event-loop.
  133.  
  134. ----------------------------------------------------------------------
  135. Subject: 155)  How can I open multiple displays with Xt? 
  136.  
  137. Just open each display separately with XOpenDisplay or XtOpenDisplay.  The
  138. latter is much simpler, since the Xt main loop will automatically poll all
  139. displays for events (if you put them all in the same application context).
  140.  
  141. However, consult the skeleton X programs for multiple-displays to see how to
  142. handle the breaking of one display connection; normally Xlib issues an XIO
  143. error and then calls exit().
  144.  
  145. [Thanks to Ken Lee (kenton@rahul.net); 4/95]
  146.  
  147. ----------------------------------------------------------------------
  148. Subject: 156)  How do I query the user synchronously using Xt?
  149.     
  150.     It is possible to have code which looks like this trivial callback,
  151. which has a clear flow of control. The calls to AskUser() block until answer
  152. is set to one of the valid values. If it is not a "yes" answer, the code drops
  153. out of the callback and back to an event-processing loop: 
  154.  
  155.     void quit(Widget w, XtPointer client, XtPointer call)
  156.     {
  157.         int             answer;
  158.         answer = AskUser(w, "Really Quit?");
  159.         if (RET_YES == answer)
  160.             {
  161.             answer = AskUser(w, "Are You Really Positive?");
  162.             if (RET_YES == answer)
  163.                 exit(0);
  164.                 }
  165.     }
  166.  
  167.     A more realistic example might ask whether to create a file or whether 
  168. to overwrite it.
  169.     This is accomplished by entering a second event-processing loop and
  170. waiting until the user answers the question; the answer is returned to the
  171. calling function. That function AskUser() looks something like this, where the 
  172. Motif can be replaced with widget-set-specific code to create some sort of 
  173. dialog-box displaying the question string and buttons for "OK", "Cancel" and 
  174. "Help" or equivalents:
  175.  
  176.   int AskUser(w, string)
  177.         Widget          w;
  178.         char           *string;
  179.   {
  180.         int             answer=RET_NONE;    /* some not-used marker */
  181.         Widget          dialog;            /* could cache&carry, but ...*/
  182.         Arg             args[3];
  183.         int             n = 0;
  184.         XtAppContext    context;
  185.  
  186.         n=0;
  187.         XtSetArg(args[n], XmNmessageString, XmStringCreateLtoR(string,
  188.                 XmSTRING_DEFAULT_CHARSET)); n++;
  189.         XtSetArg(args[n], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); n++;
  190.         dialog = XmCreateQuestionDialog(XtParent(w), string, args, n);
  191.         XtAddCallback(dialog, XmNokCallback, response, &answer);
  192.         XtAddCallback(dialog, XmNcancelCallback, response, &answer);
  193.         XtAddCallback(dialog, XmNhelpCallback, response, &answer);
  194.         XtManageChild(dialog);
  195.  
  196.         context = XtWidgetToApplicationContext(w);
  197.         while ((RET_NONE == answer) || XtAppPending(context)) 
  198.                 XtAppProcessEvent (context, XtIMAll);
  199.         XtDestroyWidget(dialog);  /* blow away the dialog box and shell */
  200.         return answer;
  201.   }
  202.  
  203.     The dialog supports three buttons, which are set to call the same 
  204. function when tickled by the user.  The variable answer is set when the user 
  205. finally selects one of those choices:
  206.  
  207.   void response(w, client, call)
  208.         Widget          w;
  209.         XtPointer client;
  210.         XtPointer call;
  211.   {
  212.         int *answer = (int *) client;
  213.         XmAnyCallbackStruct *reason = (XmAnyCallbackStruct *) call;
  214.         switch (reason->reason) {
  215.         case XmCR_OK:
  216.                 *answer = RET_YES;    /* some #define value */
  217.                 break;
  218.         case XmCR_CANCEL:
  219.                 *answer = RET_NO; 
  220.         break;
  221.         case XmCR_HELP:
  222.                 *answer = RET_HELP;
  223.                 break;
  224.         default:
  225.                 return;
  226.         }
  227. }
  228.  
  229. and the code unwraps back to the point at which an answer was needed and
  230. continues from there.
  231.  
  232. Note that modifications are needed to handle receiving WM_DELETE_WINDOW on
  233. the window; possibly WM_DELETE_WINDOW can be handled by setting the "answer"
  234. variable.
  235.  
  236. [Thanks to Dan Heller (now argv@z-code.com); note that the code in his book
  237. caches the dialog but neglects to make sure that the callbacks point to the
  238. current automatic "answer".]
  239.  
  240. ----------------------------------------------------------------------
  241. Subject: 157)  How do I determine the name of an existing widget?
  242. I have a widget ID and need to know what the name of that widget is.
  243.  
  244.     Users of R4 and later are best off using the XtName() function, which 
  245. will work on both widgets and non-widget objects.
  246.  
  247.     If you are still using R3, you can use this simple bit of code to do 
  248. what you want. Note that it depends on the widget's internal data structures 
  249. and is not necessarily portable to future versions of Xt, including R4.
  250.  
  251.     #include <X11/CoreP.h>
  252.     #include <X11/Xresource.h>
  253.     String XtName (widget)
  254.     Widget widget;    /* WILL work with non-widget objects */
  255.     {
  256.     return XrmNameToString(widget->core.xrm_name);
  257.     }
  258.  
  259. [7/90; modified with suggestion by Larry Rogers (larry@boris.webo.dg.com) 9/91]
  260.  
  261. ----------------------------------------------------------------------
  262. Subject: 158)  Why do I get a BadDrawable error drawing to XtWindow(widget)?
  263. I'm doing this in order to get a window into which I can do Xlib graphics
  264. within my Xt-based program:
  265.  
  266. > canvas = XtCreateManagedWidget ( ...,widgetClass,...) /* drawing area */
  267. > ...
  268. > window = XtWindow(canvas);    /* get the window associated with the widget */
  269. > ...
  270. > XDrawLine (...,window,...);    /* produces error */
  271.  
  272.     The window associated with the widget is created as a part of the 
  273. realization of the widget.  Using a window id of None ("no window") could 
  274. create the error that you describe.  It is necessary to call XtRealizeWidget() 
  275. before attempting to use the window associated with a widget. 
  276.     Note that the window will be created after the XtRealizeWidget() call, 
  277. but that the server may not have actually mapped it yet, so you should also 
  278. wait for an Expose event on the window before drawing into it.
  279.  
  280. ----------------------------------------------------------------------
  281. Subject: 159)  Where can I get documentation on Xaw, the Athena widget set?
  282.  
  283.     Check ftp.x.org in /pub/R5untarred/mit/hardcopy for the originals of
  284. documentation distributed with X11R5. In R6, see xc/doc/specs/Xaw or
  285. xc/doc/hardcopy/Xaw.
  286.  
  287. ----------------------------------------------------------------------
  288. Subject: 160)  What's the difference between actions and callbacks?
  289.  
  290. Actions and callbacks may be closely tied; the user may click a mouse-button
  291. in an object's window, causing an action procedure in that particular object
  292. to be called. As part of its processing of the event, the action procedure
  293. may inform the application via a callback registered on the object. However,
  294. callbacks can be given for any reason, including some that don't arise as a
  295. result of user action; and many actions don't result in any notification to
  296. the application.
  297.  
  298. Callbacks generally are a means of interaction between the user interface
  299. (UI) and some other piece of code interested in the "results"; the interested
  300. party to which the data is communicated is usually the application's back-end
  301. functions but may be another widget in a related part of the UI.  For
  302. example, a text widget invokes a callback to say "the user just entered this
  303. text string; never mind what I had to do to get it or what X events took
  304. place."
  305.  
  306. In object-oriented programming terminology, callback lists are messages
  307. defined by the widget class by which the widget instance notifies another
  308. entity that something significant has happened to the widget.
  309.  
  310. Actions, however, constitute a widget's repertoire of internal i/o
  311. behaviors.  Actions are not about results; actions are about "how", not
  312. "what" gets done. The text widget may define a dozen or two actions which
  313. define how the user can manipulate the text; the procedures for removing a
  314. line of text or switching two words can be associated with particular X event
  315. sequences (and in fact often rely on particular types of events).
  316.  
  317. Actions are (in OOP terminology) methods of the widget class by which the
  318. widget responds to some external stimulus (one or more X events).
  319.  
  320. To avoid confusing yourself on the issue of actions vs. callbacks, try
  321. thinking of actions defined by an application as methods *of the application*
  322. -- applications may define actions, as well -- by which the application
  323. responds to one or more X events (and happens to be handed an object handle
  324. as part of the method argument list). Similarly, callback handlers registered
  325. by an application with a widget can be thought of as methods of the
  326. application which respond to messages from a widget or widgets.
  327.  
  328. [Thanks to Michael Johnson (michael@maine.maine.edu) and to Kerry Kimbrough]
  329.  
  330. ----------------------------------------------------------------------
  331. Subject: 161)  How do I simulate a button press/release event for a widget?
  332.  
  333. You can do this using XSendEvent(); it's likely that you're not setting the
  334. window field in the event, which Xt needs in order to match to the widget
  335. which should receive the event.
  336.  
  337. If you're sending events to your own application, then you can use
  338. XtDispatchEvent() instead. This is more efficient than XSendEvent() in that
  339. you avoid a round-trip to the server.
  340.  
  341. Depending on how well the widget was written, you may be able to call its
  342. action procedures in order to get the effects you want.
  343.  
  344. [courtesy Mark A. Horstman (mh2620@sarek.sbc.com), 11/90]
  345.  
  346. ----------------------------------------------------------------------
  347. Subject: 162)  Can I make Xt or Xlib calls from a signal handler?
  348.  
  349. No. Xlib and Xt have no mutual exclusion for protecting critical sections. If
  350. your signal handler makes such a call at the wrong time (which might be while
  351. the function you are calling is already executing), it can leave the library
  352. in an inconsistent state. Note that the ANSI C standard points out that
  353. behavior of a signal handler is undefined if the signal handler calls any
  354. function other than signal() itself, so this is not a problem specific to
  355. Xlib and Xt; the POSIX specification mentions other functions which may be
  356. called safely but it may not be assumed that these functions are called by
  357. Xlib or Xt functions.
  358.  
  359. Setting a global variable is one of the few permitted operations.  You can
  360. work around the problem by setting a flag in the interrupt handler and later
  361. checking it with a work procedure or a timer event which has previously been
  362. added or by using a custom event loop.
  363.  
  364. R6 Xt has have support for signal handlers; there is a mechanism to set a
  365. flag in a signal handler, and XtAppNextEvent will notice that the flag has
  366. been set and call the associated callbacks.
  367.  
  368. Note: the article in The X Journal 1:4 and the example in the first edition
  369. of O'Reilly & Associates' Volume 6 are in error.
  370.  
  371. [Thanks to Pete Ware (ware@cis.ohio-state.edu) and Donna Converse
  372. (converse@x.org), 5/92]
  373.  
  374. An alternate solution is to create a pipe and add the read side of the pipe
  375. as an input event with XtAppAddInput; then write a byte to the write side of
  376. the pipe with your signal handler (write is re-entrant). The callback for the
  377. read side of the pipe reads the byte and does the actual processing that you
  378. intended. You may want the byte to be the signal number unless your callback
  379. handles only one kind.
  380.  
  381. [Thanks to Steve Kappel (stevek@apertus.com)]
  382.  
  383. ----------------------------------------------------------------------
  384. Subject: 163)! What are these "Xlib: unexpected async reply" errors?
  385.  
  386. You'll typically get these errors if you are writing a multi-threaded
  387. application and are making X calls from more than one thread -- one of the
  388. more common new ways to introduce memory corruption into Xlib (using bogus
  389. pointers is another, as is mixing up XFree/XtFree/free calls. Even an
  390. operation as simple as XSendEvent can't be called from a second thread.).
  391. Prior to X11R6, X doesn't support multi-threading; check the X11R6
  392. documentation for how to write a threaded application safely with X11R6 and
  393. later versions of X (including being sure to enable Xlib's multi-thread
  394. support).
  395.  
  396. Common widget sets are also unsafe to use except from within one thread.  The
  397. versions of Motif from OSF, for example, offer no support for
  398. multi-threading.
  399.  
  400. ----------------------------------------------------------------------
  401. Subject: 164)  What are these "Xlib sequence lost" errors?
  402.  
  403. You may see these errors if you issue Xlib requests from an Xlib error
  404. handler, or, more likely, if you make calls which generate X requests to Xt
  405. or Xlib from a signal handler, which you shouldn't be doing in any case.
  406.  
  407. ----------------------------------------------------------------------
  408. Subject: 165)  How can my Xt program handle socket, pipe, or file input?
  409.  
  410. It's very common to need to write an Xt program that can accept input both
  411. from a user via the X connection and from some other file descriptor, but
  412. which operates efficiently and without blocking on either the X connection or
  413. the other file descriptor.
  414.  
  415. A solution is use XtAppAddInput(). After you open your file descriptor, use
  416. XtAppAddInput() to register an input handler. The input handler will be
  417. called every time there is something on the file descriptor requiring your
  418. program's attention. Write the input handler like you would any other Xt
  419. callback, so it does its work quickly and returns.  It is important to use
  420. only non-blocking I/O system calls in your input handlers.
  421.  
  422. Most input handlers read the file descriptor, although you can have an input
  423. handler write or handle exception conditions if you wish.
  424.  
  425. Be careful when you register an input handler to read from a disk file.  You
  426. will find that the function is called even when there isn't input pending.
  427. XtAppAddInput() is actually working as it is supposed to. The input handler
  428. is called whenever the file descriptor is READY to be read, not only when
  429. there is new data to be read. A disk file (unlike a pipe or socket) is almost
  430. always ready to be read, however, if only because you can spin back to the
  431. beginning and read data you've read before.  The result is that your function
  432. will almost always be called every time around XtAppMainLoop(). There is a
  433. way to get the type of interaction you are expecting; add this line to the
  434. beginning of your function to test whether there is new data:
  435.  
  436.          if (ioctl(fd, FIONREAD, &n) == -1 || n == 0) return;
  437.  
  438. But, because this is called frequently, your application is effectively in a
  439. busy-wait; you may be better off not using XtAppAddInput() and instead
  440. setting a timer and in the timer procedure checking the file for input.
  441.  
  442. [courtesy Dan Heller (argv@ora.com), 8/90; mouse@larry.mcrcim.mcgill.edu 5/91;
  443. Ollie Jones (oj@pictel.com) 6/92]
  444.  
  445. There are two alternatives: the simple one is to use XtAppAddTimeout instead
  446. of XtAppAddInput and check for input occasionally; the more complex solution,
  447. and perhaps the better one, is to popen or fork&exec a child which does
  448. blocking reads on the file, relaying what it has read to your application via
  449. a pipe or a socket. XtAppAddInput will work as expected on pipes and
  450. sockets.
  451.  
  452. Thanks to Kaleb Keithley (kaleb@x.org); 12/93]
  453.  
  454. ----------------------------------------------------------------------
  455. Subject: 166)  Why doesn't my Xt timer go off when it is supposed to (sic) ?
  456.  
  457. Xt timers are non-preemptive; they do not operate like signal interrupts.
  458. That is, they don't suspend execution of the client program at a specific
  459. interval and call the timer procedure.
  460.  
  461. Rather, timers are handled by Xt as another form of input. The Xt event loop
  462. watches for X events and for socket activity; the select() statement Xt uses
  463. returns when the first timer is set to go off. Xt then calls any timers that
  464. have expired.
  465.  
  466. The implementation means that Xt timers can't be used for real-time
  467. operations.  If one callback takes some time to operate, for example, any
  468. timers that "should have" gone off during its operation are not called until
  469. the thread of execution has again returned to Xt's event loop.
  470.  
  471. ----------------------------------------------------------------------
  472. Subject: 167)  What's this R6 error: X Toolkit Error: NULL ArgVal in XtGetValues?
  473.  
  474. The application has a bug! A workaround is described in Section 3.4 of
  475. the R6 release notes.  Here's the relevant excerpt:
  476.  
  477.    GetValuesBC
  478.      Setting this variable to YES allows illegal XtGetValues requests with
  479.      NULL ArgVal to usually succeed, as R5 did.  Some applications erro-
  480.      neously rely on this behavior.  Support for this will be removed in a
  481.      future release.
  482.  
  483. ----------------------------------------------------------------------
  484. Subject: 168)  Why do I get a BadMatch error when calling XGetImage?
  485.  
  486. The BadMatch error can occur if the specified rectangle goes off the edge of 
  487. the screen. If you don't want to catch the error and deal with it, you can take
  488. the following steps to avoid the error:
  489.  
  490. 1) Make a pixmap the same size as the rectangle you want to capture.
  491. 2) Clear the pixmap to background using XFillRectangle.
  492. 3) Use XCopyArea to copy the window to the pixmap.
  493.     [Whoa! this answer is currently under reexamination.]
  494. 4) If you get a NoExpose event, the copy was clean. Use XGetImage to grab the
  495. image from the pixmap.
  496. 5) If you get one or more GraphicsExpose events, the copy wasn't clean, and 
  497. the x/y/width/height members of the GraphicsExpose event structures tell you 
  498. the parts of the pixmap which aren't good.
  499. 6) Get rid of the pixmap; it probably takes a lot of memory.
  500.  
  501. [10/92; thanks to Oliver Jones (oj@pictel.com)]
  502.  
  503. ----------------------------------------------------------------------
  504. Subject: 169)  How can my application tell if it is being run under X?
  505.  
  506. A number of programs offer X modes but otherwise run in a straight
  507. character-only mode. The easiest way for an application to determine that it
  508. is running on an X display is to attempt to open a connection to the X
  509. server:
  510.     
  511.     display = XOpenDisplay(display_name);
  512.     if (display)
  513.         { do X stuff }
  514.     else
  515.         { do curses or something else }
  516.  
  517. where display_name is either the string specified on the command-line
  518. following -display, by convention, or otherwise is (char*)NULL [in which case
  519. XOpenDisplay uses the value of $DISPLAY, if set].
  520.  
  521. This is superior to simply checking for the existence a -display command-line 
  522. argument or checking for $DISPLAY set in the environment, neither of which is 
  523. adequate. [5/91]
  524.  
  525. Note that there is a lengthy delay if $DISPLAY exists but is set to a machine
  526. which is not currently running an X server.
  527.  
  528. ----------------------------------------------------------------------
  529. Subject: 170)  How do I make a "busy cursor" while my application is computing?
  530. Is it necessary to call XDefineCursor() for every window in my application?
  531.  
  532.     The easiest thing to do is to create a single InputOnly window that
  533. is as large as the largest possible screen; make it a child of your toplevel
  534. window (which must be realized) and it will be clipped to that window, so it
  535. won't affect any other application. (It needs to be as big as the largest
  536. possible screen in case the user enlarges the window while it is busy or
  537. moves elsewhere within a virtual desktop.) Substitute "toplevel" with your
  538. top-most widget here (similar code should work for Xlib-only applications;
  539. just use your top Window):
  540.  
  541.      unsigned long valuemask;
  542.      XSetWindowAttributes attributes;
  543.  
  544.      /* Ignore device events while the busy cursor is displayed. */
  545.      valuemask = CWDontPropagate | CWCursor;
  546.      attributes.do_not_propagate_mask =  (KeyPressMask | KeyReleaseMask |
  547.          ButtonPressMask | ButtonReleaseMask | PointerMotionMask);
  548.      attributes.cursor = XCreateFontCursor(XtDisplay(toplevel), XC_watch);
  549.  
  550.      /* The window will be as big as the display screen, and clipped by
  551.         its own parent window, so we never have to worry about resizing */
  552.      XCreateWindow(XtDisplay(toplevel), XtWindow(toplevel), 0, 0,
  553.          65535, 65535, (unsigned int) 0, 0, InputOnly,
  554.          CopyFromParent, valuemask, &attributes);
  555.  
  556. where the maximum size above could be replaced by the real size of the screen,
  557. particularly to avoid servers which have problems with windows larger than
  558. 32767.
  559.  
  560. When you want to use this busy cursor, map and raise this window; to go back to
  561. normal, unmap it. This will automatically keep you from getting extra mouse
  562. events; depending on precisely how the window manager works, it may or may not
  563. have a similar effect on keystrokes as well.
  564.  
  565. In addition, note also that most of the Xaw widgets support an XtNcursor 
  566. resource which can be temporarily reset, should you merely wish to change the
  567. cursor without blocking pointer events.
  568.  
  569. [thanks to Andrew Wason (aw@cellar.bae.bellcore.com), Dan Heller 
  570. (now argv@z-code.com), and mouse@larry.mcrcim.mcgill.edu; 11/90,5/91]
  571.  
  572. ----------------------------------------------------------------------
  573. Subject: 171)  How do I fork without hanging my parent X program?
  574.  
  575.     An X-based application which spawns off other Unix processes which 
  576. continue to run after it is closed typically does not vanish until all of its 
  577. children are terminated; the children inherit from the parent the open X 
  578. connection to the display. 
  579.     What you need to do is fork; then, immediately, in the child process, 
  580.         close (ConnectionNumber(XtDisplay(widget)));
  581. to close the file-descriptor in the display information. After this do your 
  582. exec. You will then be able to exit the parent.
  583.     Alternatively, before exec'ing make this call, which causes the file 
  584. descriptor to be closed on exec.
  585.         (void) fcntl(ConnectionNumber(XDisplay), F_SETFD, 1);
  586.  
  587. [Thanks to Janet Anstett (anstettj@tramp.Colorado.EDU), Gordon Freedman 
  588. (gjf00@duts.ccc.amdahl.com); 2/91. Greg Holmberg (holmberg@frame.com), 3/93.]
  589.  
  590. ----------------------------------------------------------------------
  591. Subject: 172)  Why doesn't anything appear when I run this simple program?
  592.  
  593. > ...
  594. > the_window = XCreateSimpleWindow(the_display,
  595. >      root_window,size_hints.x,size_hints.y,
  596. >      size_hints.width,size_hints.height,BORDER_WIDTH,
  597. >      BlackPixel(the_display,the_screen),
  598. >      WhitePixel(the_display,the_screen));
  599. > ...
  600. > XSelectInput(the_display,the_window,ExposureMask|ButtonPressMask|
  601. >     ButtonReleaseMask);
  602. > XMapWindow(the_display,the_window);
  603. > ...
  604. > XDrawLine(the_display,the_window,the_GC,5,5,100,100);
  605. > ...
  606.  
  607.     You are right to map the window before drawing into it. However, the 
  608. window is not ready to be drawn into until it actually appears on the screen --
  609. until your application receives an Expose event. Drawing done before that will 
  610. generally not appear. You'll see code like this in many programs; this code 
  611. would appear after the window was created and mapped:
  612.   while (!done)
  613.     {
  614.       XNextEvent(the_display,&the_event);
  615.       switch (the_event.type) {
  616.     case Expose:     /* On expose events, redraw */
  617.         XDrawLine(the_display,the_window,the_GC,5,5,100,100);
  618.         break;
  619.     ...
  620.     }
  621.     }
  622.  
  623.     Note that there is a second problem: some Xlib implementations don't 
  624. set up the default graphics context to have correct foreground/background 
  625. colors, so this program could previously include this code:
  626.   ...
  627.   the_GC_values.foreground=BlackPixel(the_display,the_screen);    /* e.g. */
  628.   the_GC_values.background=WhitePixel(the_display,the_screen);    /* e.g. */
  629.   the_GC = XCreateGC(the_display,the_window,
  630.                 GCForeground|GCBackground,&the_GC_values);
  631.   ...
  632.  
  633. Note: the code uses BlackPixel and WhitePixel to avoid assuming that 1 is 
  634. black and 0 is white or vice-versa.  The relationship between pixels 0 and 1 
  635. and the colors black and white is implementation-dependent.  They may be 
  636. reversed, or they may not even correspond to black and white at all.
  637.  
  638. Also note that actually using BlackPixel and WhitePixel is usually the wrong 
  639. thing to do in a finished program, as it ignores the user's preference for 
  640. foreground and background.
  641.  
  642. And also note that you can run into the same situation in an Xt-based program
  643. if you draw into the XtWindow(w) right after it has been realized; it may
  644. not yet have appeared.
  645.  
  646. ----------------------------------------------------------------------
  647. Subject: 173)  What is the difference between a Screen and a screen?
  648.  
  649.     The 'Screen' is an Xlib structure which includes the information about
  650. one of the monitors or virtual monitors which a single X display supports. A 
  651. server can support several independent screens. They are numbered unix:0.0,
  652. unix:0.1, unix:0.2, etc; the 'screen' or 'screen_number' is the second digit --
  653. the 0, 1, 2 which can be thought of as an index into the array of available 
  654. Screens on this particular Display connection.
  655.     The macros which you can use to obtain information about the particular
  656. Screen on which your application is running typically have two forms -- one
  657. which takes a Screen and one with takes both the Display and the screen_number.
  658.     In Xt-based programs, you typically use XtScreen(widget) to determine 
  659. the Screen on which your application is running, if it uses a single screen.
  660.     (Part of the confusion may arise from the fact that some of the macros
  661. which return characteristics of the Screen have "Display" in the names -- 
  662. DisplayWidth, DisplayHeight, etc.)
  663.     
  664. ----------------------------------------------------------------------
  665. Subject: 174)  Can XGetWindowAttributes get a window's background pixel/pixmap?
  666.  
  667. No.  Once set, the background pixel or pixmap of a window cannot be re-read
  668. by clients.  The reason for this is that a client can create a pixmap, set it
  669. to be the background pixmap of a window, and then free the pixmap. The window
  670. keeps this background, but the pixmap itself is destroyed.  If you're sure a
  671. window has a background pixel (not a pixmap), you can use XClearArea() to
  672. clear a region to the background color and then use XGetImage() to read back
  673. that pixel.  However, this action alters the contents of the window, and it
  674. suffers from race conditions with exposures. [courtesy Dave Lemke of NCD and
  675. Stuart Marks of Sun]
  676.  
  677. Note that the same applies to the border pixel/pixmap. This is a (mis)feature
  678. of the protocol which allows the server to manipulate the pixel/pixmap
  679. however it wants.  By not requiring the server to keep the original pixel or
  680. pixmap, some (potentially a lot of) space can be saved.  [courtesy Jim
  681. Fulton, then of X Consortium]
  682.  
  683. ----------------------------------------------------------------------
  684. Subject: 175)  How do I create a transparent window?
  685.     
  686.     A completely transparent window is easy to get -- use an InputOnly
  687. window. In order to create a window which is *mostly* transparent, you have
  688. several choices:
  689.     - the SHAPE extension first released with X11R4 offers an easy way to
  690. make non-rectangular windows, so you can set the shape of the window to fit the
  691. areas where the window should be nontransparent; however, not all servers 
  692. support the extension.
  693.     - a machine-specific method of implementing transparent windows for
  694. particular servers is to use an overlay plane supported by the hardware.  Note 
  695. that there is no X notion of a "transparent color index".
  696.     - a generally portable solution is to use a large number of tiny 
  697. windows, but this makes operating on the application as a unit difficult.
  698.     - a final answer is to consider whether you really need a transparent
  699. window or if you would be satisfied with being able to overlay your application
  700. window with information; if so, you can draw into separate bitplanes in colors
  701. that will appear properly.
  702.  
  703. [thanks to der Mouse, mouse@lightning.McRCIM.McGill.EDU, 3/92; see also
  704. The X Journal 1:4 for a more complete answer, including code samples for this
  705. last option]
  706.  
  707. ----------------------------------------------------------------------
  708. Subject: 176)  Why doesn't GXxor produce mathematically-correct color values?
  709.  
  710.     When using GXxor you may expect that drawing with a value of black on a
  711. background of black, for example, should produce white. However, the drawing
  712. operation does not work on RGB values but on colormap indices. The color that
  713. the resulting colormap index actually points to is undefined and visually
  714. random unless you have actually filled it in yourself. [On many X servers Black
  715. and White often 0/1 or 1/0; programs taking advantage of this mathematical
  716. coincidence will break.]
  717.     If you want to be combining colors with GXxor, then you should be 
  718. allocating a number of your own color cells and filling them with your chosen
  719. pre-computed values.
  720.     If you want to use GXxor simply to switch between two colors, then you 
  721. can take the shortcut of setting the background color in the GC (graphics 
  722. context) to 0 and the foreground color to a value such that when it draws over 
  723. red, say, the result is blue, and when it draws over blue the result is red. 
  724. This foreground value is itself the XOR of the colormap indices of red and 
  725. blue.
  726.  
  727. [Thanks to Chris Flatters (cflatter@zia.aoc.nrao.EDU) and Ken Whaley 
  728. (whaley@spectre.pa.dec.com), 2/91]
  729.  
  730. ----------------------------------------------------------------------
  731. Subject: 177)  Why does every color I allocate show up as black?
  732.  
  733.     Make sure you're using 16 bits and not 8.  The red, green, and blue 
  734. fields of an XColor structure are scaled so that 0 is nothing and 65535 is 
  735. full-blast. If you forget to scale (using, for example, 0-255 for each color) 
  736. the XAllocColor function will perform correctly but the resulting color is 
  737. usually black. 
  738.  
  739. [Thanks to Paul Asente, asente@adobe.com, 7/91]
  740.  
  741. ----------------------------------------------------------------------
  742. Subject: 178)  Why do I get a protocol error when creating a cursor (sic)?
  743.  
  744.     You may have had this code working on a monochrome system by
  745. coincidence.  Cursor pixmaps must always have a depth of 1; when you create
  746. the cursor pixmap use the depth of 1 rather than the default depth of the
  747. screen.
  748.  
  749. ----------------------------------------------------------------------
  750. Subject: 179)  Why can't my program get a standard colormap?
  751. I have an image-processing program which uses XGetRGBColormap() to get the 
  752. standard colormap, but it doesn't work. 
  753.  
  754.     XGetRGBColormap() when used with the property XA_RGB_DEFAULT_MAP does 
  755. not create a standard colormap -- it just returns one if one already exists.
  756. Use xstdcmap or do what it does in order to create the standard colormap first.
  757.  
  758. [1/91; from der Mouse (mouse@larry.mcrcim.mcgill.edu)]
  759.  
  760. ----------------------------------------------------------------------
  761. Subject: 180)  Why doesn't the shared-memory extension appear to work?
  762.  
  763. Using the MIT shared-memory extension (MIT-SHM) is a fine way to speed up
  764. manipulation and display of images. But be aware that XShmQueryExtension(dpy)
  765. returns only information on whether or not the server to which your program
  766. is connected is capable of supporting the shared-memory extension -- it
  767. doesn't confirm that your application is running on the same machine on which
  768. you are running that server. The client and server have to be on the same
  769. machine to be able to use shared memory.
  770.  
  771. Current documentation is available via
  772. ftp://ftp.x.org/pub/R6untarred/xc/doc/specs/Xext/mit-shm.ms .
  773.  
  774. [thanks to Kaleb Keithley (kaleb@x.org); 3/95] 
  775.  
  776. ----------------------------------------------------------------------
  777. Subject: 181)  Why does the pixmap I copy to the screen show up as garbage? 
  778.  
  779.     The initial contents of pixmaps are undefined.  This means that most
  780. servers will allocate the memory and leave around whatever happens to be there 
  781. -- which is usually garbage.  You probably want to clear the pixmap first using
  782. XFillRectangle() with a function of GXcopy and a foreground pixel of whatever 
  783. color you want as your background (or 0L if you are using the pixmap as a 
  784. mask). [courtesy Dave Lemke of NCD and Stuart Marks of Sun]
  785.  
  786. ----------------------------------------------------------------------
  787. Subject: 182)  How do I get the width/height of an existing pixmap?
  788.  
  789. XGetGeometry() works on Drawables -- either windows or pixmaps. In the case
  790. of a pixmap, though, the x,y, and border_width values are 0 (meaningless).
  791.  
  792. ----------------------------------------------------------------------
  793. Subject: 183)  How can I most quickly send an image to the X server? 
  794.  
  795.     The fastest mechanism may be to use an XImage and the shared-memory
  796. extension to reduce the transmission time.
  797.     The MIT-SHM code, documentation, and example client programs can be 
  798. found on the X11R5 source tape; many vendors also support the extension.
  799.     If bandwidth is a problem, the X Image Extension has facilities for
  800. transmitting compressed images.
  801.  
  802. ----------------------------------------------------------------------
  803. Subject: 184)  How do I check whether a window ID is valid?
  804. My program has the ID of a window on a remote display. I want to check whether
  805. the window exists before doing anything with it.
  806.  
  807.     Because X is asynchronous, there isn't a guarantee that the window 
  808. would still exist between the time that you got the ID and the time you sent an
  809. event to the window or otherwise manipulated it. What you should do is send the
  810. event without checking, but install an error handler to catch any BadWindow
  811. errors, which would indicate that the window no longer exists. This scheme
  812. will work except on the [rare] occasion that the original window has been
  813. destroyed and its ID reallocated to another window. 
  814.     You can use this scheme to make a function which checks the validity
  815. of a window; you can make this operation almost synchronous by calling
  816. XSync() after the request, although there is still no guarantee that the
  817. window will exist after the result (unless the sterver is grabbed). On the 
  818. whole, catching the error rather than pre-checking is preferable.
  819.  
  820. [courtesy Ken Lee (now kenton@esd.sgi.com), 4/90; 12/93]
  821.  
  822. ----------------------------------------------------------------------
  823. Subject: 185)  Can I have two applications draw to the same window?
  824.  
  825. Yes. The X server assigns IDs to windows and other resources (actually, the
  826. server assigns some bits, the client others), and any application that knows
  827. the ID can manipulate the resource (almost any X server resource, except for
  828. GCs and private color cells, can be shared).
  829.  
  830. The problem you face is how to disseminate the window ID to multiple
  831. applications. A simple way to handle this (and which solves the problem of
  832. the applications' running on different machines) is in the first application
  833. to create a specially-named property on the root-window and put the window ID
  834. into it. The second application then retrieves the property, whose name it
  835. also knows, and then can draw whatever it wants into the window.
  836.  
  837. [Note: this scheme works if and only if there is only one instance of the
  838. first application running, and the scheme is subject to the limitations
  839. mentioned in the Question about using window IDs on remote displays.]
  840.  
  841. Note also that you will still need to coordinate any higher-level cooperation
  842. among your applications; you may find the Synchronization extension in R6
  843. useful for this.
  844.  
  845. Note also that two processes can share a window but should not try to use the
  846. same server connection. If one process is a child of the other, it should
  847. close down the connection to the server and open its own connection.
  848.  
  849. Note also that Display IDs and GC values describe addresses local to an
  850. application and cannot be transmitted to another application; note also that
  851. if you are using Xt you may not share widget IDs, which are local to the
  852. client.
  853.  
  854. Note also that several clients may draw to a window but for particular X
  855. events such as button-presses only one client can receive the event.
  856.  
  857. [mostly courtesy Phil Karlton (karlton@wpd.sgi.com) 6/90]
  858.  
  859. ----------------------------------------------------------------------
  860. Subject: 186)  Why can't my program work with tvtwm or swm?
  861.  
  862.     A number of applications, including xwd, xwininfo, and xsetroot, do not
  863. handle the virtual root window which tvtwm and swm use; they typically return 
  864. the wrong child of root. A general solution is to add this code or to use it in
  865. your own application where you would normally use RootWindow(dpy,screen):
  866.  
  867. /* Function Name: GetVRoot
  868.  * Description: Gets the root window, even if it's a virtual root
  869.  * Arguments: the display and the screen
  870.  * Returns: the root window for the client
  871.  */
  872. #include <X11/Xatom.h>
  873. Window GetVRoot(dpy, scr)
  874. Display        *dpy;
  875. int             scr;
  876. {
  877. Window          rootReturn, parentReturn, *children;
  878. unsigned int    numChildren;
  879. Window          root = RootWindow(dpy, scr);
  880. Atom            __SWM_VROOT = None;
  881. int             i;
  882.  
  883.   __SWM_VROOT = XInternAtom(dpy, "__SWM_VROOT", False);
  884.   XQueryTree(dpy, root, &rootReturn, &parentReturn, &children, &numChildren);
  885.   for (i = 0; i < numChildren; i++) {
  886.     Atom            actual_type;
  887.     int             actual_format;
  888.     long            nitems, bytesafter;
  889.     Window         *newRoot = NULL;
  890.  
  891.     if (XGetWindowProperty(dpy, children[i], __SWM_VROOT, 0, 1,
  892.         False, XA_WINDOW, &actual_type, &actual_format, &nitems,
  893.             &bytesafter, (unsigned char **) &newRoot) == Success && newRoot) {
  894.             root = *newRoot;
  895.             break;
  896.         }
  897.     }
  898.  
  899.     XFree((char *)children);
  900.     return root;
  901. }
  902.  
  903. [courtesy David Elliott (dce@smsc.sony.com). Similar code is in ssetroot, a
  904. version of xsetroot distributed with tvtwm. 2/91]
  905.  
  906. A header file by Andreas Stolcke of ICSI on
  907. ftp.x.org:contrib/libraries/vroot.shar functions similarly by providing
  908. macros for RootWindow and DefaultRootWindow; code can include this header
  909. file first to run properly in the presence of a virtual desktop.
  910.  
  911. (Note the possible race condition.)
  912.     
  913. ----------------------------------------------------------------------
  914. Subject: 187)  Can I rely on a server which offers backing store?  
  915.  
  916.     You can assume only that the X server has the capability of doing
  917. backing store and that it might do so and keep your application's visuals
  918. up-to-date without your program's involvement; however, the X server can run
  919. out of resources at any time, so you must be able to handle the exposure
  920. events yourself. You cannot rely on a server which offers backing store to
  921. maintain your windows' contents on your behalf.
  922.  
  923. ----------------------------------------------------------------------
  924. Subject: 188)  How do I catch the "close window" event to avoid "fatal IO error"?
  925.  
  926.     Several windows managers offer a function such as f.kill or f.delete
  927. which sends a message to the application that it should delete its window;
  928. this is usually interpreted as a shutdown message.
  929.     The application needs to catch the WM_DELETE_WINDOW client message.
  930. There is a good example in the xcalc sources in X11R5.
  931.     Motif-based applications should in addition set the resource
  932. XmNdeleteResponse on the top-level shell to XmDO_NOTHING, whether they are
  933. using the Motif window manager or not.
  934.     If the application doesn't handle this message the window manager may
  935. wind up calling XKillClient, which disconnects the client from the display and
  936. typically gives an Xlib error along the lines of "fatal IO error 32 (Broken 
  937. pipe)".
  938.  
  939. [Thanks to Kaleb Keithley, kaleb@x.org; 11/93]
  940.  
  941. ----------------------------------------------------------------------
  942. Subject: 189)  How do I keep a window from being resized by the user?
  943.  
  944.     Resizing the window is done through the window manager; window managers
  945. can pay attention to the size hints your application places on the window, but 
  946. there is no guarantee that the window manager will listen. You can try setting 
  947. the minimum and maximum size hints to your target size and hope for the best. 
  948.     Note that you may wish to reconsider your justification for this
  949. restriction.
  950.  
  951. ----------------------------------------------------------------------
  952. Subject: 190)  How do I keep a window in the foreground at all times?
  953.  
  954.     It's rather antisocial for an application to constantly raise itself
  955. [e.g. by tracking VisibilityNotify events] so that it isn't overlapped -- 
  956. imagine the conflict between two such programs running.  
  957.     The only sure way to have your window appear on the top of the stack
  958. is to make the window override-redirect; this means that you are temporarily
  959. assuming window-management duties while the window is up, so you want to do 
  960. this infrequently and then only for short periods of time (e.g. for popup 
  961. menus or other short parameter-setting windows).
  962.  
  963. [thanks to der Mouse (mouse@larry.mcrcim.mcgill.edu); 7/92]
  964.  
  965. ----------------------------------------------------------------------
  966. Subject: 191)  How do I make text and bitmaps blink in X?
  967.  
  968.     There is no easy way.  Unless you're willing to depend on some sort of
  969. extension (as yet non-existent), you have to arrange for the blinking yourself,
  970. either by redrawing the contents periodically or, if possible, by playing games
  971. with the colormap and changing the color of the contents.
  972.  
  973. [Thanks to mouse@larry.mcrcim.mcgill.edu (der Mouse), 7/91]
  974.  
  975. ----------------------------------------------------------------------
  976. Subject: 192)  How do I get a double-click in Xlib?
  977.  
  978.     Users of Xt have the support of the translation manager to help 
  979. get notification of double-clicking.
  980.     There is no good way to get only a double-click in Xlib, because the 
  981. protocol does not provide enough support to do double-clicks.  You have to do 
  982. client-side timeouts, unless the single-click action is such that you can defer
  983. actually taking it until you next see an event from the server.  Thus, you 
  984. have to do timeouts, which means system-dependent code.  On most UNIXish 
  985. implementations, you can use XConnectionNumber to get the file descriptor of 
  986. the X connection and then use select() or something similar on that.
  987.     Note that many user-interface references suggest that a double-click
  988. be used to extend the action indicated by a single-click; if this is the case
  989. in your interface then you can execute the first action and as a compromise
  990. check the timestamp on the second event to determine whether it, too, should
  991. be the single-click action or the double-click action.
  992.  
  993. [Thanks to mouse@larry.mcrcim.mcgill.edu (der Mouse), 4/93]
  994.  
  995. ----------------------------------------------------------------------
  996. Subject: 193)  How do I render rotated text?
  997.  
  998. The X Logical Font Description was enhanced for R6 to allow embedding a
  999. transformation matrix in certain fields of an XLFD name.  Thus arbitrary
  1000. rotation, scaling, shearing, etc. are possible.  To draw text along an
  1001. arbitrarily sloped line, open a font with the appropriate rotation
  1002. transformation and individually place and draw each character.  Drawing text
  1003. along a curve requires a different font for each character orientation
  1004. needed.  The overhead of opening so many fonts is somewhat mitigated by
  1005. another XLFD extension which allows you to ask for a subset of the
  1006. characters.  See section 4 of xc/doc/specs/XLFD/xlfd.tbl.ms in the R6
  1007. distribution.  Also see The X Resource, Issue Nine, p. 211, "New Font
  1008. Technology for X11R6," by Nathan Meyers.  (Note: due to changes after
  1009. publication deadline, the information in the Meyers paper about the syntax of
  1010. character set subsetting is out of date.) These capabilities are also
  1011. available to an R5 X server using an R6 font server.
  1012.  
  1013. If you are not using R6, your only choice, if you want to stay within the
  1014. core X protocol, is to render the text into a pixmap, read it back via
  1015. XGetImage(), rotate it "by hand" with whatever matrices you want, and put it
  1016. back to the server via XPutImage(); more specifically:
  1017.  
  1018.     1) create a bitmap B and write your text to it.
  1019.     2) create an XYBitmap image I from B (via XGetImage).
  1020.     3) create an XYBitmap Image I2 big enough to handle the transformation.
  1021.     4) for each x,y in I2, I2(x,y) = I(a,b) where 
  1022.         a = x * cos(theta) - y * sin(theta)
  1023.         b = x * sin(theta) + y * cos(theta)
  1024.     5) render I2
  1025.  
  1026. Note that you should be careful how you implement this not to lose bits; an
  1027. algorithm based on shear transformations may in fact be better.
  1028.  
  1029. The high-level server-extensions and graphics packages available for X also
  1030. permit rendering of rotated text: Display PostScript, PEX, PHiGS, and GKS,
  1031. although most are not capable of arbitrary rotation and probably do not use
  1032. the same fonts that would be found on a printer.
  1033.  
  1034. In addition, if you have enough access to the server to install a font on it,
  1035. you can create a font which consists of letters rotated at some predefined
  1036. angle. Your application can then itself figure out placement of each glyph.
  1037.  
  1038. [courtesy der Mouse (mouse@larry.mcrcim.mcgill.edu), Eric Taylor
  1039. (etaylor@wilkins.bmc.tmc.edu), and Ken Lee (now kenton@esd.sgi.com), 11/90;
  1040. Liam Quin (lee@sq.com), 12/90; Dave Wiggins (dpw@x.org), 5/94.]
  1041.  
  1042. InterViews (C++ UI toolkit, in the X contrib software) has support for
  1043. rendering rotated fonts in X.  It could be one source of example code.
  1044. [Brian R. Smith (brsmith@cs.umn.edu), 3/91]
  1045.  
  1046. Another possibility is to use the Hershey Fonts; they are stroke-rendered and
  1047. can be used by X by converting them into XDrawLine requests.
  1048. [eric@pencom.com, 10/91]
  1049.  
  1050. The xrotfont program by Alan Richardson (mppa3@syma.sussex.ac.uk) (posted to
  1051. comp.sources.x July 14 1992) paints a rotated font by implementing the method
  1052. above and by using an outline (Hershey) font.
  1053.  
  1054. The xvertext package by Alan Richardson (mppa3@syma.sussex.ac.uk) is a set of
  1055. functions to facilitate the writing of text at any angle.  It is on ftp.x.org
  1056. as R5contrib/xvertext.5.0.shar.Z.
  1057.  
  1058. O'Reilly's X Resource issue 3 includes information from HP about
  1059. modifications to the X fonts server which provide for rotated and scaled
  1060. text.  The modifications are on ftp.x.org in R5contrib/hp_xlfd_enhancements/.
  1061.  
  1062. Bristol Technology's XPrinter product has extensions to Xlib to rotate text.
  1063. Send email to info@bristol.com for more details.
  1064.  
  1065. ----------------------------------------------------------------------
  1066. Subject: 194)  Why doesn't my multi-threaded X program work (sic) ? 
  1067.   
  1068. Support in Xlib and Xt for multi-threaded X programs is included in X11R6.
  1069. See the documentation for XInitThreads, XtToolkitThreadInitialize, section
  1070. 2.7 of the Xlib specification, section 7.12 of the Xt specification, and the
  1071. article "Multi-Threaded Xlib," The X Resource, Issue 5, by Stephen Gildea.
  1072. The following discussion applies only to pre-R6 libraries:
  1073.  
  1074. You cannot use non-thread aware, non-reentrant libraries with threads.
  1075.  
  1076. If you must do this, you have only one choice: call the functions from the
  1077. initial thread only.
  1078.  
  1079. Why opening windows from other threads causes protocol errors can be
  1080. explained easily: you are accessing shared resources (the display
  1081. structure, the connection to the display, static data in the Xlib) from
  1082. a number of threads at the same time, without using any form of
  1083. exclusive access control.
  1084.  
  1085. [Thanks to casper@fwi.uva.nl (Casper H.S. Dik)]
  1086.  
  1087. ----------------------------------------------------------------------
  1088. Subject: 195)  How can I ensure that only one instance of my application is running?
  1089.  
  1090. There are several mechanisms on the client-side you can use to ensure that
  1091. attempts to run multiple copies of an application are caught; you can use
  1092. them if you know that the second copy of the application will be invoked on
  1093. the same machine or the same network as the first or if you know that they
  1094. share a common view of a file-system. The common license-manager daemons
  1095. operate in this way.
  1096.  
  1097. A simple method that uses the X server as a conduit among several
  1098. applications which may be running on different machines and hence have only
  1099. the X server in common is for the first client to grab ownership of a
  1100. specially-named selection; the selection can be registered with the X
  1101. Registry to ensure its uniqueness. Subsequent invocations of the program can
  1102. check to see whether XGetSelectionOwner() for that selection returns an X
  1103. window; the program logic first checks to see whether or not it is a
  1104. duplicate, exiting if so, and otherwise sets the marker by asserting
  1105. ownership of the selection.
  1106.  
  1107. An alternative method, in which the first application writes a property to
  1108. the root window and subsequent invocations check for the existence of the
  1109. property as a sign that they are duplicate versions, fails both for being
  1110. easy to defeat and for tending to refuse to start up the first application
  1111. when it should do so -- if previous invocations crashed and the X server was
  1112. set not to remove the property when a client disconnects, the property may
  1113. have been left as a marker when it should have been removed.
  1114.  
  1115. [Thanks to Nicholas Young (youngn@logica.co.uk); 4/95]
  1116.  
  1117. Sample code implementing an alternate scheme is available from
  1118.      http://www.wri.com/~cwikla/xcenter/singleLaunch
  1119.  
  1120. ----------------------------------------------------------------------
  1121. Subject: 196)  How can I have two applications communicate via the X server?
  1122.  
  1123. The communication can take place via special property values; the two
  1124. applications can change the value of a property and each watch for changes to
  1125. it. If the communication is two-directional then two properties can be used.
  1126. The technique is appropriate for small messages which can be encoded easily.
  1127.  
  1128. It is expensive and unnecessary to communicate via properties on the root
  1129. window; a window owned by one of the applications is preferable.  There is a
  1130. problem, however, in communicating the window ID from one application to the
  1131. other.
  1132.  
  1133. The application owning the window can assert ownership of a specially-named
  1134. selection; the selection can be registered with the X Registry to ensure its
  1135. uniqueness. The second application loops, requesting the value of the
  1136. selection; the first application encodes the ID of its window and sends it.
  1137. The second application can then use XSelectInput() to get PropertyNotify
  1138. events on that window.
  1139.  
  1140. Thereafter, communication is via that window via XGetWindowProperty() and
  1141. XChangeProperty().
  1142.  
  1143. Watch also for the deletion of the property in order to disconnect properly;
  1144. one of the applications may have exited.
  1145.  
  1146. ----------------------------------------------------------------------
  1147. Subject: 197)  Where can I get information on internationalizing applications?
  1148.  
  1149. See http://www.vlsivie.tuwien.ac.at/mike/i18n.html and
  1150. ftp://ftp.vlsivie.tuwien.ac.at//pub/8bit/i18n-programming .
  1151.  
  1152. ----------------------------------------------------------------------
  1153. Subject: 198)  What is the X Registry? (How do I reserve names?)
  1154.  
  1155. There are places in the X Toolkit, in applications, and in the X protocol
  1156. that define and use string names. The context is such that conflicts are
  1157. possible if different components use the same name for different things.
  1158.  
  1159. The X Consortium maintains a registry of names in these domains:
  1160. orgainization names, selection names, selection targets, resource types,
  1161. application classes, and class extension record types; and several others.
  1162.  
  1163. The list as of April 1994 is in the file xc/registry in the R6 distribution.
  1164. The current Registry is also available by sending "send docs registry" to the
  1165. xstuff mail server.
  1166.  
  1167. To register names (first come, first served) or to ask questions send to
  1168. xregistry@x.org; be sure to include a postal address for confirmation.
  1169.  
  1170. [11/90; condensed from Asente/Swick Appendix H; 1/94]
  1171. ----------------------------------------------------------------------
  1172.  
  1173. David B. Lewis                     faq%craft@uunet.uu.net
  1174.  
  1175.         "Just the FAQs, ma'am." -- Joe Friday 
  1176.