Table of Contents
Previous Chapter
CHAPTER 9 Interactive Graphics Capability (IGC)
The Interactive Graphics Capability (IGC) is a process that displays meteorological data (satellite images, station plots, radar, gridded model graphics, soundings, etc...) inside an X window.
An IGC process provides some user interface, but the majority of its interface comes from the UI process which is described in Chapter8.
The actual conversion from data to its pictorial form is done by Depictable objects which are described in detail in Chapter10.
This chapter will first discuss the software and hardware issues that influenced the design of the IGC. Then it will describe the IGC process environment, including what the major objects are, what they do, and how they interact with each other. Finally, this chapter will provide step by step descriptions of how the IGC implements its major features such as loading and displaying a product, zooming, looping, sampling, etc.
All workstations developed at FSL prior to the WFO-Advanced were carefully crafted around highly specialized display hardware. The display hardware not only performed many powerful display functions, such as zooming and panning, but also had a unique architecture that supported animation from local display memory and high speed disks. Because of this specialized hardware many display functions were easy to implement, fast in performance, and required very little of the host's processing resources.
FSL's previous workstations used a single large window to display all meteorological data: contours, images, and plots, whether they were generated in advance or interactively by means of an application. However, there was a desire on the part of a number of meteorologists to have an additional display window for the purpose of monitoring weather in a particular area or to display the output of an application, such as a skew-T or a time-series plot. A proposed solution was to create an additional small window along one side of the screen strictly for applications. This would allow the forecaster to look at applications without losing the display in the large window. For closer inspection, the user could transfer the contents of the application window to the large window. At the same time, the contents of the large display would be transferred to the small application window so it would still be visible. This approach, suggested initially for the UNIX PC workstation became easy to implement on a UNIX workstation with the X window system.
The first prototype of this approach was implemented on a Sun Sparc 2 and consisted of one large square window and four small windows to the left side of the large window. For simplicity, a single process controlled and managed the information in all the windows. Since the Sparc2 had only an eight bit (256 colors) lookup table, the images and graphics in the five windows had to share a common lookup table. Before an image was loaded into a window the value of each image pixel was converted to correspond to the appropriate color in the lookup table. As long as all the images and graphics used similar colors this approach provided reasonably good results. However, if one of the images was displayed in the gray scale then the number of available colors and gray scale values became unacceptable. The experience with this prototype resulted in two significant recommendations: 1) increase the number of available colors by using a 24-bit color system, and 2) reduce the complexity of managing five windows by creating a separate process (IGC) for each window.
A prototype was tested on a Sun Sparc 2 GTX workstation with 24 bits of color. The five windows now shared over 16 million colors, more than adequate for all workstation displays. Each pixel of an image was converted and stored as 24 bits of data plus eight bits of zeros to fill a 32-bit computer word. The drawback to this approach was the four-fold increase in computer memory requirements. For an animation sequence of 32 1000x1000-pixel images, the memory requirement rose from 32 to 128 megabytes. This larger size resulted in slower loading and animation rates because considerably more bytes had to be transferred into and out of memory. An interesting side effect on the GTX was the sequential changing of display colors as the red, green and blue values were transferred from memory to the screen.
The introduction of Hewlett Packard workstations with the CRX24 display controller provided additional options for implementing multiple display windows. In addition to its true 24-bit color, the CRX24 supports four separate 8-bit color tables: one table for the image underlay, a second private table for overlays, a third for overlays needed by the X window manager (and also the default), and a fourth for transparent displays. Instead of deciding on either 8 bits or 24 bits of color, it is now possible to consider a hybrid approach using 8-bit and 24-bit colors for the display windows. The suggested approach uses 8-bit colors in the large window and 24-bit colors in the smaller windows. This satisfies the requirement for a full range of 256 colors in all the display windows. Using this approach, the large window requires approximately 32 megabytes and each small window approximately 5 megabytes of memory for a 32-frame animation sequence, for a total of 52 megabytes for all five windows. If additional savings in memory is desired, the maximum animation length in the small windows can be reduced to a smaller number. The total memory requirement for this hybrid approach, even when considering that the host workstation has to drive two monitors, is considered reasonable. Aside from these memory considerations, this hybrid approach also provides acceptable load and animation performance since the images are relatively small in size.
Although this approach adequately addresses the memory and some basic performance concerns, it also results in increased software complexity since the same data must be loaded differently depending on whether they are loaded to an 8-bit or 24-bit window. The display for each small window is prepared in a 24-bit (i.e. 32-bit computer word) pixmap in the host memory. When a satellite image with a graphic overlay is desired, the 8-bit satellite pixels are converted and mapped to a 24-bit pixmap and the vector graphic is then merged with the image in the pixmap. To remove the graphics from the displayed image, the satellite image is reloaded into the pixmap. To avoid the load time from the database, a second pixmap exists for each frame that contains only the image. When interactively moving a graphics line in the small window this second pixmap refreshes the image each time the line is moved. Because the windows are small (200 by 200 pixels), the performance in these small windows is good.
To load the same image and graphics combination described above into the large window requires a different technique. Images are loaded into an 8-bit underlay window and vector graphics are added by using the transparent overlay window. Each vector graphic is prepared as a bit map and combined with other graphics in an 8-bit pixmap. A technique known as "stipple fill" is employed to draw additional graphics into the pixmap. Although not practically useful, as many as 256 graphics can be drawn into the pixmap and displayed in the overlay window.
The complexity of the IGC is increased further by a requirement to subdivide the display window into four separate panels and load each panel with a set of products. This is useful if the user wants to look at radar reflectivity at four different elevation tilts or view different satellite channels. As long as the same color table is needed for all four panels, the large display window can adequately display all products using the 8-bit color architecture. One can assure that the 8-bit color architecture suffices by carefully defining the products that can be loaded into the four panels in advance. However, if the user is given the capability to modify the pre-defined four-panel display by loading new data into a panel then the possibility of exceeding the number of available colors is high. To assure that sufficient colors are always available for all panels, the IGC needs to be able to concurrently support the 24-bit color mode. A special algorithm is implemented that assigns either 8 bits or 24 bits of color to a panel based on the data displayed in the panel. In order to retain good performance, the algorithm tries to assign 8-bit color tables to as many panels as possible and re-examines the assignments each time a new product is loaded.
The common invocation of the IGC is as a child process, invoked by the user interface process (UI process). The parent process is responsible for defining the area in which an IGC will display. For the D2D workspace, the UI will create five X windows and position them inside the UI's application window. All of these windows will be created using the underlay planes of the graphics hardware, and will be capable of displaying images. Four small windows are created with a 24-bit visual, while the large window is created with an 8-bit visual. With this scheme, five images with different color requirements can be displayed simultaneously.
The UI process invokes an IGC process for each of the five display areas, passing the area's X window ID as a process argument. The IGC is allowed to draw into that window, solicit events for that window, and create additional child windows to be displayed on top of that window. However, the UI process is the owner of that window, and is the only process that can destroy it. The UI process can also tell an IGC to use a different window for its layout during a swap operation which is described in detail in Section 9.6.5, "Swapping".
The UI process assigns an ID to each IGC which is also passed as a program argument. Currently the ID is an integer in the range 0..4. The ID is used by the UI process to identify which IGC process is sending an IPC message to the UI.
The UI also informs the IGC whether it is running in a small or large display area through a process argument. An IGC will exhibit the following differences depending on whether it is running in a large or small display area:
- Small IGC's provide a user interface to initiate a swap. Large IGC's do not.
- Small IGC's do not display legends, or provide an interface to operate on legends, since the display area is not big enough. Instead, they display the time of the frame being displayed.
- Small IGC have a smaller maximum frame count than large IGC's which is specified in the configuration file, "config/fxa.config."
The last argument of interest is the IPC target of the parent process. An IGC needs to send messages to the UI process in order to inform the parent of its state, so that the UI can keep its UI widgets in sync with what is being displayed.
As a child process, the IGC is dependent upon the UI process for its user interface. Most of the UI process widgets affect only the IGC in the large display area. Since the IGC is in a different process, commands to initiate IGC actions are in the form of IPC messages.
However, an IGC running as a child process does provide some of its own user interface through the use of the mouse. An IGC can receive these X events directly. These events are enough to manage context-sensitive pop-up menus and some dialog boxes, such as a dialog to choose an overlay graphic's color.
The IGC can be run by itself without having to run the UI process. The advantages of this approach is that the start-up time for a single IGC is much less than start-up time for five IGC processes and a UI process. Also, it is slightly easier to connect a debugger to a stand-alone process. However, without the UI process, the menu bar, control bar, and dialog boxes (including the volume browser) are replaced by a far-less elegant, harder to use keyboard interface. Thus, running as a stand-alone process is useful for developers but not practical for end users.
An IGC requires an X window that defines its display area. The UI normally has the responsibility of creating that window. However, in stand-alone mode, the IGC has to create its own window, which will be a window with window manager decorations whose parent is the root window. If the IGC process is invoked with the "trueColor" argument, then this window will be a 24-bit window. If the IGC_Process is invoked with no arguments, then the window will be an eight-bit window.
Some of the functionality that the UI process provides is implemented in a keyboard interface. For example, to load a product, the user would type in "[<A product key>]". The complete key bindings are described in the file, igc/KeyLegend.Doc.
The user interface provided by the mouse that is available to the IGC as a child process is also available as a stand alone process.
Like many display applications, an IGC process performs initialization, waits for and processes events, destroys its objects, and then terminates.
An IGC does the following during process initialization:
- Initializes OI, which will also initialize Xlib and obtain a connection to the X server. OI is passed the process argument list since it may be interested in some of the arguments such as -display <X Server hostname>.
- Parses the process arguments, as described in Section9.2.1.1 and Section9.2.2.1.
- If the IGC is a stand-alone process, creates an X window on which an IGC display layout will be built.
- Constructs an IGC_Impl object which will construct many of the other main IGC objects. Its constructor is passed many of the parsed process arguments, plus the handle to the X server.
- Constructs an EventDispatcher object. Its constructor is also passed the handle to the X server.
- Constructs a UI_WorkspaceManager object. If the IGC is a child process, then this object is passed the IPC target of the parent process, which is one of the process arguments.
After initialization, an IGC enters an event dispatch loop which is managed by the EventDispatcher object. Execution will remain inside this loop until the EventDispatcher receives an event indicating that the process should be terminated. If the IGC is a child process, this event will be an IPC message from the UI process. If the IGC is a stand-alone process, this event will be an <Alt Q> entered from the keyboard.
After exiting the event dispatch loop, the IGC will destruct the UI_WorkspaceManager, IGC_Impl, and EventDispatcher objects. The IGC_Impl object will then destruct most of the important IGC objects. The EventDispatcher needs to be destructed last, since other IGC objects need to refer to it, upon their destruction.
Destructing objects is important, since the IGC may have started some child extension processes which need to be terminated. Also, the IGC may have registered with the NotificationServer process and will need to un-register itself.
This description of the objects that provide the IGC functionality will have the following format:
- Process Context: Identifies the number of these objects that exist at one time in an IGC process, and the object or module responsible for creating and destroying these objects. Also describes the important arguments used to construct these objects.
- Inheritance: Identifies the inheritance classes and why the inheritance relationship exists. If this object does not use inheritance, this section is omitted.
- Modes: Describes an IGC object's different modes of operation. If this object has only one mode of operation, then this section is also omitted.
- Responsibilities: Lists the main tasks for which this object is responsible.
Only one EventDispatcher object exists in an IGC process. The process's main module is responsible for the construction and deletion of this object. A pointer to the X server connection is needed to construct this object since the EventDispatcher will be making Xlib calls directly.
Listens for the following kinds of events by polling, and dispatches these kinds of events to multiple clients. Polling is inefficient! It would be preferable to use the UNIX select system call, but DMQ doesn't support file descriptors.
- IPC messages from the UI Process, Notification Server, and extension processes.
- OI/X events generated from the pop-up menus, and the color chooser dialog.
- X events such as button clicks, cursor movement, exposure, and key presses that occur inside a window managed by a DisplayPanel object. These events will be dispatched to DisplayPanel objects.
- Timer expirations which are used for looping and distinguishing a button click from a button drag. This object supports a timer granularity in milliseconds.
- Idle events that are dispatched whenever the IGC is not busy processing its other events. The FrameSeq object is a client of these kinds of events so that it can prepare non-current frames for display.
Only one IGC_Impl object exists in an IGC process. The process's main module is responsible for the construction and deletion of this object. The following is needed to construct this object.
- A pointer to the X server connection which will be passed to the DisplayMgr object.
- The ID of the X window on which the IGC should build its layout. This will also be passed to the DisplayMgr object.
- Whether this IGC is to run in a large or small display area.
IGC_Impl inherits from the IGC_ABC class. This object is the implementation portion of a "Proxy" design pattern. The proxy portion of this pattern is the IGC object that lives inside the UI process. The IGC_ABC class ensures that the public interface between the proxy and the implementation remains consistent.
- Creates and destroys the main IGC objects.
- Receives IPC requests from the UI process and passes them on to the other IGC objects that do the real work. This object sort of resembles the "Facade" design pattern.
- Caches and provides access to whether the IGC is running in a large or small display area.
Only one UI_WorkspaceManager object exists in an IGC process. The process's main module is responsible for the construction and deletion of this object. The following is needed to construct this object.
- The IPC target of the parent UI process. If a null IPC target is passed in, then the IGC is running in stand-alone mode.
- The ID of this IGC assigned by the parent process.
UI_WorkspaceManager's primary responsibility is to be a proxy to the UI process. In other words, any IGC object that needs to send information to the UI process will do so by calling a public method of this object. This object is qualified to send messages to the UI since it knows the UI's IPC address and the ID of this IGC.
Only one LoopingMgr object exists in an IGC process. The IGC_Impl is responsible for the construction and deletion of this object.
LoopingMgr inherits from the TimerEventClient class so that it can receive a callback from the EventDispatcher when a timer expires.
Only one DisplayMgr object exists in an IGC process. The IGC_Impl is responsible for the construction and deletion of this object. The following is needed to construct this object.
- A pointer to the X server connection which is needed by this object, and other IGC objects who will be making Xlib calls.
- The ID of the X window on which the IGC will build its layout. This object will use this window, but will not destroy it since it did not create it.
Most often, an IGC will run with a single display panel. But sometimes it is useful to divide the display into four equal portions, such as for displaying four different tilts of radar.
The DisplayMgr implements a single panel layout by constructing a single DisplayPanel object, passing the main layout window as an argument. When switching to a four-panel layout, that DisplayPanel object will be destructed.
The implementation of a four-panel layout is slightly more complicated. This object will create four sub-windows on top of the main layout window. These windows will not be transparent, so the main layout window will not be visible. These four windows will equally subdivide the area of the parent window, and will have the same depth (8 or 24 bits) as the parent window. This object will then create four DisplayPanel objects, each receiving one of those four sub-windows as a constructor argument. When switching to a single-panel layout, the four sub-windows and the four DisplayPanel objects will be destructed.
- Provides methods for querying and changing the display layout (single- or four-panel).
- Provides a method for altering the display mode of a DisplayPanel object (8- or 24-bit mode).
- Manages cursor resources. The IGC supports the following kinds of cursors:
· Pie Cursor used when preparing frames in the background.
· Busy Cursor used when the IGC is not responsive to user input.
· Interactive drawing cursors.
· Linked cursors which are used only during four panel layout.
- Manages font resources for legends and sampling. Font sizes are dependent on the IGC magnification and the width and height of the display panel(s).
- Maintains the image display parameters (fade/dim).
- Allocates the color set used for graphics/legends. The initial values of this set are read in from the file, dataMgmt/fxa.config, but this set can be changed dynamically since the user can specify colors of a graphic overlay. All display panels will be using the same color set, and will be using the same X colormap for their graphic window. The DisplayMgr keeps track of which colors in the set have been used to display an overlay.
Either one or four of these DisplayPanel objects exist at one time during the life of the IGC process, depending on the mode of the DisplayMgr (see Section9.3.5.2). The DisplayMgr object is responsible for the construction and deletion of these objects. The ID of the X window that this panel object will use as the image window is required for construction.
Inherits from the DisplayAreaEventClient class so that it can receive a callback from the EventDispatcher whenever an Xlib event occurs inside the panel windows.
Inherits from the TimerEventClient class so that it can receive a callback from the EventDispatcher when a timer expires. This is used to distinguish button clicks from button drags.
Inherits from the DisplayPanelActionsClient class so that it can receive a callback from the PopUpActionMgr whenever the user selects an option from a pop-up that pertains to this display panel.
This object can run using either a pseudo-color (8-bit) display algorithm or a true color (24-bit) display algorithm.
In 8-bit mode, this object will use two X windows mapped to the same screen space. The bottom window is the same window that was passed in at construction time. This window will be used to display images using a private X colormap, utilizing all 256 colors. This window is created with the visual that uses the underlay (image) planes of the H-CRX24 hardware. The top window will be created by this object, and will be a child window of the bottom window. In order to see the bottom window, the top window will have a transparent background. This window will be used to display graphic products (non-images) and legends. This window is created with the visual that uses the overlay planes and the transparency feature of the H-CRX24 hardware.
Here are some of the advantages of using 8-bit mode with a two window architecture:
- Image and graphic colors don't have to be shared between a single 256-color set. This makes image combination a lot less complicated.
- Graphics can be drawn independently without having to refresh the image.
However, there are these disadvantages:
- Creates a dependence on the graphics hardware to provide transparency and overlay planes.
- In order to achieve fast looping, two sets of pixmaps must be allocated (each set containing a pixmap for each frame). Substantial pixmap allocation can cause memory resource problems for the X server.
In 24-bit mode, this object will use the window passed in at construction time as the only panel window. Thus, all graphics and legends will be displayed directly on top of the image in the same window.
Here are the advantages of the 24-bit mode.
- Many different images with different color requirements can be displayed simultaneously in different display panels that are using true color.
- Image combo looks more realistic since an 8/8-bit combo is used instead of a 4/4-bit combo.
And there are also disadvantages:
- 24-bit pixmaps require four times as much X server memory as 8-bit pixmaps.
- Image combos take much longer to fade or dim than image combos displayed in 8-bit display panels.
- Displays depictable output, sample text, and legends.
- Provides a mechanism for selecting a legend by clicking on it.
- Handles timer and display area events from the event dispatcher.
- Maintains sets of pixmaps (each set containing a pixmap for every active frame), so that graphics and images can be displayed quickly for fast looping speeds (up to 20 frames/second).
Only one ViewMgr object exists in an IGC process. The IGC_Impl is responsible for the construction and deletion of this object.
- Manages the scale and map projection used by all loaded products.
- Manages the current view consisting of:
· Zoom factor
· Display center
· Magnification
· Default relative picture density. Each overlay has the ability to over-ride this value.
- Manages the coordinate conversion between screen coordinates and lat/lon which is used for sampling and by the interactive depictables.
Only one FrameSeq object exists in an IGC process. The IGC_Impl is responsible for the construction and deletion of this object.
Inherits from IdleStateClient class so that it can receive a callback from the EventDispatcher whenever there is no other events to process.
Inherits from OverlayActionsClient class so that it can receive a callback from the PopUpActionMgr whenever the user selects an option from a pop-up that pertains to a particular overlay.
- Loads and unloads all products (images, graphics, background maps, and combo images). It implements the load by organizing depictable objects with matching times into frames by managing Frame, DepictSeq and DepictTuple objects.
- Initiates the display and printing of the current frame.
- Prepares non-current frames for display.
- Maintains the following data structures:
· Tuple table: A hash table (Dict) that contains indices to DepictTuple objects. The index is built from the DepictSeq object pointer, and the data time of the tuple's depictable. In the case of combo image tuples, the index contains two data times.
· Frame list: A list (SeqOf) of frame objects.
· Load order list: A list of DepictSeq objects. This list maintains the order in which products were loaded and will be displayed.
- Keeps extension processes up to date with what is being displayed.
- Stores and retrieves a complete display context from a file.
- Provides a mechanism for changing the number of displayed frames and the frame that is currently displayed (current frame).
During the entire life of the IGC process, the number of Frame objects that exist is equal to the maximum frame count (which is currently 32, for a large IGC). The FrameSeq object is responsible for the construction and deletion of these objects.
- Maintains a list of DepictTuple objects that all have matching times in common. This object is not responsible for the creation and deletion of tuples, it just refers to them. There is no limit on the number of tuples/depictables that a frame can contain.
- Provides access to the list of DepictTuple objects for purposes of display, legend selection, sampling, and printing.
- Provides a mechanism for adding and removing tuples from the frame. The order of the tuple list is important since it is also the order in which depictables will be displayed and printed. Thus, map background tuples/depictables are first on the list, so all other graphics will be drawn on top. A frame can contain multiple image tuples/depictables as long as the tuples are being displayed in different display panels.
- Maintains a nominal frame time, which all depictables contained in this frame should match.
- Keeps track of which tuple is currently being prepared in the background, and whether any tuples need to be prepared in the background.
The number of GraphicDepictTuple objects that exist in an IGC_Process depends on the number of graphic (non-image) products that are loaded. The number of tuples for each graphic product is equal to the number of unique times from the time-matched inventory. The FrameSeq object is responsible for the construction and deletion of these objects. The following is needed to construct these objects:
- A list of data times that will be passed to the depictable. Most depictables require only one time, but there are some that require a list of times, such as Time-Height Cross Section depictables.
- A pointer (only for reference) to a GraphicDepictSeq object.
GraphicDepictTuple inherits from the DepictTuple class because graphics and images have a number of characteristics in common, and a few that differ. Also, it is convenient for the Frame and FrameSeq objects to think of just DepictTuple objects, rather than GraphicDepictTuple or ImageDepictTuple objects.
- Creates, destroys, and maintains an X pixmap, which has the same width and height as the display panels. The depth of this pixmap is 1 bit.
- Creates, destroys, and maintains a GraphicDepictable object. This object uses the DepictableServer to actually create the object, since only the server knows which concrete class to use.
- Creates, destroys, and maintains a TextString object containing the legend which is the product name plus the data time of the depictable.
- Maintains a struct containing the IGC zoom and density parameters of the last time this object's depictable was rendered.
- Maintains a pointer and provides access to a GraphicDepictSeq object. This object contains information about this graphic overlay.
- Maintains a count of the number of Frame objects that point to this object (called the usage count).
The number of ImageDepictTuple objects that exist in an IGC_Process depends on the number of image products that are loaded. The number of tuples for each image product is equal to the number of unique times from the time-matched inventory. The FrameSeq object is responsible for the construction and deletion of these objects. The following is needed to construct these objects:
- Two lists of data times that will be passed to the two depictables. If this is for a single image, then only one list of times is really necessary. Most depictables require only one time, but there are some that require a list of times, such as Time-Height Cross Section depictables.
- A pointer (for reference only) to a ImageDepictSeq object.
ImageDepictTuple inherits from the DepictTuple class because graphics and images have a number of characteristics in common, and a few that differ. Also, it is convenient for the Frame and FrameSeq objects to think of just DepictTuple objects, rather than GraphicDepictTuple or ImageDepictTuple objects.
- Creates, destroys, and maintains an X pixmap, which has the same width and height as the display panels. The depth of this pixmap (either 8 or 24 bits) depends on the mode of the DisplayPanel object that will display this image.
- Creates, destroys, and maintains one or two ImageDepictable objects depending on whether this is a single or a combo image. This object uses the DepictableServer to actually create the object, since it knows which concrete class to use.
- Creates, destroys, and maintains a TextString object containing the legend which is the product name plus the data time of the depictable. In the case of a combo image, there will be two product names and data times.
- Maintains a struct containing the IGC zoom and density parameters of the last time this object's depictable was rendered.
- Maintains a pointer and provides access to an ImageDepictSeq object. This object contains information about this image overlay.
- Maintains a count of the number of Frame objects that point to this object (called the usage count).
The number of GraphicDepictSeq objects that exist in an IGC_Process is the number of graphic (non-image) products that are loaded. The FrameSeq object is responsible for the construction and deletion of these objects. The following is needed to construct these objects:
- Load information such as the load mode, forecast time, and load time.
- A Set object containing display panel identifiers indicating which display panels will be used to display depictables that are associated with this DepictSeq.
- The DepictKey for this graphic product.
- A flag indicating whether this product is visible (displayed) or not.
- A value indicating what the relative picture density for this overlay should be.
Inherits from the DepictSeq class because graphics and images have a number of characteristics in common, and a few that differ. Also, it is convenient for the FrameSeq objects to think of just DepictSeq objects, rather than GraphicDepictSeq or ImageDepictSeq objects.
- Provides interfaces for setting and querying various attributes about this graphic overlay. Some of these attributes are:
· Load Attributes (time matching mode, forecast time, inventory time);
· Relative picture density;
· Whether the overlay is displayed or toggled off (visibility);
· The set of display panel identifiers into which depictables of this sequence will be drawn;
· Information about the product obtained from dataMgmt's depictable information file (depictInfo.txt);
· Whether this product is slot loaded;
· Whether this product is an interactive overlay, and whether it is editable or not;
· The color of the overlay and the legend, (obtainable in both RGB format, and as a color table index or pixel value).
- Determines which pop-up actions make sense for this graphic overlay.
The number of ImageDepictSeq objects that exist in an IGC_Process is the number of image products that are loaded. The FrameSeq object is responsible for the construction and deletion of these objects. The following is needed to construct these objects:
- Load information such as the load mode, forecast time, and load time. If the image is a combo, then two sets of load info are passed in.
- A Set object containing display panel identifiers indicating which display panels will be used to display depictables that are associated with this DepictSeq.
- The DepictKey for this graphic product. If the image is a combo, then two keys are passed in.
- A flag indicating whether this product is visible (displayed) or not.
- A value indicating what the relative picture density for this overlay should be.
Inherits from the DepictSeq class because graphics and images have a number of characteristics in common, and a few that differ. Also, it is convenient for the FrameSeq objects to think of just DepictSeq objects, rather than GraphicDepictSeq or ImageDepictSeq objects.
- Provides interfaces for setting and querying various attributes about this image overlay. Some of these attributes are:
· Load Attributes (time matching mode, forecast time, inventory time).
· Relative picture density. Raster, gridded, and radial images don't use relative picture density, but deep graphic images, such as the perspective profiler image, do.
· Whether the overlay is displayed or toggled off (visibility).
· The set of display panel identifiers into which depictables of this sequence will be drawn.
· Information about the product(s) obtained from dataMgmt's depictable information file (depictInfo.txt).
· Whether this product(s) is slot loaded.
· The color of the legend, (obtainable in both RGB format, and as a color table index or pixel value). By default, images use white as their legend color, but that color can be altered by the user.
- Determines which pop-up actions make sense for this image overlay.
- Creates, destroys, and manages one or two ColorTable objects, depending on whether this is a single or combo image. Provides methods for querying and setting these objects. These objects are capable of writing to an X colormap, and also implement the color table combination algorithms discussed in Section 9.5.4.3, "Rendering an 8-bit image combo".
Initial Situation: No time varying products are loaded, but static products (maps /topo image, etc.) may be loaded and displayed.
- User selects product from the user interface of the fxa process. An IPC message is sent containing a depict key, load mode, inventory time, forecast time, and a combine flag. The IGC_Impl object receives this message and then calls FrameSeq::load.
- Checks for an implicit clear. Product may require a different map projection than the one being used. If so, then all the existing products are unloaded.
- If combine flag is not set, and the new product is an image, unloads any images that are being displayed in the panel in which the new image will be displayed.
- Obtains an inventory from dataMgmt.
- Calls the routine that time-matches primary sequences, passing the preferred frame count.
- Assigns each time on the time match list to the corresponding frame's nominal frame time.
- Copies the pointers to the static (map background) tuples in the first frame to the rest of the frames, and increases the use count of these static tuples.
- Creates a new DepictSeq object, and adds it to the beginning of the load list. Passes to the DepictSeq constructor the load information that was received from the UI process.
- For each time in the time match list, checks to see if there is a DepictTuple object with the same time and sequence. If not, creates one, and adds it to the tuple table. Then adds a pointer to that tuple to the corresponding frame, and increases the tuple's use count.
- Analyzes the image color table requirements for each display panel. If the IGC layout is single panel, then this step is skipped. If all the panels have the same color table requirement, then nothing further needs to be done. If there is more than one requirement, the requirement with the most panels, (or in the case of a tie, the combo requirement) will be used to determine the panels that can be displayed in 8-bit pseudo color. All the other panels will be converted to 24-bit true color.
- Redraws the current frame, and marks all other frames as needing redrawing.
Initial Situation: One or more time varying products have already been loaded.
- Follows steps 1 - 4 described in Section9.4.1.
- Calls the routine that time matches overlay sequences, passing the nominal frame times.
- Tries to find a DepictSeq object with the same load attributes. If not, create one, and add to the load list before all the static products but after all the existing time-varying products.
- Follows steps 9 - 11 described in Section9.4.1.
Same steps as the single image, except that an existing image is not unloaded. Rather, its DepictTuple and DepictSeq objects are expanded to include the new image as the second image.
A Multi-load is a way of loading multiple products with one load command. This mechanism is used for families, radar combos, and four panel configurations.
When a multi-load command arrives from the UI, the IGC uses that (single) key to look up the following information in a dataMgmt table:
- which products should be loaded;
- into which panels the products should go;
- whether the products should initially be displayed or toggled off.
The IGC then loads each product, but defers the display and rendering until all the products are processed.
- When a DepictSeq object for a time varying product is created, it sends a message to the NotificationServer process, asking for updates. When this object is destructed, it un-registers with the NotificationServer.
- When a new time for a loaded product arrives, the NotificationServer sends a message to the IGC_process, containing the depict key and that new time.
The next four steps are also executed whenever the user changes the preferred frame count.
- The FrameSeq object removes all DepictTuple objects from the frames, but does not delete those objects from the tuple table, or the DepictSeq objects from the load order list.
- For every product in the list, obtain a new inventory, redo the time matching, and place tuples back in the frame object according to the time matching. Some new tuples may need to be created, and some tuples will be not be re-added to the frames.
- The frame sequence then deletes all unused DepictTuple and DepictSeq objects.
- The current frame is displayed, and all other frames are marked as needing redrawing.
The current frame needs to be displayed whenever any of the following occurs:
- Loading or unloading a product.
- Arrival of an auto-update.
- Adjustment of the preferred frame count, but only if the current frame changes.
- Toggling a product's visibility
- Changing the display attributes of one or more products. Display attributes include:
· magnification
· picture density
· color
· texture (line style or line width)
- Modification of an interactive overlay by an extension process.
- Clearing the display.
- Change in image fade or dim for an image displayed in a 24-bit panel. For 8-bit images, display is required only if the legends change, since fade and dim are done for 8-bit by modifying the color table.
To display the current frame, the following steps are taken:
- Every tuple in the current frame is examined. Image tuples are processed first followed by graphic tuples. This is because if the display panel is 24 bits, the image needs to be drawn first, so graphics will be drawn on top of it. For 8-bit panels, the ordering is not important, since two different windows are used.
- For each tuple that is visible (the tuple's DepictSeq object maintains the visibility flag), the following is done:
· Renders the tuple, if necessary. The ViewMgr's zoom and density parameters are compared with the tuple's zoom and density parameters the last time it was rendered. If they are the same, then this tuple does not need to be rendered. The details of rendering a tuple are covered in Section9.5.3 and Section9.5.4.
· Copies the tuple's drawable to every affected display panel. (The DepictSeq object also maintains the panel information).
For an image drawable, the DisplayPanel object will take that drawable directly and assign it as the image window's background pixmap. The panel object will also receive a pointer to the ColorTable object which is instructed to load the image's 256 colors into the image window's private colormap. Loading the color table is not necessary for 24-bit panels.
For a graphic drawable, the 1-bit pixmap (bitmap) is copied into the DisplayPanel object's backing graphics pixmap corresponding to the current frame. This copy is done with a stipple fill in order to preserve what was drawn by previous tuples. The color of the tuple is applied when the tuple's pixmap is copied into the panel's pixmap.
- Once all the tuples have been examined, every DisplayPanel object will do the following:
· Obtain a list of tuple objects from the current frame. It will display the legends of each tuple, with the first legend displayed in the lower right corner of the display panel and the others stacked on top. If the tuple is visible, then the legend is displayed in the color of the tuple, otherwise the legend is displayed in gray.
· Assign the graphics backing pixmap corresponding to the current frame to the graphics window's background pixmap.
As mentioned earlier, one goal of the IGC is to support fast looping speeds, up to 20 frames per second. In order to achieve this goal, each frame's picture needs to be rendered into a pixmap (or two pixmaps in the case of 8-bit display panels). The advantage of using a pixmap is that it can be displayed into a window rather quickly, and it can be filled off screen, behind the user's back, while the IGC process is waiting for events. If the user wants to step or loop to a frame that hasn't been rendered to a pixmap yet, then the user will notice a delay. The length of the delay depends on how many products are in the frame, and how long it takes for each product's depictable to produce its picture. So, the trade-off is to perform as much rendering as possible while the workstation is idle, but still respond promptly to the user's actions.
Here is how those pixmaps are prepared in the background.
- When the EventDispatcher doesn't have any X, IPC, or timer events to process, it calls a method in the FrameSeq object. This method counts the total number of frames that need to be redrawn, then figures out which pie cursor the DisplayMgr object should display based on the ratio between frames needing redrawing and the total number of frames. If no frames need to be processed, then the default cursor is displayed.
- One of those Frame objects is then instructed to prepare a single tuple as described in Section9.5.1 step 2. However, instead of copying the tuple's bitmap or pixmap to the X window, it is copied to a pixmap corresponding to the frame that is being processed.
- If that frame has processed its last tuple, then the legends for that frame are drawn into the pixmap corresponding to that frame, and the frame is marked as no longer needing redrawing.
Graphic rendering involves passing a drawable (which can be thought of as a blank canvas) and having the depictable (the artist) paint a graphic representation of the data into the canvas. Since the drawable is only one bit deep, the depictable does not have to deal with color. The following steps are taken by the GraphicDepictTuple object:
- Tells the DisplayMgr object to change the cursor to its busy representation (wrist-watch).
- Clears the drawable by setting all the pixels to 0.
- Instructs the depictable to paint into the drawable by passing the depictable the following information:
· data needed to use Xlib, such as the pointer to the display connection, the drawable, and the graphics context;
· the extent (width and height) of the drawable;
· zoom, picture density, and line texture data obtained from the ViewMgr object.;
· scale and map projection data obtained from the ViewMgr object.
- Restores the cursor.
Image rendering is similar to graphic rendering, except that the canvas is a byte (8-bit) buffer instead of an X drawable. Each ImageDepictable object (there might be two in the case of image combo) will fill its byte buffer with each pixel representing a color index between 0 and 255. The display panel will expand and/or combine the buffers, and then instruct Xlib to copy the buffer into the tuple's drawable. The details differ depending on whether it is a single or combo image, and whether the display panel is 24 or 8 bits deep.
The following steps are performed by an ImageDepictTuple object:
- Tells the DisplayMgr object to change the cursor to its busy representation (wrist-watch).
- Allocates a buffer which is an array of bytes (char) whose size is the width * height of the tuple's drawable.
- Instructs the ImageDepictable object to paint into the byte buffer by passing the following information:
· a pointer to the buffer;
· the extent (width and height) of the drawable;
· zoom, picture density, and line texture data;
· scale and map projection data.
- Passes the byte buffer to Xlib, to copy it into the tuple's 8-bit pixmap.
- De-allocates the memory allocated in step 2.
- Restores the cursor.
The following steps are performed by an ImageDepictTuple object:
- Executes the first three steps described in "Rendering a single 8-bit image."
- Allocates a second byte buffer, which uses 4 bytes for every pixel. Thus, the size of this buffer is 4 times that of the buffer used as the depictable's canvas.
- For each byte of the buffer filled by the Image Depictable object, the tuple looks up the red, green, and blue intensity values using the image color table and pixel index represented by that byte. The three color components are then multiplied by the image brightness value, a float between 0 and 1 that is maintained by the DisplayMgr object. Four bytes are copied into the second byte buffer: a blank (0) byte, and one byte for each of the red, green, and blue values.
- Passes the second buffer to Xlib, so it can be copied into the tuple's 24-bit pixmap.
- De-allocates both byte buffers.
- Restores the cursor.
The following steps are performed by an ImageDepictTuple object:
- Tells the DisplayMgr object to change the cursor to its busy representation (wrist-watch).
- Allocates a buffer which is an array of bytes (char) whose size is the width * height of the tuple's drawable.
- Creates a ComboDepictable object, by passing pointers to the two ImageDepictable objects owned by this tuple. This step needs to be done only when rendering for the first time or whenever one of the image depictable objects is replaced.
- Instructs the ComboDepictable object to paint into the byte buffer by passing the depictable the following information:
· a pointer to the byte buffer;
· the extent (width and height) of the drawable;
· zoom, picture density, and line texture data;
· scale and map projection data.
It is important to understand how the combo depictable fills its byte buffer in order to fully understand the image combination algorithm. For each pixel or byte, the combo depictable asks each of its two depictables for the color value (an 8-bit number between 0 and 255) of that pixel. The two pixel values are quantized into one value using the algorithm depicted in Figure9.1. That combined pixel value is then written at the appropriate position in the byte buffer.
- Passes the byte buffer to Xlib, so it can copy the buffer into the tuple's 8-bit pixmap.
- De-allocates the memory allocated in step 2
- Restores the cursor.
Figure 9.1 Combining two 8-bit pixels into one.

The following steps are performed by an ImageDepictTuple object:
- Tells the DisplayMgr object to change the cursor to its busy representation (wrist-watch).
- Allocates three byte buffers which are arrays of bytes (char). Two of these byte buffers will be used as a drawing canvas for the tuple's two image depictables. Their sizes are the (width * height) of the tuple's drawable. The third byte buffer, four times the size of the others, will be used to send the combined data to X.
- Instructs both Image Depictable objects to paint into their byte buffers by passing the depictables the following information:
· a pointer to the byte buffer;
· the extent (width and height) of the drawable;
· zoom, picture density, and line texture data;
· scale and map projection data;
· a flag indicating whether the color bar should be displayed left justified. One depictable will have this set to true, while it will be false (right side) for the other.
- For each byte of the buffers filled by the depictables, the tuple looks up the red, green, and blue intensity values using the image color table and pixel index represented by that byte. The two colors are then combined into a new color using a linear interpolation based on the image fade value, a float between 0 and 1 that is maintained by the DisplayMgr object. The three components of the new color are then multiplied by the image brightness value. Four bytes are copied into the third byte buffer: a blank (0) byte and one byte for each of the red, green, and blue values.
- Passes this third buffer to Xlib, to be copied into the tuple's 24-bit pixmap.
- De-allocates the buffers allocated in step 2.
- Restores the cursor.
Dimming refers to adjusting the brightness of a single or combined image. Fading is relevant only to combined images and refers to the adjusting of the contribution of each image. A fade value of 0.5 implies that both images are being displayed equally. The user can change these values using the Image Controls Dialog which is managed by the fxa (UI) process.
The new fade and combo values are sent by the fxa, received by the IGC_Impl object and handled by the DisplayMgr object.
If the display panels are 24 bits deep, then the images in those panels will need to be re-rendered, following the recipe outlined in Section9.5.4.4. If the display panels are 8 bits deep, then the combined color table needs to be recalculated as described in the following section. A display can have a mixture of 8- and 24-bit display panels.
A color table object includes a method that combines itself with another color table object and then loads the resulting color table into the X colormap of a display panel's image window. This is accomplished by the following algorithm:
- Two subsets of 16 colors are computed from each color table. The color table is subdivided equally into 16 buckets. The most colorful color from each bucket is added to the subset. Three factors are considered in determining whether a color is more colorful:
· the color's brightness (sum of all three red, green, and blue components);
· the amount it differs from gray, white, or black;
· the difference between this color and the color from the previous bucket.
- Each entry in the combined color table is a linear interpolation of one subset color with a color from the other subset. The interpolation is calculated using the image fade value, a float between 0 and 1 that is maintained by the DisplayMgr object. The scheme for building this color table is depicted in Figure9.2.
- Applies the image brightness level to every entry in the combined color table by multiplying the brightness with each color's red, green, and blue component.
Figure 9.2 Arrangement of a combined color table (entries 16 - 239 omitted)

Zooming is when the user specifies both a new display center and a zoom factor, while roaming is when the user specifies only a new display center. Although the user interfaces are quite different, the implementations of zooming and roaming are essentially the same.
The simplest user interface for zooming is positioning the cursor in the display panel where the display center should be, and clicking button 1 to zoom out or button 2 to zoom in. In four-panel mode, even though only one of the panels receives the button click event, all four panels will respond to the zoom. Here's what happens behind the scenes:
- The EventDispatcher object receives the Xlib event, and determines to which display panel object to send the event, by examining the window where the event occurred.
- The DisplayPanel object then tells the ViewMgr whether a zoom out or zoom in was selected, and also what the new display center should be.
- The ViewMgr then executes the zoom operation using the procedure described in Section 9.6.1.3.
A more useful interface is through the context sensitive pop-up menus. The user can pop up a cascading menu that presents a choice of zoom factors specified in terms of the width of the display in kilometers. The new display center is where the user pops up the menu. The advantage of this interface is that the user can go directly to the desired zoom factor. With the button click interface, it may take several display refreshes (which can be time consuming) before the desired zoom factor is obtained.
Roaming is initiated by the user by holding down button 2 at a certain position inside one of the display panel. As the user moves the cursor while holding the button, the picture (both the image and graphics/legends) follows the cursor, only inside the selected display panel. As the picture moves off the screen, the area where the picture used to be is drawn in black (see Figure9.3). Once the user releases the button, all the display panels are redrawn with the new display center. At this point, the roaming panel will have its black areas filled in with the new picture.
FIGURE 9.3 Example of roaming Panel A

Here's what happens behind the scenes:
- The DisplayPanel object who has the cursor gets the button press event from the EventDispatcher object.
- If the button is button 2, the display panel initiates a timer to expire in 0.5 seconds. If the button is still held down when the timer expires, then roaming begins, and the roaming start position is recorded.
- The DisplayPanel object receives motion notify events as the user moves the cursor.
- The window coordinate of where the upper left corner of the panel's pixmaps will now be placed is computed according to the new cursor position. The pixmaps (image and graphic) are recopied into the window at that new coordinate.
- Two rectangles, which are the difference between the new position and the old position of the pixmaps, are computed. Those two rectangles are drawn in the panel windows using the background color.
- Steps 3-5 are continued until the DisplayPanel object receives the button press event from the Event Dispatcher. The new display center, which is the (roaming end position - roaming start position) + the center of the display panel, is computed. The new display center is then passed to the ViewMgr object which then executes the roam operation using the procedure described in the next section.
- Tell the DisplayMgr object to change the cursor to its busy representation (wrist-watch).
- Convert the display center to 1:1 coordinate space by dividing it by the current zoom factor and adding it to the display origin (upper left corner position in 1:1 coordinate space).
- The ViewMgr maintains a list of zoom factors which are floating point values that are initialized from the fxa.config file. The ViewMgr also keeps track of the current zoom factor. If the user is zooming in, then select the next largest zoom factor. If the user is zooming out, select the next smallest zoom factor. If the user is roaming, then use the current zoom factor.
- Convert the panel's extent (width and height) in 1:1 coordinate space using the new zoom factor. If the display center is outside of the panel's extent, then move it inside.
- Calculate the display origin in 1:1 space, and save that coordinate, the display center, and the new zoom factor as the current view.
- Redraw the current frame, and all other frames marked as needing redrawing. Since the current view has changed, all tuples should be re-rendered, which means that each depictable will need to re-fill its tuple's drawable. See Section 9.5.1, "Displaying the current frame".
- Restore the cursor.
The user is able to control whether a product is to be displayed, without having to unload or reload it. Basically, the IGC supports this by providing a mechanism for the user to select an overlay by clicking on its legend. The visibility flag inside the DepictSeq object associated with that overlay is then adjusted, and the display is refreshed. Here is a more detailed walk-through of this procedure:
- The user clicks on one of the displayed legends in the lower right corner of one of the display panels with mouse button 1.
- The EventDispatcher object receives the Xlib button release event, and determines to which DisplayPanel object to send the event, by examining the window where the event occurred.
- The DisplayPanel object then checks to see if the legends are being displayed. If not, then this event is interpreted as a zoom out and is handled as described in Section9.6.1.
- Obtains a list of the tuple objects that are loaded into the current frame. If only legends for background maps are being displayed, then all non-map tuples are removed from the list. Likewise, if product legends are being displayed, then all map tuples are removed from the list. Also, if a tuple is not being displayed in the display panel where the click took place, it is removed from the list.
- Uses the Y coordinate of the button release event to determine which legend is underneath the cursor. If the Y position is above the top-most legend, then this event is interpreted as a zoom out.
- Uses the X coordinate of the button release event to determine if the button click is to the left of the first character of the legend selected in the previous step. If it is to the left, then this event is interpreted as a zoom out. However, if it is to the right of the first character, then we found the legend under the button click. That legend has a DepictTuple object associated with it.
- The DepictSeq object, obtained from the selected tuple object, toggles its internal visibility flag.
- Redraws the current frame, and all other frames are marked as needing redrawing. If the selected overlay is turned off, then all tuples that have a pointer to the DepictSeq object associated with that overlay will be skipped during the copying of a tuple's drawable to a display panel. However, the legends of those tuples will still be displayed, but drawn in a gray color. For more details, see Section 9.5.1.
Sampling is an IGC feature that displays text describing the meteorological values of the displayed products at the point where the cursor is. Thus, every time the cursor is moved while sampling is active, new values are displayed. Not every product currently supports sampling, although METAR plots and most images do. The text appears as close as possible to the cursor, and each product that supports sampling has a single line of text, drawn in the color of the product's legend. Here is how that feature is supported behind the scenes:
- The DisplayPanel object who has the cursor gets the button press event from the EventDispatcher object.
- If the button is button 1, the DisplayPanel object initiates a timer to expire in 0.5 seconds. If the button is still held down when the timer expires, then sampling is made active.
- When sampling becomes active, the FrameSeq object is instructed to disable background processing. The cursor is not as responsive while tuples are being rendered in the background.
- While sampling is active, the DisplayPanel object will do the following every time it receives a motion notify event from the X server (which is generated every time the user moves the cursor).
· Tells the ViewMgr object to convert the display coordinate from the motion notify event to a lat/lon coordinate.
· For every visible tuple in the current frame, instructs that tuple to call its depictable's "interrogate" method, passing the lat/lon coordinate. If that tuple is for a combo image, it may have several depictable objects to call. That method will return a TextString object. If that object does not contain a null string, then registers that string and the overlay color with every DisplayPanel object that is displaying this tuple.
· Instructs every DisplayPanel object to erase the previous sample text. This is done by copying the area to be erased from the backing graphics pixmap to the panel's graphics window.
· Instructs every DisplayPanel object to display all the registered sample text directly to the panel's graphics window. The upper left corner of the sample text is computed so that it appears directly below, and slightly the right of the cursor. However, if this position does not allow the entire sample text to be displayed in the panel, that position is adjusted to the left or above.
- When the user releases the mouse button, the DisplayPanel object with the cursor will receive the button release event from the EventDispatcher. If sampling is active, then it is made inactive, by setting an internal flag in the affected DisplayPanel object. Any sampling that was drawn to the panel's window is erased, and background processing is turned back on.
Stepping refers to specifying a new current frame and displaying that frame. If the frame does not need to be redrawn, then displaying that frame just involves having each display panel object copy the backing pixmaps corresponding to the new current frame into the panel windows. Stepping implies that the stimulus for changing the current frame comes from a user request. The IGC supports the following step commands:
- Step to first frame: The current frame is set to the earliest non-empty frame.
- Step to last frame: The current frame is set to the latest non-empty frame.
- Step forward: The new current frame is set to the next non-empty frame later than the old current frame. If the old current frame is the latest frame, then the current frame is set to the earliest frame.
- Step backward: The new current frame is set to the next non-empty frame earlier than the old current frame. If the old current frame is the earliest frame, then the current frame is set to the latest frame.
A non-empty frame is defined as a frame that satisfies all of the following conditions:
- Contains at least one visible, time-varying DepictTuple object.
- Has not been marked by the user as a frame to skip.
Looping can be thought of as stepping, except the stimulus for changing the current frame comes from a timer expiration. In order for the user to effectively control looping, the IGC supports the following looping parameters.
- State: Whether looping is on or off.
- Direction: Whether the loop will move forward, move backward, or cycle (move forward to the latest frame, move backward to the earliest frame, then repeat).
- Forward dwell: The amount of time that each frame is displayed while looping forward.
- Backward dwell: The amount of time that each frame is displayed while looping backward.
- First frame dwell: The amount of time to spend displaying the earliest frame.
- Last frame dwell: The amount of time to spend displaying the latest frame.
Here's what happens when the user selects one of the step control buttons of the control panel managed by the UI (fxa) process.
- The fxa sends an IPC message to an IGC process. The IGC_Impl object receives this message which contains a step command.
- If looping is on, then the LoopingMgr is told to turn looping off.
- The new current frame is calculated according to the step command described in the previous section.
- The new current frame is displayed. If the frame needs to be redrawn then the procedure described in Section 9.5.1, "Displaying the current frame" is followed. If the frame does not need to be redrawn, then each DisplayPanel object copies the backing pixmaps corresponding to the new current frame into its panel windows.
Here's what happens when the user enables looping by clicking on the loop state button of the control panel managed by the UI (fxa) process.
- The UI process sends an IPC message to an IGC process. The IGC_Impl object receives this message which contains a flag indicating that looping is to be turned on. This request is then passed on to the LoopingMgr object.
- The FrameSeq object is instructed to disable background processing since this is not really needed if looping is active.
- The EventDispatcher is told to activate a timer, and to call a method in the LoopingMgr object when the timer expires.
- When the timer expires, the following is done:
· Determines the step command which is calculated from the looping direction and the current frame and passes the command to the FrameSeq object which executes steps 3 and 4 of the Stepping procedure (Section9.6.4.1).
· Determines how long to display this current frame by considering the looping direction and the dwell times. The EventDispatcher object is then told to expire the next timer using this computed duration.
Here's what happens when the user disables looping by clicking off the loop state button of the control panel managed by the UI (fxa) process.
- The UI process sends an IPC message to an IGC process. The IGC_Impl object receives this message which contains a flag indicating that looping is to be turned off. This request is then passed on to the LoopingMgr object.
- The FrameSeq object is instructed to re-activate background processing.
- The EventDispatcher is told to deactivate the timer.
Swapping is when the user selects one of the small IGC processes to display its loaded products in the large display area. That IGC process will now become the large IGC, responsive to the user interactions from the menu bar, control bar, volume browser, and other applications initiated by the UI process. Meanwhile, the IGC process that was displaying its products in the large display area will now use the display area that the small IGC was using.
Here is a walk-through of what happens to the IGC Process that is selected to be swapped into the large display.
- The user clicks mouse button 3 inside one of the display panels.
- The EventDispatcher object receives the Xlib button release event, and determines to which DisplayPanel object to send the event, by examining the window where the event occurred.
- The DisplayPanel object instructs the UI_WorkspaceManager object to send a message to the UI process requesting a swap.
- The IGC_Impl object will then receive an IPC message from the UI process indicating a new size type which the IGC_Impl object saves and the ID of a new X window to use for the IGC layout. This is sent to the DisplayMgr object.
- The DisplayMgr object destroys all of its DisplayPanel objects, and any X windows that were created for the four panel layout.
- If the panel layout is single panel, then a DisplayPanel object is created using the X window that was sent by the UI process.
- If the panel layout is four panel, then four new X windows are created. The X window passed in by the UI is the parent window. The origin and extent of these windows are computed so that they evenly subdivide the display area of the parent window. Since these windows will be displayed on top of the parent window, the parent window will not be visible, and will not be used by any DisplayPanel object. The depth (8 or 24 bits) of these new four windows will be the same as the parent window. The DisplayMgr will then create four DisplayPanel objects, each constructed with one of the four windows just created.
- Each created DisplayPanel object will determine whether its in 8- or 24-bit mode by querying the depth of the window that was passed in to the constructor. It will then create an additional window for graphics, if in 8-bit mode, and also create a backing pixmap for each active frame.
- Every DepictTuple object in the FrameSeq is forced to re-render by resetting its internal zoom and density information.
- The current frame is redrawn, and all other frames are marked as needing redrawing.
Here is what happens to the IGC_Process that will be swapped out of the large display and into one of the small displays.
- Receives a message from the UI process which asks the IGC_Impl to send a message back to the UI process acknowledging the receipt of the first message. This lets the UI process know that this IGC is not busy drawing or handling a user's request and is ready to swap.
- Steps 4 - 10 of the above procedure are then followed.
Table of Contents
Next Chapter
This document is maintained by Joe
Wakefield. Last updated 9 Jan 97.