1 2X11 implementation notes 3------------------------ 4 5(0) Errors. 6 7On the first call to connect to a server, I call XSetErrorHandler to 8install a non-fatal error handler. This handler calls the on_error 9function set by p_handler, reporting a priority 1 error with an error 10message that begins with "Xlib: ". 11 12A more severe problem is the XSetIOErrorHandler routine, which must 13not return. Such an error will result in the on_panic routine set by 14p_panic being called for each screen of the display. 15 16Status returns in Xlib are 0 on failure, non-0 on success. Anything 17returning Status bypasses the error handler set by XSetErrorHandler, 18and must therefore be checked. 19 20(1) Fonts. 21 22----------------------------- 23 24At connect time, XListFonts is used to find as many fonts matching 25"courier", "times", "helvetica", "symbol", and "new century 26schoolbook" as possible. Specifically, in the font list, an attempt 27is made to find medium, bold, italic (or oblique), and bold italic 28versions of all five fonts (this will never succeed with symbol), for 29a total of 20 possible typefaces. For each typeface, I catalog all 30the sizes - in pixels! - the server can provide, sorted according to 31size. For each available size, I store a copy of the font name that 32will retrieve that font later. In the case of a scalable font, this 33name will have wildcard characters for the sizes. (If more than one 34font matches, I take the first in the XListFonts list.) After this 35search, I have recorded all the fonts of interest that exist on this 36server, with the means to retrieve them. For scalable fonts, a call 37to XListFonts will still be necessary in order to get a specific size 38which is not prebuilt. 39 40If a requested typeface is not available, I first check if the 41non-bold, non-italic basic version is present. If not, I check for 42any bold, italic, or bold-italic versions. If none of these is 43available, I try first times, then new century, then helvetica, then 44courier in the requested face, and finally that same sequence in the 45basic face. If this search comes up empty, I fall back to the GUI 46font (see below). Once the typeface is found, I choose the pixel size 47closest to the request, or, if a scalable version is available, I 48construct the exact pixel size requested. 49 50I cache up to 6 fonts to allow switching among several fonts without 51loading and unloading. When the cache is full, the least recently 52used font is unloaded. 53 54Additionally, there is a GUI font which I load at connect time. If 55nothing better can be found, this will be the default font for the 56server (guaranteed to be loaded according to O'Reilly 6.2.2 volume 57one). 58 59----------------------------- 60 61The "standard" pixel sizes are: 62 63points pixels 64 75 dpi 100 dpi 65 8 8 11 66 10 10 14 67 12 12 17 68 14 14 20 69 18 18 25 70 24 24 34 71 72The two 14 pixel fonts sometimes differ by one pixel in average width 73between the 75 and 100 dpi resolutions; I don't distinguish them, and 74use whichever happens to come first in XListFonts. Therefore, a full 75installation of these standard fonts involves 11 sizes for each of 17 76fonts (no bold or italic symbol fonts), for a total of 187 typefaces. 77When scalable fonts are also available, this will be 204 font names to 78be catalogued. X font names have 14 components: 79 80-foundry-family-wgt-slant-wid--pixels-pts-hres-vres-spacing-avgwid-char-set 81 82For the five fonts I care about, I have seen these variants: 83 84 adobe|bitstream-courier-medium|bold-o|i|r-normal-- m iso8859-1 85 adobe-times-medium|bold-i|r-normal-- p iso8859-1 86 adobe-helvetica-medium|bold-o|r-normal-- p iso8859-1 87 adobe-symbol-medium|medium-r|r-normal-- p adobe-fontspecific 88 adobe-new century schoolbook-medium|bold-i|r-normal-- p iso8859-1 89 90----------------------------- 91 92Font rotation is painful. The basic idea is to create an offscreen 93bitmap, draw to the bitmap, read the bitmap back as an XImage, rotate 94the XImage bitmap, then write the bitmap back to a second offscreen 95bitmap. The weird part begins now: You can specify a "stipple" 96pattern when you fill an area; the bitmap containing the rotated text 97can be used as a stipple, so that a call to XFillRectangle actually 98paints the rotated text. This actually perfectly simulates all the 99drawing options available for painting text -- except, of course, you 100can't stipple it (actually you could, by using a counter-rotated 101stipple pattern while drawing the text into the first bitmap). 102 103The hitch is that the XImage interface is botched. The XFree86 source 104(and I suspect vendor X's as well) has a reasonably efficient 105XPutImage call to convert from the myriad image formats to the one 106required by the server. However, XGetImage does not perform any 107conversion, so you get images back in whatever format the server uses 108- making efficient rotation a huge chore. (XGetSubImage looks like it 109would perform the required format conversion, but it turns out to be 110implemented very inefficiently using XGetPixel and XPutPixel -- it's 111not obvious to me why the very same efficient routines used by 112XPutImage could not be used to make XGetSubImage just as efficient. 113It turns out the server doesn't translate either Get or Put requests 114-- this is just a client side issue.) I decided this was an X 115problem, not a Gist problem, and assume that someday, efficient 116versions of XGetSubImage will become the norm. My compromise was to 117use the same image format as the XCreateBitmapFromData functions -- 118namely the format used in all the bitmap files supplied with the X 119distribution. Presumably, this particular format will come early on 120any prioritization of optimizations. 121 122Note that X11 "default" bitmap is 123 124format= XYPixmap 125bit_order= LSBFirst 126byte_order= LSBFirst (unused) 127bitmap_unit= 8 128bitmap_pad= 8 129xoffset= 0 130no extra bytes per line 131 132(This is what is required for input to XCreateBitmapFromData, and 133handled by XReadBitmapFile and XWriteBitmapFile.) 134 135----------------------------- 136 137 138(2) Colors. 139 140I support three color models: standard colors, palette colors, and rgb 141colors. Palettes are restricted to 240 colors, which leaves room for 142up to 16 standard colors within a 256 color colormap. 143 144A huge amount of work is required to intelligently handle the case of 145the PseudoColor visual; the other visuals (StaticGray, GrayScale, 146StaticColor, TrueColor, and DirectColor) are relatively simple. 147 148First, for DirectColor or GrayScale, I create a single colormap (256 149r=g=b=index colors) at p_connect time, and arrange for it to be 150installed on every window. This effectively reduces the case of 151DirectColor to TrueColor, and the case of GrayScale to StaticGray. I 152do not support color table animation; therefore the TrueColor and 153StaticGray visuals are functionally equivalent to DirectColor and 154GrayScale, respectively. 155 156Now, for any visual other than PseudoColor, XAllocColor immediately 157gives the closest match possible to any rgb value on the display. 158 159For PseudoColor, I support two modes of operation for every toplevel 160window -- shared and private colormaps -- controlled by the P_PRIVMAP 161hint passed to the p_window function. Shared colormap windows always 162use the default colormap for the screen; each private colormap window 163has its own colormap (they can't share each others maps). In the case 164of private colormaps, I take care to reduce colormap flashing by 165allocating all the standard colors at the same pixel they have in the 166default colormap for the screen, and by allocating palette colors from 167the top down (since most X servers seem to allocate them from the 168bottom up). 169 170At the first reference to an rgb-model color in a PseudoColor window, 171I install a 5-9-5 (5 reds, 9 greens, 5 blues) colormap. All 172subsequent palette-model or rgb-model colors are approximated as well 173as possible from within this 595 colormap. (This matches Mesa's 174strategy for 8-bit deep screens.) Once this 595 colormap is 175installed, it will persist, with p_palette calls allocating 176palette-model colors from this 595 map instead of changing colormap 177colors. Destroying the window is the only way to return to a "normal" 178colormap in which an attempt is made to get the exact rgb values 179requested for palette-model colors. 180 181One final complexity is that offscreen pixmaps cannot have their own 182colormaps under X. Thus, an offscreen uses the colormap of its parent 183window, and calls to p_palette or references to rgb-model colors when 184drawing to an offscreen pixmap will change the colormap of the parent 185window as a side effect. 186 187 188 189----------------------------- 190 191(3) Events. 192 193The x11_create function creates a new window, and attaches its p_win 194struct to the window via a hashtab for later retrieval. There is one 195hashtab per display; the effect is the same as the XContext mechanism. 196The x11_create function also calls XSelectInput to determine which X 197events the window will receive. 198 199Toplevel windows additionally may require setting window properties to 200communicate with the window manager (WM_DELETE_WINDOW is the most 201important). And menus require both the override_redirect property and 202save_under property. 203 204All button press events are selected with OwnerGrabButtonMask, and 205pointer grabs are made with owner_events True. This forces the X 206server to do the geometry calculation. However, I intend that the 207higher level platform independent event handlers will allow for some 208variation in the details of event delivery semantics. 209 210One "event" in the sense of the basic input event manager consists of 211all the data readable on the X socket, which may be several or many X 212events. Callbacks for all of these occur without polling for any new 213input in between. 214 215----------------------------- 216 217(4) X Resources. 218 219Window class names for all resources is "Gist". (Toplevel windows 220will have class "Gist", unless created with the P_DIALOG hint, in 221which case they have class "GistDialog".) All resources can be 222overridden by setting external program variables before making a 223connection (via p_connect or, for the colors, p_multihead). 224 225X resources are: 226 X resource program override variable 227 -------------------------------------- ------------------------- 228 boldfont (preferred) or font (or Font) x_xfont 229 foreground (or Foreground) x_foreground 230 background (or Background) x_background 231 guifg x_guifg 232 guibg x_guibg 233 guihi x_guihi 234 guilo x_guilo 235 236defaults: 237 font: 9x15 238 fixed 239 <font in default GC on root window> 240 foreground: black 241 background: white <if foreground closer to black than white> 242 black <if foreground closer to white than black> 243 guifg: foreground 244 guibg: background 245 guihi: <none> 246 guilo: <none> 247 if the hilight or lolight color is not specified, use a 2x2 248 gray bitmap with FillOpaqueStipple to draw hi or lo regions 249 the fg color of the hi stipple is always white; the foreground 250 color of the lo stipple is always black 251 the bg color of the stipple (for either hi or lo) is the 252 "background" color, unless that is too close to white or black, 253 in which case the stipple bg is the "foreground" color 254 255A 3d effect is generated by drawing the top and left sides of boxes 256hi, and the bottom and right sides of boxes lo. 257