|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T d
Length: 20859 (0x517b) Types: TextFile Names: »ddX.doc«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki └─⟦526ad3590⟧ »EUUGD11/gnu-31mar87/X.V10.R4.tar.Z« └─⟦2109abc41⟧ └─⟦this⟧ »./X.V10R4/X/ddX.doc«
Copyright Massachusetts Institute of Technology 1985, 1986 Changes from Release 3. StippleFill to keep CAD people happy.... This file briefly documents the device-dependent interface routines that must be implemented for each new device. The file Xdev.h describes the format of various objects manipulated by the device-dependent layer. The file vsinput.h describes the format of the event queue, mouse cursor coordinates, and mouse motion box; these are the least likely to be portable across a range of device drivers and operating systems. However, only a partial attempt has been made to parameterize the code for alternatives, as they will almost certainly depend on what the device driver provides. An implementor would do well to look at the VS100 library and device driver, as well as the public parts of the QVSS implementation, and crib as much code as possible. The input side is basically an exercise in avoiding system calls, using shared memory between the device driver and the X server. In the DEVICE structure, ->mouse, ->mbox, and ->queue must point to memory shared between the driver and the server. The event queue is a fixed length circular buffer. Current experience suggests that 64 entries is sufficient. In the vsEventQueue, ->events points at the base of the buffer, and ->size is the number of event structures (only size-1 events can actually be stored). The ->head and ->tail are indexes into the queue; both should start at 0. The device driver increments tail (and wraps) after writing an event; the server increments head (and wraps) after it reads an event. The queue is empty when head equals tail, and the queue is full when ((tail + 1) MOD size) equals head. The driver must implement FREAD select to indicate a non-empty queue. To avoid queue overflow, the driver might want to compact motion events: if the mouse moves and the last event in the queue is a motion event, and it is not the only event in the queue, then update the existing event rather than append a new one. The contents of motion events, other than the ->vse_type field, are completely ignored. Motion events are simply treated as hints, and the cursor coordinates are read from DEVICE->mouse. The driver must keep these coordinates up to date. Implementation of the motion box DEVICE->mbox is optional, but it cuts down enormously on needless context switches when the mouse is moving. As long as the mouse is inside the box, motion events need not be added to the queue. If the mouse goes outside the box, then the driver should trash the box, e.g., by setting mbox.bottom to 0, and start generating motion events again. If the input queue cannot be implemented directly in the driver, but an FREAD selectable file descriptor can be provided, then an alternate input mechanism can be defined by calling (from OpenDisplay or InitDisplay) the external routine Define_input_handler (func) int (*func)(); with a routine to be called whenever the file descriptor is readable. The routine takes no arguments, and the return value is ignored. It should read all pending input data, without blocking. For button and keyboard input, it should create standard format event structures and call the external routine Deal_with_input (ev) vsEvent *ev; with them. For mouse motion, it should simply call the external routine Deal_with_movement () after first setting the cursor coordinates in DEVICE->mouse. Note that this form of implementation might lead to poorer interactive response than a mapped input queue, since select() is only called when there are no buffered input requests to process. A handler routine should not be defined unless one is needed. Certain implementations may want to perform various operations just before the server blocks waiting for input. For example, it may be necessary to flush DMA buffers, or repaint a software-maintained cursor. This can be accomplished by calling (typically from OpenDisplay or InitDisplay) the external routine Define_block_handler (func) int (*func)(); with a routine to be called whenever the server is about to go blocked. The routine takes no arguments, and the return value is ignored. A handler routine should not be defined unless one is needed. Similarly, certain implementations may want to perform various operations just after the server unblocks. For example, it might be deemed adequate to erase a software-maintained cursor at this point, rather than checking on each output request if the cursor is still on-screen and in a region about to be over-written. (Note, however, that the server may not actually do any output before going blocked again.) This can be accomplished by calling (typically from OpenDisplay or InitDisplay) the external routine Define_wakeup_handler (func) int (*func)(); with a routine to be called whenever the server unblocks. The routine takes no arguments, and the return value is ignored. A handler routine should not be defined unless one is needed. ProcessInput (ev) vsEvent ev; Called for each keyboard/button event received. Only vse_type will have been looked at so far. After any necessary translation (e.g., convert keyboard codes to LK201 standard), call the external routine Deal_with_input (ev) vsEvent *ev; to have the event handled. For translation to multiple events, call Deal_with_input with each one. Can modify event argument (e.g., insert new keycode) before each call. See lk201.c for example. Note that, for historical reasons, the vse_key value for buttons is backwards from what X uses: left is 0, middle is 1, and right is 2. For host memory allocation, library routines can use the external routines: char *Xalloc (amount) int amount; char *Xrealloc (ptr, amount) char *ptr; int amount; which are guaranteed not to return a NULL pointer. int OpenDisplay (display) char *display; /* display number */ Opens display device. Returns device file descriptor or -1 (and sets errno). Descriptor will (only) be used in select() call to wait for input. int InitDisplay (info) DEVICE *info; /* device data */ Fills in device data. Returns 0 or -1 (and sets errno). Does any additional necessary device initialization, e.g., maps the event queue, downloads firmware into VS100. Called after OpenDisplay. int DisplayDead () Tests if display is powered up and functional. Returns 0 (alive) or -1 (dead). Device should, if possible, send SIGHUP to process on power-up. InitMouse () Does any mouse-specific initialization required, e.g., attaches cursor to mouse, enables mouse motion events. Called after first LoadCursor() call. caddr_t AllocateSpace (bytes) int bytes; /* number of bytes to allocate */ Returns pointer to buffer of indicated size. Returns NULL if no room. Called at most once per output request, for creating CLIP list for an output request. Should NOT be malloc'ed on each call! Should either return a pointer to a static buffer, or malloc only when the request is larger than what has already been malloc'ed. For the semantics of output operations, refer to the corresponding protocol request descriptions in X.doc. Device errors during the following output operations can be logged by calling the external routine DeviceError (why) char *why; In the following routines, clipcount is always greater than 0, and clips[0] should NEVER be modified when clipcount = 1. Any arguments carried over directly from protocol request will conform to requirements stated in X.doc For example, display function is guaranteed in the range 0-15, tiles are guaranteed to have ->tile set. "Extra" bits in zmasks and pixel values are not guaranteed to be zero. Coordinates are all absolute, with (0,0) being the upper left corner of the screen. PixFill (srcpix, xymask, dstx, dsty, width, height, clips, clipcount, func, zmask) int srcpix; /* source pixel */ BITMAP *xymask; /* source mask or NULL */ int dstx, dsty; /* destination */ int width, height; CLIP *clips; /* clipping rectangles */ int clipcount; /* count of rectangles */ int func; /* GX display function */ int zmask; /* plane mask */ See X_PixFill. TileFill (tile, xoff, yoff, xymask, dstx, dsty, width, height, clips, clipcount, func, zmask) PIXMAP *tile; /* source tile */ int xoff, yoff; /* tile origin */ BITMAP *xymask; /* source mask or NULL */ int dstx, dsty; /* destination */ int width, height; CLIP *clips; /* clipping rectangles */ int clipcount; /* count of rectangles */ int func; /* GX display function */ int zmask; /* plane mask */ See X_TileFill. int StippleFill (srcpix, xoff, yoff, stipmask, dstx, dsty, width, height, clips, clipcount, func, zmask) int srcpix; /* source pixel */ int xoff, yoff; /* stipple origin */ BITMAP *stipmask; /* stipple mask */ int dstx, dsty; /* destination */ int width, height; CLIP *clips; /* clipping rectangles */ int clipcount; /* count of rectangles */ int func; /* GX display function */ int zmask; /* plane mask */ See X_StippleFill. Returns 0 and sets errno to EINVAL if stipmask shape can't be handled, else returns non-zero. PixmapPut (src, srcx, srcy, width, height, dstx, dsty, clips, clipcount, func, zmask) PIXMAP *src; /* source */ int srcx, srcy; /* region of source */ int width, height; int dstx, dsty; /* destination */ CLIP *clips; /* clipping rectangles */ int clipcount; /* count of rectangles */ int func; /* GX display function */ int zmask; /* plane mask */ See X_PixmapPut. PixmapBitsPut (width, height, format, data, xymask, dstx, dsty, clips, clipcount, func, zmask) int width; /* source width */ int height; /* source height */ int format; /* 0: XY-format, 1: Z-format */ char *data; /* source data */ BITMAP *xymask; /* source mask or NULL */ int dstx, dsty; /* destination */ CLIP *clips; /* clipping rectangles */ int clipcount; /* count of rectangles */ int func; /* GX display function */ int zmask; /* plane mask */ See X_PixmapBitsPut. Source data can be modified if necessary. BitmapBitsPut (width, height, data, fore, back, xymask, dstx, dsty, clips, clipcount, func, zmask) int width; /* source width */ int height; /* source height */ char *data; /* source data */ int fore; /* foreground source pixel */ int back; /* background source pixel */ BITMAP *xymask; /* source mask or NULL */ int dstx, dsty; /* destination */ CLIP *clips; /* clipping rectangles */ int clipcount; /* count of rectangles */ int func; /* GX display function */ int zmask; /* plane mask */ See X_BitmapBitsPut. Source data can be modified if necessary. CopyArea (srcx, srcy, width, height, dstx, dsty, clips, clipcount, func, zmask) int srcx, srcy; /* source */ int width, height; int dstx, dsty; /* destination */ CLIP *clips; /* clipping rectangles */ int clipcount; /* count of rectangles */ int func; /* GX display function */ int zmask; /* plane mask */ See X_CopyArea. Cliplist MUST be processed in given order. PrintText (string, strlen, font, fore, back, charpad, spacepad, dstx, dsty, clips, clipcount, func, zmask) char *string; /* character string */ int strlen; /* string length */ FONT *font; /* source font */ int fore; /* foreground source pixel */ int back; /* background source pixel */ int charpad; /* inter-character pad */ int spacepad; /* space-character pad */ int dstx, dsty; /* destination */ CLIP *clips; /* clipping rectangles */ int clipcount; /* count of rectangles */ int func; /* GX display function */ int zmask; /* plane mask */ See X_Text. Character string can be modified if necessary. PrintTextMask (string, strlen, font, srcpix, charpad, spacepad, dstx, dsty, clips, clipcount, func, zmask) char *string; /* character string */ int strlen; /* string length */ FONT *font; /* font mask */ int srcpix; /* source pixel */ int charpad; /* inter-character pad */ int spacepad; /* space-character pad */ int dstx, dsty; /* destination */ CLIP *clips; /* clipping rectangles */ int clipcount; /* count of rectangles */ int func; /* GX display function */ int zmask; /* plane mask */ See X_TextMask. Character string can be modified if necessary. DrawCurve (verts, vertcount, xbase, ybase, srcpix, altpix, mode, bwidth, bheight, pat, patlen, patmul, clips, clipcount, func, zmask) Vertex *verts; /* vertexes */ int vertcount; /* vertex count */ int xbase, ybase; /* draw origin */ int srcpix; /* source pixel * int altpix; /* alternate source pixel */ int mode; /* 0: solid, 1: dashed, 2: patterned */ int bwidth; /* brush width */ int bheight; /* brush height */ int pat; /* pattern */ int patlen; /* pattern length */ int patmul; /* pattern repeat count */ CLIP *clips; /* clipping rectangles */ int clipcount; /* count of rectangles */ int func; /* GX display function */ int zmask; /* plane mask */ See X_Draw. Vertex list can be modified if necessary. Draw origin must be added to all (absolute) points. Always called with at least one vertex. First vertex will always have VertexDontDraw and will never have VertexRelative. DrawFilled (verts, vertcount, xbase, ybase, srcpix, tile, xoff, yoff, clips, clipcount, func, zmask) Vertex *verts; /* vertexes */ int vertcount; /* vertex count */ int xbase, ybase; /* draw origin */ int srcpix; /* source pixel */ PIXMAP *tile; /* optional tile or NULL */ int xoff, yoff; /* tile origin */ CLIP *clips; /* clipping rectangles */ int clipcount; /* count of rectangles */ int func; /* GX display function */ int zmask; /* plane mask */ See X_DrawFilled. Vertex list can be modified if necessary. Draw origin must be added to all (absolute) points. Always called with at least one vertex. First vertex will always have VertexDontDraw and will never have VertexRelative. PIXMAP *PixmapSave (srcx, srcy, width, height) int srcx, srcy; /* source */ int width, height; See X_PixmapSave. Resulting PIXMAP should have refcnt of 1. Returns NULL if no room. PixmapGet (srcx, srcy, width, height, client, format, swapit) int srcx, srcy; /* source */ int width, height; int client; /* file desc to write to */ int format; /* 0: XY-format, 1: Z-format */ int swapit; /* 1: swap shorts */ See X_PixmapGet. Writes region to client in given format using the external routine: Write (client, buf, total) int client, total; char *buf; Must pad data to a multiple of four bytes. If swapit is set and format is Z with > 8 planes or format is XY, then data must be byte-swapped before calling Write. Data can be swapped by using the external routine: Swap_shorts (ptr, total) short *ptr; int total; where total is the number of shorts (not bytes) to swap. ResolveColor (red, green, blue) unsigned short *red, *green, *blue; /* update in place */ Modifies values to closest values supported by hardware. Usually involves masking low-order bits. StoreColors (count, entries) int count; /* number of entries */ ColorDef *entries; See X_StoreColors. All entries will be guaranteed to have legal color map indexes. FONT *GetFont (name) char *name; /* font or file name */ Gets and stores a font. Resulting FONT should have refcnt of 1. Should always read a font; sharing is implemented at a higher level. Returns NULL and sets errno to ENOMEM if no room. Returns NULL and sets errno to EINVAL if no such font. Argument name is ephemeral, pointer cannot be used directly in FONT. FreeFont (font) FONT *font; Free font storage and FONT structure itself. Will only be called when when refcnt is zero. int CharWidth (c, font) unsigned c; /* character */ FONT *font; /* font */ Returns width of character, or 0. int TextWidth (string, strlen, spacepad, font) char *string; /* character string */ int strlen; /* string length */ int spacepad; /* space-character pad */ FONT *font; /* font */ Returns width of string with padding. BITMAP *StoreBitmap (width, height, data) int width; /* bitmap width */ int height; /* bitmap height */ char *data; /* bitmap data */ See X_StoreBitmap. Resulting BITMAP should have refcnt of 1. Returns NULL if no room. Source data can be modified, if necessary. Source data is ephemeral, pointer cannot be stored directly in BITMAP. FreeBitmap (bitmap) BITMAP *bitmap; Frees bitmap data and BITMAP structure itself. Will only be called when refcnt is zero. BITMAP *CharBitmap (c, font) unsigned c; /* character */ FONT *font; /* font */ See X_CharBitmap. Resulting BITMAP should have refcnt of 1, or must increment refcnt if sharing is performed. Should not retain pointer into font data, as font may be freed before BITMAP. Returns NULL and sets errno to ENOMEM if no room. Returns NULL and sets errno to EINVAL if no such character. PIXMAP *StorePixmap (width, height, format, data) int width; /* pixmap width */ int height; /* pixmap height */ int format; /* 0: XY-format, 1: Z-format */ char *data; /* pixmap data */ See X_StorePixmap. Resulting PIXMAP should have refcnt of 1. Returns NULL if no room. Source data can be modified, if necessary. Source data is ephemeral, pointer cannot be stored directly in PIXMAP. FreePixmap (pixmap) PIXMAP *pixmap; Frees pixmap data and PIXMAP structure itself. Will only be called when refcnt is zero. If contains a BITMAP reference, should decrement its refcnt and free if zero. PIXMAP *MakePixmap (xymask, fore, back) BITMAP *xymask; /* mask or NULL */ int fore; /* foreground pixel */ int back; /* background pixel */ See X_MakePixmap. Resulting PIXMAP should have refcnt of 1, or must increment refcnt if sharing is performed. Returns NULL if no room. If pointer to xymask is retained in PIXMAP, must increment xymask->refcnt. QueryShape (shape, width, height) int shape; /* 0: cursor, 1: tile, 2: brush */ short *width, *height; /* update in place */ See X_QueryShape. CURSOR *StoreCursor (func, image, fore, back, mask, xoff, yoff) int func; /* GX display function */ BITMAP *image; /* cursor image */ int fore; /* foreground pixel */ int back; /* background pixel */ BITMAP *mask; /* cursor mask or NULL */ int xoff, yoff; /* tip */ See X_StoreCursor and comments in Xdev.h. Resulting CURSOR should have refcnt of 1, or must increment refcnt if sharing is performed. Returns NULL is no room. If pointers to image and/or mask are retained in CURSOR, must increment image->refcnt and/or mask->refcnt. Should do as much processing as possible to minimize LoadCursor time. FreeCursor (cursor) CURSOR *cursor; Free cursor storage and CURSOR structure itself. Will only be called when refcnt is zero. If CURSOR contains any BITMAPs, their refcnts should be decremented and, if zero, the BITMAPs freed. LoadCursor (cursor) CURSOR *cursor; Loads a new cursor. If you need to read the color map, use the external routine: Query_color (pixel, red, green, blue) unsigned pixel; unsigned short *red, *green, *blue; Loading a cursor is assumed to leave the upper left corner fixed, not the tip. SetMouseCharacteristics (threshold, acceleration) int threshold, acceleration; See X_MouseControl. SetCursorPosition (pos) vsCursor *pos; Moves the cursor and updates DEVICE->mouse coordinates. The position is for upper left corner of cursor, not its tip. SetAutoRepeat (onoff) int onoff; /* 0: off, 1: on */ Controls autorepeat of the "main array" of the keyboard (whatever makes sense to autorepeat). If there is a conflict between up/down and autorepeat modes on keys (as with the LK201), turning off autorepeat should enable up/down transitions. SetKeyClick (volume) int volume; /* 0: off, 1-8: on */ Sets key-click volume. SoundBell (volume) int volume; /* 0-7 */ Causes audible bell, with 0 soft but still audible. SetLockLED (onoff) int onoff; /* 0: off, 1: on */ Controls keyboard LED for ShiftLock key, if any. int SetVideo (onoff) int onoff; /* 0: off, 1: on */ Controls video. Returns 0 on success, -1 on failure. For screensaver, X will first attempt to PixmapSave the entire screen. If this fails, it will attempt to disable the video. This may or may not be desirable (or possible).