aboutsummaryrefslogtreecommitdiff
path: root/vendor/x11iraf/xgterm/NOTES
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/x11iraf/xgterm/NOTES')
-rw-r--r--vendor/x11iraf/xgterm/NOTES959
1 files changed, 959 insertions, 0 deletions
diff --git a/vendor/x11iraf/xgterm/NOTES b/vendor/x11iraf/xgterm/NOTES
new file mode 100644
index 00000000..f14fa19d
--- /dev/null
+++ b/vendor/x11iraf/xgterm/NOTES
@@ -0,0 +1,959 @@
+xgterm.NOTES -- Some random design notes made while writing this code. Not
+intended to be useful to anyone reading this code.
+
+
+To do:
+ Object manager
+ add bitmap support
+ add event handling support
+ Gterm widget
+ add cell array
+ pixrect operations?
+ minor odds and ends
+ Gtermio
+ modify to use object manager
+ add messaging capability
+ GIO
+ add messaging capability
+ modify cell array support as needed
+
+
+Pixmaps
+ cache by name
+ new entry replaces old
+ entries are never freed unless overwritten
+ for lookup, check cache first then look for file (normal resource
+ translation)
+
+ typical bitmap:
+
+ #define opendot_width 16
+ #define opendot_height 16
+ #define opendot_x_hot 7
+ #define opendot_y_hot 7
+ static char opendot_bits[] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x01,
+ 0x60,0x03,0x20,0x02,0x60,0x03,0xc0,0x01,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+
+ types of bitmaps - bitmap, pixmap, cursor
+
+ createBitmap name width height data
+ createPixmap name width height depth fg_color bg_color data
+ createCursor name source mask fg_color bg_color x_hot y_hot
+
+
+Event handling
+
+ addEventHandler <procname> <event-mask> [<event-mask>...]
+ userEventHandler {widget event-type time wx wy rx ry other}
+ where "other" is a event-specific list of fields
+
+Event structs
+
+ event masks, event names are numerous
+ most events have these fields:
+ type, time, x_win, y_win, x_root, y_root other
+ other fields:
+ key: state (key or button mask), keycode
+ button: state (key or button mask), button code
+ motion: state (key or button mask), is_hint
+ crossing: mode (normal, grab, ungrab)
+ focus: mode (normal, grab, ungrab)
+ visibility: state
+ error: error_code, request_code, minor_code
+
+ keycode|button|mode|state
+
+Event masks
+
+ Button1MotionMask
+ Button2MotionMask
+ Button3MotionMask
+ Button4MotionMask
+ Button5MotionMask
+ ButtonMotionMask
+ ButtonPressMask
+ ButtonReleaseMask
+ ColormapChangeMask
+ EnterWindowMask
+ ExposureMask
+ FocusChangeMask
+ KeyPressMask
+ KeyReleaseMask
+ KeymapStateMask
+ LeaveWindowMask
+ NoEventMask
+ OwnerGrabButtonMask
+ PointerMotionHintMask
+ PointerMotionMask
+ PropertyChangeMask
+ ResizeRedirectMask
+ StructureNotifyMask
+ SubstructureNotifyMask
+ SubstructureRedirectMask
+ VisibilityChangeMask
+
+Event names
+
+ ButtonPress
+ ButtonRelease
+ CirculateNotify
+ CirculateRequest
+ ClientMessage
+ ColormapNotify
+ ConfigureNotify
+ ConfigureRequest
+ CreateNotify
+ DestroyNotify
+ EnterNotify
+ Expose
+ FocusIn
+ FocusOut
+ GraphicsExpose
+ GravityNotify
+ KeyPress
+ KeyRelease
+ KeymapNotify
+ LeaveNotify
+ MapNotify
+ MapRequest
+ MappingNotify
+ MotionNotify
+ NoExpose
+ PropertyNotify
+ ReparentNotify
+ ResizeRequest
+ SelectionClear
+ SelectionNotify
+ SelectionRequest
+ UnmapNotify
+ VisibilityNotify
+
+
+GTERM CELL ARRAY
+
+ Colormap
+ use pseudocolor visual if possible
+ a fixed number of well defined sharable, read-only cells
+ a variable number of private read-write cells
+ the private cells are allocated at runtime when the
+ application allocates a colormap
+ the graphcap entry specifies the maximum number of private
+ colormap cells that can be allocated
+ a private colormap is used if the requested cells cannot
+ be allocated
+ there is only one colormap per gterm widget (if there are
+ multiple cell arrays they share the same colormap)
+
+ Cell arrays (obsolete term?)
+ A cell array is mapping of an MxN array of 8 bit pixel values
+ to a region of the screen.
+ The pixel values in a cell array range from 0 to NC, and are
+ contiguous in that range. NC is the number of colors in
+ the gterm colormap. The first few values starting at 0
+ are statically allocated and cell array pixels will
+ normally start at the first dynamically allocated value.
+ The cell array mapping defines the transformation used to paint
+ a region of the Gterm window from the cell array pixels.
+ Scaling and axis flipping are possible.
+ Cell arrays are defined and written to in separate steps. A
+ given write operation may modify only part of the MxN pixels
+ of the cell array.
+
+ New operations
+ write colormap Writes N cells of the gterm colormap starting
+ at a given pixel value.
+
+ define cell array Define transformation for cell array N.
+ Several cell arrays may be active.
+
+ write cell array Write to a subregion of a cell array (operates
+ in cell array pixels, not screen pixels).
+
+ Arbitrary regions of the colormap or a cell array may be
+ modified, allowing for very interactive operations.
+
+ Binary pixel values must be encoded for transmission between the
+ client and server. The simplest encoding adds 040 to the value
+ of each pixel (byte), resulting in a printable byte stream.
+ Control codes may be used for compression schemes.
+
+ Alternative scheme
+ Store cell array in off screen buffer. This is the same as
+ above except that in the above scheme the pixels are not
+ saved.
+ Modifying any pixel data, or editing the mapping causes the
+ affected region of the screen to be rewritten.
+ The advantage of this approach is that operations such as zoom
+ and pan can be implemented merely by modifying the mapping.
+ Given multiple cell arrays, one can also do blink, split
+ screen, etc.
+ Perhaps mappings should be separate from cell arrays. The
+ same array may be mapped to more than one region of the
+ screen, or a mapping may map portions of more than one
+ array.
+ Fundamental items are pixel array, mapping, colormap
+
+ Pixmap operations
+ Create host or display pixmap
+ Destroy pixmap (or all such pixmaps)
+ Copy data to/from pixmap and screen
+ Read a file into a pixmap or series of pixmaps
+ Append pixmap to a file
+
+ Should be combined with Obm capabilities for creating and
+ referencing pixmaps.
+
+ Pixmap operations can be used for a number of purposes,
+ including movie making.
+
+Imaging Procedures
+
+ Images (rasters) are implemented internally in Gterm using either
+ ximages or off screen pixmaps. Which format is used is decided at
+ raster create time and is controlled by a Gterm resource. This is
+ transparent to the client application. Currently only 8 bit rasters
+ are supported.
+
+ GtRasterInit (gt)
+ GtAssignRaster (gt, raster, drawable)
+ GtCreateRaster (gt, raster, type, width, height)
+ GtDestroyRaster (gt, raster)
+ exists = GtQueryRaster (gt, raster, &width, &height)
+ n = GtNRasters (gt)
+
+ GtWritePixels (gt, raster, pixels, x1, y1, nx, ny)
+ GtReadPixels (gt, raster, pixels, x1, y1, nx, ny)
+ pixmap = GtCreatePixmap (gt, src, x, y, width, height)
+ GtCopyPixmap (gt, pixmap, dst, x, y, width, height)
+
+ GtWriteColormap (gt, first, nelem, r, g, b)
+ GtReadColormap (gt, first, nelem, r, g, b)
+
+ GtInitMappings (gt)
+ GtCopyRaster (gt, rop, src,sx,sy,snx,sny, dst,dx,dy,dnx,dny)
+ GtSetMapping (gt, mapping, src,sx,sy,snx,sny, dst,dx,dy,dnx,dny)
+ GtGetMapping (gt, mapping, src,sx,sy,snx,sny, dst,dx,dy,dnx,dny)
+ GtEnableMapping (gt, mapping, enable)
+ GtRefreshMapping (gt, mapping)
+
+ For the widget class we can also have commands to operate upon
+ pixmaps created by or written into a gterm widget.
+
+ createPixmap name src [x y width height]
+ copyPixmap name dst [x y width height]
+ destroyPixmap name
+
+ There should also be commands to delete pixmaps, write pixmaps to
+ files, and read pixmaps from files.
+
+ The imaging routines operate in window or pixmap pixels. If a
+ window is resized, any mappings referencing the window are modified
+ to reflect the change in size. A query-size function is required
+ to pass the window size in pixels back to the client. A set-size
+ (resize window) procedure is also desirable to allow the client to
+ attempt to set the window to the optimum size for an image.
+
+ The client uses a special library of procedures for imaging. These
+ use GIO escapes to communicate with the stdgraph kernel. The
+ stdgraph kernel uses special ESC codes to communicate with the
+ server.
+
+ Applications which do only simple imaging will use GIO calls to
+ put a cell array and assign colors, using NDC coordinates for the
+ cell array mapping. More demanding applications that must operate
+ in pixel space, operate directly on image buffers, etc., will use
+ the GIO escapes directly. The stdgraph kernel will keep track of
+ the window size and perform NDC to pixel space conversions for the
+ put cell array call.
+
+
+Implementation
+
+ Code structure
+
+ client
+ gio
+ gim
+ gki_escape
+ | (--IPC--)
+ stdgraph kernel
+ serial encoding
+ | (--IPC--)
+ gtermio
+ obm
+ gterm widget
+
+
+ Simple graphics applications use the high level GIO routines for
+ imaging. These include put/get cell array and put/get colors, with
+ gset being used to select colors for drawing.
+
+ A small library of routines are used in client programs that have
+ more demanding imaging requirements. These are implemented using
+ GIO escapes and operate in pixel space, providing direct access to
+ the gterm imaging functions.
+
+ The GIO escapes are processed by the stdgraph kernel. This uses ASCII
+ escape sequences defined in graphcap to communicate with the server.
+ The GIO escape codes are defined in lib$gescape.h.
+
+ The gtermio code in Xgterm processes these escape sequences and
+ converts them into calls to the imaging routines in the gterm widget.
+
+ The object manager also provides routines for calling the gterm
+ imaging routines from within UI code.
+
+ The actual Xlib based imaging code is in the gterm widget.
+
+
+Complications
+
+ Cursor mode - wants to buffer all GKI instructions, including the
+ GIM escapes, some of which are voluminous. If any interactive image
+ editing, redrawing, etc. is done without initializing things, this
+ could be a lot of data. Would like cursor mode to work in the sense
+ that one can redraw the screen, zoom and pan.
+
+ Cursor readback - for a cursor read within a mapped region of the
+ screen, the logical thing is to return raster coordinates rather
+ than Tek window coordinates. The server should make the mapping
+ transparent, so that the client gets raster coordinates regardless
+ of the image offset, scale, any axis flip, and so on.
+
+ Cursor mode strategy - all GIM escapes issued by the client are
+ executed, but only setmapping instructions are buffered. During a
+ cursor mode redraw the setmapping instructions are edited to reflect
+ the cursor mode zoom/pan (this should be done by a GIM routine), and
+ retransimitted to the server at the time that they are encountered
+ in the display list. In most cases this will result in the image
+ data being redrawn at the appropriate time, e.g. after a frame draw
+ and area clear, and before any overlaid graphics is drawn.
+
+ This requires that the server not initialize the imaging system on
+ every frame clear (probably the imaging subsystem should be
+ initialized when the cursor mode frame buffer is cleared, rather
+ than when the server screen is cleared). The space required to
+ buffer setmapping instructions is mimimal. A disadvantage is that
+ :.write/read will not save or redisplay image data. The major
+ advantage is that this provides full cursor mode zoom/pan capability
+ and is time and space efficient.
+
+ To encapsulate manipulation of the GIM escapes in the cursor mode
+ code, a GIM (stdgraph kernel) routine should be called when a GIM
+ escape is executed to edit the instruction, if any, left behind in
+ the cursor mode buffer. This routine will have access to the
+ cursor mode frame buffer and will edit it as necessary, e.g.
+ deleting the instruction, replacing it, or editing earlier GIM
+ escapes in the same frame buffer.
+
+ Cursor readback strategy - to solve this problem it appears to be
+ necessary to have the server pass back the "cursor number" in a
+ cursor read. When a cursor read occurs there is no way the client
+ can predict which cursor will be read; the server selects the cursor
+ depending upon the pointer location. The cursor number is the Tek
+ cursor, a raster cursor, or a region of a window. The WCS number
+ in the cursor value struct passed back to the client indicates
+ which cursor was read.
+
+
+Timings
+
+ Time to copy 631296 byte text file through a tty/pty
+
+ lepus 8-9sec 70 Kb/sec
+ tucana 2sec 300 Kb/sec
+
+
+Cursor Handling
+
+ The general scheme is that when the cursor is read, the server
+ determines which raster the cursor is in and returns pixel
+ coordinates relative to this raster, regardless of how the raster is
+ mapped to the screen. The return cursor value includes the raster
+ number, pixel X and Y coordinates, and the keystroke (keycode) which
+ terminated the cursor read.
+
+ Since the Tek cursor value struct does not provide adequate
+ resolution or any provision for the raster number, a custom cursor
+ return value is required. gtermio will continue to support a Tek
+ cursor, using a special escape to initiate a custom cursor read.
+
+ gki_retcursor needs to be modified to provide more coordinate
+ resolution and to allow the "cursor" (raster) number to be returned.
+
+ In cursor mode, WCS selection will use the CN/raster number instead
+ of screen position to determine the WCS to be used. A WCS maps a
+ range of world coordinates (e.g. image pixel coordinates) to a
+ viewport in NDC space.
+
+
+Current cursor mechanism
+
+ ESC SUB - initiate standard Tek cursor read
+ user types key to terminate graphics input mode
+
+ server returns cursor value encoded as
+ key
+ hix; lox
+ hiy; loy
+ trailer1; trailer2
+ x, y are encoded in Tek screen coordinates, 0-1023,0-779
+
+ gki_getcursor (fd, x, y, key, cursor)
+ stg_getcursor (cursor number)
+ call stg_readcursor to read cursor
+ returns GKI cursor value struct
+ cursor number, x, y, key
+
+ stg_readcursor (cursor, x, y, key)
+ stg_rdcursor (tty, cursor, x, y, key, output_rc)
+ set raw mode
+ getc until pattern is matched
+ clear raw mode
+ stg_encode to decode cursor value
+ return x, y, key
+
+ rcursor (fd, curval, maxch)
+ grc_cursor (rc, stream, x, y, key, ppos) (screen)
+ gtr_readcursor (stream, x, y, key) (screen)
+ gki_getcursor (fd, mx, my, key, 0) (GKI)
+ grc_scrtowcs (stream, x, y, xc, yc, wcs) (WCS)
+ grc_scrtondc (sx, sy, mx, my) (NDC)
+ wcs = grc_selectwcs (tr, mx, my)
+ grc_settran (w, ct)
+ grc_ndctowcs (ct, mx, my, wx, wy) (WCS)
+ format and return cursor value as a string (WCS)
+
+ screen coordinates - workstation screen/window
+ NDC coordinates - normalized screen coordinates (no zoom)
+ WCS coordinates - world coordinates in active WCS
+
+ WCS - max 16 per screen
+ wx1,wx2,wy1,wy2 range of world coordinates
+ sx1,sx2,sy1,sy2 viewport, NDC coordinates
+ xtran, ytran type of transformation in each axis
+ clip flag to clip at viewport boundary
+
+ WSTRAN - cursor mode ndc-to-screen
+ vx1,vx2,vy1,vy2 range of NDC coordinates
+ mx1,mx1,my1,my2 range of GKI coordinates
+
+
+Cursor mechanism with rasters
+
+ The key concept underlying this scheme is that GKI (NDC) coordinates
+ refer to the "raster" the cursor is in, rather than to the screen,
+ hence are independent of the raster-to-screen mapping. One
+ logically draws into a raster, and any mappings defined on the
+ raster take care of rendering the graphics on the screen. A cursor
+ read returns both screen coordinates, used for cursor mode zoom/pan,
+ and image raster GKI/NDC coordinates. A special case is raster 0,
+ the screen (actually the drawing window), which is what GKI/NDC
+ coordinates always referred to in the past. When drawing into
+ raster 0 one is drawing directly to the screen. When drawing into a
+ raster, one is still drawing to the screen, but via any mapping or
+ mappings defined on the raster.
+
+ Each raster has zero or more WCS associated with it. The WCS
+ associated with the raster defines a mapping between some world
+ coordinate system, e.g., image pixel coordinates, and NDC or
+ normalized raster coordinates. To get from world coordinates to
+ pixels on the screen, one converts from world coordinates to NDC
+ coordinates via the WCS, then from NDC coordinates to raster pixels,
+ then from raster pixels to screen pixels via the mapping. To be
+ more precise, the full transformation is as follows:
+
+ GIO in the client:
+ world -> NDC
+ NDC -> GKI (clipped at viewport)
+
+ Cursor mode in the CL:
+ GKI to "screen" (zoomed/clipped-GKI) coordinates
+ zoomed-GKI to Tek coordinates for serial protocol
+
+ Gtermio code in the server:
+ Tek coordinates to raster pixel coordinates for current
+ drawing raster
+
+ Gterm widget code:
+ raster pixel coordinates to screen pixel coordinates
+ via a mapping defined on the raster
+ repeat for each mapping defined on the raster
+
+ Graphics drawing for raster overlays requires that the server treat
+ the input Tek encoded coordinates (1024x780) as normalized for the
+ current raster. If the raster number is zero the normal drawing
+ operation (into the display window) takes place. If the raster
+ number is nonzero any mappings defined on the referenced raster
+ define where the graphics is drawn on the screen. If a mapping is
+ disabled no drawing takes place. Graphics are automatically clipped
+ at the boundary of the destination rect defined by a mapping.
+
+ In a cursor read operation, the server determines which raster if
+ any is mapped to the region of the screen the cursor is in. Both
+ screen (raster 0) and raster coordinates are returned using a
+ special cursor value struct. The cursor value return by RCURSOR
+ (hence =gcur and clgcur) returns the world coordinates defined by
+ the selected WCS for the current raster. If no WCS is defined NDC
+ coordinates are returned. If multiple WCS are defined for a raster
+ cursor mode selects the "nearest" viewport as it has always done
+ for screen coordinates.
+
+ About the only alternative to the above scheme is to have the server
+ return raster pixel coordinates. The problem with this is that this
+ is inconsistent with the GIO graphics model, and the WCS cannot be
+ used to return world coordinates, or to draw graphics overlays.
+
+ A complication with this scheme is that normally WCS 1 is used for
+ the screen (raster 0). Sometimes more than one WCS is used. Hence
+ to make a strict association between WCS number and raster number
+ would require that raster numbers be allocated accordingly in the
+ client. Also it is not clear what happens if there is more than one
+ WCS defined for a raster. To get around this problem a way is
+ needed to define which raster a WCS refers to. This can be done
+ without a (significant) protocol change by encoding the frame number
+ in the existing, little used WCS_CLIP field of the existing WCS
+ structure.
+
+
+Colormap Sharing
+
+ A gterm resource selects type of colormap: default, private, shared
+ default means default screen colormap, shared by all apps
+ private means colormap is used only by this gterm instance
+ shared means non-default colormap shared by multiple gterms
+
+ In the case of the default colormap, read-only or read-write cells
+ are allocated out of the screen default colormap. This guarantees
+ that the colors of non-gterm windows will not be affected when gterm
+ colors are allocated, but it may not be possible to allocate all
+ requested colors, or having allocated these colors to a gterm
+ widget it may not be possible to run other applications. Use of
+ the default colormap is appropriate for applications that do not
+ use many colors.
+
+ A private colormap is allocated and used by only a single gterm.
+ This guarantees that the expected number of colors will be available,
+ and prevents one gterm from changing another's colors. The main
+ disadvantage is that the window will go black (or whatever) when
+ the pointer is not in the window.
+
+ A shared colormap is a non-default (custom) colormap shared by
+ multiple gterms. Allocation of colors is guaranteed, but when one
+ gterm modifies the colormap all gterms using the shared colormap
+ are affected. They are however still visible and if they contain
+ similar data the display may still appear reasonable. There can
+ be multiple shared colormaps, each with a different name.
+
+ It is possible to use a trick to minimize colormap flashing when
+ private or shared colormaps are used. This works so long as the
+ default colormap has only a limited number of colors allocated,
+ and the gterm client needs only a limited number of colors (e.g.
+ 200 or so out of 256). The trick is to allocate as many colors as
+ possible from the default colormap, assigning the same pixels for
+ colors in the custom colormap. The default colormap is then copied
+ to the private (or shared) colormap, and the new colors are stored
+ in both colormaps. The newly allocated colors are then freed in
+ the default colormap. The custom colormap will then inherit most
+ of the color assignments of the default colormap, and in turn the
+ default colormap may still have the initial color assignments from
+ the custom colormap.
+
+ Differences will appear as both colormaps change thereafter, but in
+ practice many color assignments are fairly static so colormap
+ flashing should be minimized. The default colormap can be updated
+ periodically by repeating the allocate, store, copy, and free
+ sequence, e.g., when the custom colormap is modified.
+
+ Custom gterm colormap allocation strategy: in the normal case reserve
+ 216 colors for private use. The remaining cells are copied from the
+ default colormap to minimize colormap flashing. If the gterm client
+ requests more than 216 colors the full colormap is allocated.
+
+ 0 - 37 copied from default colormap
+ 38 - 253 reserved for gterm client
+ 254 - 255 copied from default colormap
+
+ The point where the gterm colormap starts (e.g. 38) should be defined
+ by a resource as there is no guarantee which end of the default
+ colormap static colors will be allocated at.
+
+ if (use default colormap) {
+ allocate read-write cells
+ store colors
+ } else {
+ if (don't have colormap yet) {
+ map colormap name to atom
+ if (named gterm colormap not found) {
+ # Create gterm colormap.
+ open connection to display
+ create colormap, allocate all colors
+ call XSetRGBColormaps to set colormap property
+ call XSetCloseDownMode to make colormap permanent
+ close display
+ } else {
+ call XGetRGBColormaps to get colormap property
+ get colormap id
+ }
+ set colormap id for gterm window
+ call XSetWMColormapWindows to notify WM of custom colormap
+ }
+ store new colors in custom colormap
+ if (match colormaps) {
+ copy global cells from default colormap
+ attempt to allocate cells in default colormap
+ attempt to store new colors in default colormap
+ free cells allocated above
+ }
+ }
+
+ If the gterm widget has a private colormap different than that of
+ its top level window, XSetWMColormapWindows must be called for gterm
+ window focus in/out events to indicate to the WM that the colormap
+ for the gterm window is to be loaded.
+
+
+Windowing the Display
+
+ Given a range of display pixel values and a normalized colormap,
+ apply a threshold/gain transformation to window the display (i.e.,
+ write new screen colormap). This needs to be done in the UI to
+ provide acceptable interactive response.
+
+ GtWindowDisplay (gw, offset, slope)
+
+ offset (0.5 +/- X) center of windowed region
+ slope (+/- X) slope of transfer function
+
+ The transfer function is applied to the normalized colormap
+ and the output colormap is written to the screen.
+
+ To window over a greater dynamic range one must regenerate the
+ display pixel values from the raster or image (this can be done by
+ the client). For example, the client application can display a
+ histogram and the user can mark the region to be written to the the
+ gterm raster pixels.
+
+ The marker facilities described in the next section can be used to
+ implement real-time display of the grayscale transfer function if
+ desired. The message facility could also be used to transfer the
+ image histogram and information about the histogram region loaded
+ into a raster, for use with the transfer function to generate a
+ full display of the grayscale mapping from disk image to screen.
+
+
+Graphics Markers
+
+ A "marker" is a graphics object, defined on a raster, which can be
+ created or destroyed, which can draw itself, or which can modify
+ (move or resize) itself in response to pointer events. Markers have
+ attributes such as the marker type (text, line, circle, polygon,
+ etc.), color, line width, center, width, height, visibility, and
+ sensitivity. Markers can accept callbacks which are executed when
+ the object is interactively moved or resized.
+
+ Markers can be used to annotate a window, as if one were drawing
+ into a window. The chief difference between a marker and a simple
+ drawing operation (such as a polyline) is that markers are not just
+ lines on the screen, but actual objects capable of responding to
+ requests or taking independent action.
+
+ Generic functions
+
+ create
+ destroy
+ copy
+ set attribute
+ get attribute
+ raise, lower
+
+ Generic attributes
+
+ type
+ visibility
+ autoRedraw
+ sensitivity
+ foreground, background text markers
+ linecolor, linewidth
+ knotcolor, knotsize
+ fillcolor, fillstyle polygon markers
+ width, height
+ x, y
+
+ Marker types
+
+ text font, string
+ line vertices
+ box
+ rectangle
+ circle
+ ellipse
+ polyline vertices
+ polygon vertices
+
+ Procedures
+
+ gm = GmGreate (gt, type, interactive)
+ gm = GmCopy (gm)
+ GmDestroy (gm)
+ GmAddCallback (gm, func, client_data)
+ gm = GmSelect (gt, x, y, &what)
+
+ GmMarkpos (gm)
+ GmRedraw (gm, func, erase)
+ GmRaise (gm, ref_gm|NULL)
+ GmLower (gm, ref_gm|NULL)
+ GmNotify (gm, events)
+
+ GmAdd (gm, x, y)
+ GmDelete (gm, x, y)
+ GmMove (gm, x, y)
+ GmResize (gm, x, y)
+ GmRotate (gm, x, y)
+
+ GmSetAttribute (gm, attribute, value, type)
+ GmGetAttribute (gm, attribute, value, type)
+ GmSetVertices (gm, points, first, npts)
+ npts = GmGetVertices (gm, points, first, maxpts)
+
+ raster = GtSelectRaster (gt, st, sx, sy, rt, &rx, &ry, &mp)
+ GtMapVector (gt, mp, dir, st, sv, dt, dv, npts, clip)
+
+ Markers operate in screen coordinates (raster 0). The SelectRaster
+ and MapVector routines may be used to convert to and from raster
+ coordinates if desired.
+
+ Actions
+ create (type)
+ destroy marker
+ set (attr, value)
+ raise marker
+ lower marker
+ notify callback
+
+ markpos marker
+ markposAdd marker point button1-down
+ redraw marker button1-up
+ add point
+ delete point
+ deleteDestroy point or marker delete or backspace
+ move marker
+ resize marker
+ moveResize point or marker button1-motion
+ rotate marker shift-button1
+
+ Marker specific functions (internal)
+
+ bool = select (gm, x, y, &what)
+ classinit (gm)
+ markpos (gm, &rect)
+ redraw (gm, function)
+
+ add (gm, x, y)
+ delete (gm, x, y)
+ move (gm, x, y)
+ resize (gm, x, y)
+ rotate (gm, x, y)
+
+ The marker specific functions are the methods for each marker
+ class. The functions add, delete, move etc. merely edit the marker
+ descriptor. A separate call to redraw is required to redraw the
+ modified marker.
+
+ Actions such as deleteDestroy and moveResize will select one of the
+ listed actions based upon the pointer coordinates. For example with
+ moveResize, if the pointer is in the center of a marker the entire
+ marker is moved, and if the pointer is near a point the point is
+ moved or the marker resized depending upon the type of marker.
+
+ The default translations for these actions are shown at the right.
+ These translations are in effect only when the pointer is over a
+ marker that is sensitive and visible. The cursor will change to
+ indicate that the marker is active; the cursor type will indicate
+ whether the entire marker, a single point, or add-point will be
+ selected if button1 is pressed at that location. In addition, the
+ default translation for button1-down for the window is create
+ rectangle. Hence a rectangle object can be created and dragged out
+ with the left button at any time just using the default
+ translations. This can be used prior to executing a command to
+ indicate the region to be operated upon.
+
+ Actions such as move, resize, rotate, etc. do not redraw the object
+ (unless autoRedraw is set). Instead, these actions do a GXor redraw
+ of the marker at the old location, edit the marker according to its
+ type, and then do another GXor redraw at the new location. When
+ tracking the cursor this produces a rubber-band effect. When
+ tracking completes (e.g., button1-up) the screen is refreshed at the
+ markpos position, erasing the old marker, any affected markers are
+ redrawn at the markpos position, and the edited marker is redrawn at
+ the new location.
+
+ A Marker is created with GmCreate. If the interactive flag is set
+ a mode is entered where the mouse is used to set the initial
+ position and size of the object. The cursor changes to indicate
+ that the widget is waiting for input. The user moves the mouse to
+ the position on the screen where the object will go, clicks the left
+ pointer, and then does a drag to set the initial size and
+ orientation of the object. When the button is released the create
+ object operation is complete, unless the marker type is polygon in
+ which case multiple click-and-drag operations are required to
+ interactively define the polygon.
+
+ If the create is not interactive, the GmCreate returns immediately,
+ and SetAttribute calls are used to set the object attributes and
+ then display the object.
+
+ Once a marker has been created the sensitivity attribute controls
+ whether the object can be interactively moved or resized with the
+ mouse. If the marker is sensitive, when the pointer is placed
+ within the marker or near a vertex or edge the cursor will change to
+ indicate that the marker, vertex, or edge can be dragged to move or
+ resize the marker. Alternatively, the delete or backspace key can
+ be used to destroy the marker. This will not actually destroy the
+ marker, but will notify the client (via a callback) that the user
+ has requested that the marker be destroyed.
+
+ When the mouse is near a sensitive marker a special translation
+ table defines the key or pointer bindings associated with the drag,
+ delete, etc. marker actions. Typical bindings would be left pointer
+ for create and drag, middle pointer to terminate a sequence such as
+ when drawing a polygon or to abort a create object, shift left
+ pointer to add a point to an existing polygon, and delete or
+ backspace to delete an object, or in add-point mode, the last vertex
+ in a polygon.
+
+ All the gterm widget need do is, when there is one or more sensitive
+ marker in a window, track the cursor and load the marker translation
+ table when the pointer is over a marker which is sensitive. The
+ rest will be done by the marker actions.
+
+ Markers can be used in UI code to provide a more general method of
+ position input than a cursor read, which can only specify a single
+ point. For example to input a rectangular region, one would do the
+ following:
+
+ UI selects marker type rectangle
+ UI creates a rectangle marker in interactive mode
+ cursor changes to indicate create-object mode
+ user positions mouse and clicks left button
+ holding button down, user drags out the rectangle
+ button up terminates GmCreate
+ UI calls GetVertices and passes polygon back to client
+ UI destroys marker
+
+ If desired, the client application can draw the polygon again
+ using normal graphics drawing commands (i.e., not as a marker).
+
+ To mark a region on a raster in UI code:
+
+ UI creates rectangle object in noninteractive mode
+ visibility and autoredraw are initially false
+ UI calls SetAttribute to set rectangle position, size, etc.
+ UI sets visibility attribute to cause marker to be drawn
+
+ If the region is to be active, e.g. something should happen if the
+ user moves or resizes the region, then the sensitivity should be
+ set to true and a callback can be posted to take some action if the
+ region is changed. For example, this could be used to graphically
+ pan the image or adjust the colormap.
+
+ Markers are only drawn to the screen, never to the screen pixmap.
+ Hence they can be erased by copying from the screen pixmap. If the
+ screen needs to be refreshed the markers are redrawn from the object
+ list maintained internally by the gterm widget.
+
+
+Display of Pixel Dependent Information
+
+ A common feature of image display UIs is the ability to display
+ information about the pixel under the cursor, either in sample mode
+ or continuously as the cursor is moved. For maximum flexibility
+ one must rely upon the client application to return information about
+ a pixel, since usually only the client has full access to the data,
+ and the significance of a pixel can be highly application specific.
+ An example of this is the display of the cursor position and pixel
+ intensity in user coordinates.
+
+ To implement this feature we need the following capabilities.
+
+ o The UI posts a callback procedure which is called whenever
+ the cursor moves, i.e., which receives pointer-moved events.
+
+ o The UI obtains information about the pixel under the pointer
+ from the client.
+
+ o The UI displays this information in a text object, either
+ overlaid on the image or in a separate text display area.
+
+ The WS already provides the ability to post a callback to receive
+ pointer-moved events. What we need is an efficient way to obtain
+ information about the pixel under the cursor. Due to the overhead
+ of the client-server architecture, it is undesirable to query the
+ client every time we need information about a pixel. Hence, we must
+ get information for a block of pixels in single query and cache this
+ information in the server, sending another query only when the
+ pointer moves to a different region of the screen.
+
+ This can be done by sending a request to the client to send a block
+ of information (text) for all the points in a grid in pixel space.
+ The client responds by generating the text as a message to a UI
+ parameter. The UI then needs a way to select text from the UI
+ parameter, and generate another query if the desired data is not
+ cached.
+
+ The cached text consists of a sequence of lines of the form
+
+ raster-x raster-y client-text
+
+ The server will need to cache several such blocks of data, each with
+ a header identifying the raster number and the region of the raster
+ covered by the cached data. The object code in the server will
+ provide convenience routines for managing and searching this data.
+
+
+Text Display Facilities
+
+ Real-time display of pixel information requires some way of
+ displaying the text passed back by the client via the method
+ described in the last section. Text display can be done either
+ using a text widget ouside the gterm window, or using a text marker
+ if the text is to be overlaid on the image. An advantage of using a
+ marker for the text overlay is that since the marker is active, the
+ user can use the mouse to reposition the text on the screen.
+
+
+Translations
+
+ The Widget specifies the default translations. The Widget
+ translations resource specifies replacement, augment, or override
+ translations. Additional augment or override translations may
+ be specified in a function call (e.g. to cause the widget to invoke
+ an application specified menu via a translation).
+
+ On a marker focusout, the widget must restore the gterm window
+ translations.
+
+ At initialize time:
+
+ if (translations resource defined) {
+ if (augment or override translations) {
+ defTranslations = compiled Gterm translations
+ compile auxiliary translations
+ set augment or override flag
+ } else
+ defTranslations = compiled translations resource
+ } else
+ defTranslations = compiled translations resource
+
+ At focusout time:
+
+ SetValues defTranslations
+ for (each auxiliary translation table)
+ augment or override widget translations
+
+ Additional auxiliary widget translations can be specified with
+ GtAugmentTranslations or GtOverrideTranslations.
+
+oo