Article 2714 of comp.sources.unix: Path: nntpd.lkg.dec.com!crl.dec.com!crl.dec.com!bloom-beacon.mit.edu!spool.mu.edu!howland.reston.ans.net!newsfeed.internetmci.com!in1.uu.net!vixie!vixie!not-for-mail From: wolf@prosun.first.gmd.de (Wolfgang Koehler) Newsgroups: comp.sources.unix Subject: v29i057: grafix-1.2 - a C++ library for easy X11 GUI apps, Part03/05 Date: 1 Dec 1995 11:59:09 -0800 Organization: Vixie Enterprises Lines: 2446 Sender: vixie@vix.com Approved: vixie@gw.home.vix.com Message-ID: <49nmqd$96a@gw.home.vix.com> References: <1.817847834.9257@gw.home.vix.com> NNTP-Posting-Host: gw.home.vix.com Submitted-By: wolf@prosun.first.gmd.de (Wolfgang Koehler) Posting-Number: Volume 29, Issue 57 Archive-Name: grafix-1.2/part03 #!/bin/sh # This is part 03 of Grafix # ============= README.txt ============== if test -f 'README.txt' -a X"$1" != X"-c"; then echo 'x - skipping README.txt (File already exists)' else echo 'x - extracting README.txt (Text)' sed 's/^X//' << 'SHAR_EOF' > 'README.txt' && Grafix Ver. 1.2 1995, Oct 30. ============================================== 1. What is "Grafix" ? X "Grafix" is a utility originally designed to help scientists in the visualization of results of a computation, esp. for numerical integrations of partial differential equations. X It can be used, however, for any application that wants to use X-Windows for drawing pictures, functions or other graphic objects in a convinient interactive manner or even for writing a graphical user interface for any task. X Grafix should be considered as a layer between an application and the X Window system built up of a bunch of basic classes as building elements. The simplest way of using it is to define instances of these classes. For more complicated programs the user has to define own derivations to the basic clases. X - Grafix is based on Unix and the X Window system. X - Grafix does not use any commercial code, like Motif, so it is totally free. X - Grafix is been ported and tested for Linux and SunOS, with X11R5/R6 X - Grafix is small and fast since it is pure functionality without any X superfluous additives. X - Grafix is completely written in C++ and to compile with g++ on both platforms X The object-oriented approach enables a quite simple way of introducing user X defined behaviour. X - Grafix includes classes for the basic operations to have a convinient window X management, like : X - windows with automatic restoring for complex drawings (backing store) X - several types of predefined button classes for different purposes : X quit_button, delete_button, help_button, callback_button, toggle_button, X instance_button, dump_button, hardcopy_button, ... X all the buttons have a Motif-like three dimensional shape X - popup-windows and pulldown-menus for selecting discrete values X - help popups can be bound to any window X - scrollbars for selecting coniguous values X - windows with real-valued co-ordinate systems where the user has not to X worry about pixel co-ordinates X - a simple edit window for entering strings X - simple file selection boxes for openening files interactively X for reading (with directory scan) and writing (query before overwrite) X - a predefined palette manager for color definitions that can be X implemented in any application X - as advanced class : an complete manager to handle the display X of 2-dim functions (given on a equidistant grid) as lattice or body X in arbitrary perpective, shadowing and details zooming. X - new : animator class : to store time sequences of two dimensional arrays X in a file (more than one, also 3-dim arrays can be treated as vector X of 2-dim arrays) and replay them like a video film. X This is at most useful for visualizing time consuming integration X procedures X - new : integrator class : very easy to use prototype to link any X numerical 2- or 3-dim FDE-integration program with the graphic interface X and playback feature X - new : scrolled windows X - new : classes for displaying tree- and graph-structures, and as X application a very nice graphic class browser X (and a simple one "dir-tree") X - Grafix has some example programs to show the basic functions,eg X "win-demo", "edit-demo", "file-browser", "calc", "pal-demo", etc. X The simple ones should help the learner to understand the functionality : X hello, win-demo, edit-demo, file-browser, pal-demo, clock-demo, dir-tree X while the other provide also real functionality : X class-browser, file-browser, cursors, calc, one-dim, two-dim, replay X - The programs "one-dim", "two-dim", "three-dim", "replay" X give a complete model of some numerical integration methods for the one X or two dimensional advection equation (simple upstream method, X Smolarkievicz-method, Lax-Wendroff). They have several buttons and menus X for playing with some parameters and three-dim allows X to afterwards show the ongoing integration as animation. X These demos should be easily adopted to any one or two dimensional X set of differentional equation with time dependence (finite difference) X 2. What is it NOT X - it is not a commercial software, so I will not take any warranty for the X usability of the software - it is not in a "ready to use" state, it requires the user to write own X C++-code (this should be obvious) - I can give no guarantee to respond on error reports or queries for X improvements since my time for this task is limited. But I'll try my best X to help. X 3. What do you need to use "Grafix" X - You should have basic knowledge about C++ classes and what an X-window is. X Further knowledge about Xlib programming will be helpful but is not X necessary since I tried to encapsulate this in the classes. X - You need g++ to compile the code, other compilers possibly do not allow some X special constructs for passing multidimensional arrays as parameters. X These type casts could be easily substituted, however. X - You need Unix (SunOS, Linux) and X11R5 or X11R6. X Portations to other platforms are not my concern, since I have no X possibility to test them. But if you have gcc and X11 there should be no X major problems. X Reported platforms that work (possibly with minor adaptions): X SGI (Silicon Graphics, IRIX) X Sun , SunOS 5.3 (Solaris 2.3) X Bull DPX/20 (PowerPC and AIX 3.2.5). X PC (Interactive Unix, ISC 4.0) X HP 9000/735 with HP/UX 9.03A X - you have to agree to the "GNU GENERAL PUBLIC LICENSE" X TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION, X (see included standard file "COPYING" for details) X in order to use the program, copy, distribute or modificate it or parts X of the code. X Additionally, I forbid the use of any part of the package X for military purposes and any portations to Win*ows-XX X 4. How to start X I strongly suggest starting with the example programs in the package. They demonstrate nearly the complete functionality. Compile them, start and play with them. Then have a look at the sources and try to understand how they work. X - Have a look at the file "grafix.mk" if the paths for Xlib are correct for X your platform. On my Linux-PC I have "XPATH = /usr/X11R6", while the Sun X expects "XPATH = /opt/X11R6". BTW, X11R5 should also work. X X If you want to make a port to a new hardware platform, please add X a new entry similiar to to the existing ones, eg. X ifeq ($(shell uname),myplatform) X XPATH = .... X LFLAGS = .... X CFLAGS = -I.... -DMYPLATFORM X endif X If possible, let me know about this, so I may include this in the next X release. X X Another possible cause of compilation failure is that some special include X files for gcc are not found (regex.h). Then you should include X "-I./gccinc" in your CFLAGS X - To build all demos type : X for the first time "gmake depend" X and then "gmake" X - To let them all run consecutivly type : X "gmake demorun" X - read the file HOWTO for a detailed instruction of the installation X and a description of the use of Grafix. X 5. Main changes since version 1.0 (from Feb. 95) (see LOG.txt for details) X - event handling simplified, so each window class receives only the events X of interest - new classes for text viewing (files.c) - file-browser demo included - clock_win : included - main_window class allows additional arguments for positioning - animator- and replay- functionality for saving and redisplaying results of X integration runs - scrolled windows included - Tree windows derivation - class-browser as a complete demo for these - dir-tree as simple demo for scrolled windows, and Tree windows - some bug fixes : eg. the black background color on some displays - compilation errorfree with gcc 2.6.3, and 2.7.0 - support of TrueColor modes (16bpp, 32bpp) X X X X SHAR_EOF chmod 0644 README.txt || echo 'restore of README.txt failed' Wc_c="`wc -c < 'README.txt'`" test 7763 -eq "$Wc_c" || echo 'README.txt: original size 7763, current size' "$Wc_c" fi # ============= HOWTO.txt ============== if test -f 'HOWTO.txt' -a X"$1" != X"-c"; then echo 'x - skipping HOWTO.txt (File already exists)' else echo 'x - extracting HOWTO.txt (Text)' sed 's/^X//' << 'SHAR_EOF' > 'HOWTO.txt' && X Grafix, Vers. 1.2, 1995, Oct. 30 0. General Remarks ================== The Grafix package is far from beeing complete and surely not bug free. Several features are of rudimentary functionality but I hope to improve them step by step. (It depends upon how much time I can afford for this task). Nevertheless, the basic structure of the system can be considered as unchanging. X Beta testers and bug reports are wellcome, also improvement suggestions. However, I cannot make ports to other platforms. If a user intends to do this I will offer my support. Feel free to ask me if you have problems, questions about any part of the system. This text "HOWTO" is also not yet complete. As with the whole package it will be completed step by step. X My Email address is : X wolf@first.gmd.de X 1. Demonstration Programs ========================= X The look at the demos in most cases enables a much faster understanding of the imbedded connections and functionality of a programming interface than reading a manual. So the first step should be the installation of the demos and the second trying to understand how they work. X For this purpose I have added several demos : X 1.1 simple demos --------------- hello.c : the simplest program X win-demo.c : shows the working of all basic window functionality; like X main_window, buttons, popups, help-popups, pulldowns, displays, X scrollbars, etc. X calc.c : an implementation of a simple calculator X with hex/dec/bin conversion, arithmetic and logic operations X clock.c : implementation of a simple analogue clock X cursors.c : show all predifined X-Cursors X edit-demo.c : usage of "edit_window" for entering strings X file-browser.c: a complete browser which shows the usage of the X "file selection box" class, vertical scrollbars, text view X pal-demo.c : X-window colors palette display and manipulation X dir-tree : display directory tree (demo for tree-graphs) X 1.2. numerical demos -------------------- one-dim.c : a quite realistic example developed for practical use; X it shows the use of real coord-systems for displaying real-valued X functions, the use of pulldown menus for selecting values, X the animation technique for integrating a differential eq. X lat2demo.c : demonstrates the use of lattice_manager class X generates pictures of two functions inside one main window, each having X its own lattice-manager functionality buttons and popups X for manipulating its appearance; only some 40 lines code X lat-demo.c : another demo of the lattice_manager class for displaying X two dimensional functions. X It combines the lattice_manager functionality with 2 additional X pulldowns for interactively selecting a function and setting a new X grid size. The code needed for this is only some 50 lines. X two-dim.c : a realistic example; shows the use of the lattice_manager class X for displaying and animating two dimensional functions (or arrays) X based on solvers for the two dimensional advection equation. X It allows the user to change interactively the grid size, time step X value, some parameters of the initial values, the flow direction, X the integration method, the number of time steps to integrate, etc. X three-dim.c : a prototype program for linking to any two- or three-dimensional X finited difference equation integration program. It enables interactive X integration with graphic display of the computed arrays. X It makes use of the new animator class, ie. saving of computed fields X in a so-called video file for later reviewing with the "replay" program X replay : replay a saved file of a three-dim run X 1.3 useful demos ---------------- class-browser : a very nice graphical class browser that reads some C-files X extracts the class inheritance graph by parsing the definitions X and displays it in a graphical window X X 2. Making and running the demos =============================== X After unpacking the shell archives you should at first type : X "gmake demos" X which compiles and links all demo programs together with the archive in X the current directory. X To get a first glance of the whole thing then type : X "gmake demorun" X which invokes all demos consecutively. X X If make fails there are probably some path related problems, eg. the Xlib X is not found under the standard path. If this is the case you have to replace X the corresponding macros in the file "Makefile" with the proper values for X your system. X If the compiler g++ is not to be found on your system, you are in trouble. X (see README). X X Note that an X Window server must run on your computer, of X course, and the DISPLAY environment variable must be set. X For users not so famliar with this topic; you have to use X export DISPLAY=`hostname`:0.0 X for bash, or X setenv DISPLAY `hostname`:0.0 X for csh or similiar shells. X X The order of using the demos should be like listed above, since it works up X from simple to complex. X X If the demos do work try all buttons and play with the parameters. X The left mouse button activates a button or pulldown, the right button X gives a specific help popup for this window (if installed). X The optical behaviour of active buttons is Motif-like, ie. they show their X state "up" or "down" with a three-dimensional frame. However, there is X additionally the feature that the "state of activity" of an button is X indicated by "flattening" the frame if the pointer enters it. X X I also recommend using a color display; on black-and-white displays the X appearence will be poor. X 3. More detailed information about the demos ============================================ 4. Some basic concepts of Grafix ================================ X * window tree X The user should know the basics of the tree structure of windows under X. There is one root window that represents the screen. An application can create "main windows" (in Grafix of type "main_window") that are children of root. Their appearence on the screen is usually managed by the window manager. Then it can recursively create subwindows of certain size and at positions relative to the parent window .(0,0) is the left upper corner. In Grafix the user should not need to interact with X directly but through creation of window instances of some class. Each class represents a XX-window with some specific behaviour. However, the tree structure is the same as under X. The behaviour of the class is mainly determined from the callbacks attached with it (see below). X X * window classes The basic classes defined in window.h are window as funadamental class for all others main_window that are defined as having no parent (always root), buttons to initiate actions if the mouse button is pressed X usually not directly used, but to inherit subclasses X from which dozens are defined pulldown_window a main_window that is attached to a button. It pops up X directly under the button. Mainly for making a selection. plate window with 3 dim appearance (mainly for buttons) menu_bar to place other windows (mostly buttons) automatically scrollbar to interactively enter a number with a slider text_popup to show text in an popup (eg. a help text) pixmap_window has a backing store mechanism so it is used for complicated X drawings (functions, lattices..) coord_window defines real valued co-ordinates and drawing functions that X operate directly on them (world co-ordinates) X X * mapping between X-events to window instances X The main problem in writing an object-oriented X-interface is the interaction between windows and events. Since every window should be represented as an instance of a peculiar class any X-event that is assigned to this window should be able to trigger class specific action. While the second part of this problem is easily solved with virtual functions of C++ the first requires a little trick. In Grafix I use a table which maps the window-IDs that are generated from the X-server calls to XCreateWindow() to the this-pointer of the attached window instance. X Since version 1.3 the mechanism has internally changed a lot (but the interfacing functions are not affected). Now I use a hash table (implemented as vector of lists). The vector index is computed as (WID % tabsize) and for each index the list is parsed until the requested WID is found. By setting the tabsize to about 100 it is guarateed that each list is kept quite short and list parsing doesn't take too long time. (In this case you would see a delayed response of mouse actions). However, the tabsize can be set to any value. The number of windows is now unlimited. X Upon deleting a window, the list entry is removed to keep the lists short. However, it sometimes occures that deleted windows receive X-events. (Eg. if the deleting was done from a button press of a button that is part of the deleted window, and the next button release will occur). These events are simply ignored, since the search function returns NULL. X X * basic callbacks mechanism : the main_loop X Any X-application must implement a loop for handling events. In Grafix this "main_loop" is a method of "main_window". This means in a typical application one creates a main_window instance (surely with some children windows) and then before the closing "}" of main it calls "mw->main_loop();". X All the rest (the interactive run) has to be managed inside this call. X Here I will give a short glance how this internally works. (The reading of this paragraph should not be obligate for a normal user) The first statement in this loop is a call to XNextEvent() which queries the X-server for the next event in the queue. From the window-ID of the event-structure the corresponding instance is computed (this-pointer) and the general "CallBack" function is invoked which calls the virtual function that is attached to the event type. There a specific event handling takes place. Some important event types should be mentioned here : Expose ButtonPress, KeyPress Enter/Leave Configure All event types have a default virtual handler in the window class which can (and will) be modified in inherited classes. X An application can have more than one main_windows and therefore invoke a main_loop for each of them. This is not useful in normal applications since they all basically do the same. However, this can be used to temporarily define main_windows (on the execution stack, ie. as local object inside a function) and then call it's main_loop to prevent the execution to leave this function before a certain action is performed. This is used eg. in the "confirm_box" and "file_selection_box" class. X X * colors X The Xlib uses several different modes of color display. Depending on your hardware you can use a subset of these. The usual color modes are : X - TrueColor : with at least 16 bpp (bits per pixel) color depth. X it means that you can use all colors (without a palette mechanism) X at the same time. Usually with 16bpp you have a color resolution X of 565 rgb, ie. 5 bit for red and blue, 6 bit for green X (giving total 65536 enries). The colors X that you define with XAllocColor are then rounded to the nearest X entry of this table. X - PseudoColor : usually for 8bpp displays. Here you have only 256 colors X that can be displayed at the same time. Therefore a paletting X mechanism is used to select the colors you want to see on the screen. X But be aware that the palette size is only low 256, which can X be easily overflow. Eg. a palette from the lattice-applications X uses 100 entries, the window manager needs some 10 for decorations, X the button colors need 3 at least, and so do other programs you have X running in X. X The main advantage of the PseudoColor is, you may recolor a picture X immediatly by simply changing the palette (used in the lattice progs) X 5. How to write own applications with Grafix (overview) ======================================================= 5.0 "Hello World" example X Here is the whole code of the well known "Hello World" program with Grafix : X X #include "window.h" X main(int argc, char *argv[]) { X main_window *mw = new main_window(argv[0],200,200); X text_win *tw = new text_win(*mw,"Hello World !",180,20,10,50); X button *qb = new quit_button(*mw,100,20,50,150); X mw->main_loop(); X } X 5.1 general hints, the class "window" X X * the window class X window is the superclass of all others. Each window keeps a list of its children. This list is needed for mapping, resizing, and deleting. It is quite easy to reconstruct from this the complete window tree of a running application starting with the root window, or for any main_window. X X * some basic methods for the window class X constructor : takes as arguments parent window, width and height (in pixel) the relative position on the parent (with resp. to left upper corner = 0,0) and the border width. The constructor mainly calls "XCreateSimpleWindow" with default parameters, sets the this pointer in the global pointer table and appends itself to the window tree. X X * the window mapping, expose events and the related callbacks X the exposing of a window is the most important event. It is usually the first trap a newcomer to X falls in. "Why doesn't the window appear when I draw it ?". The reason is that the mapping and drawing has to be done (nearly) asynchronuously with other things. Exposing events are triggered whenever a part of a window becomes visible. That is the case when it is mapped for the first time but also when an obscuring window is removed (from the window manager eg.). The normal course in creating a window is as follows: At the start of the main loop a "RealizeChildren" is invoked which recursively parses the window tree and invoking for each subwindow the function chain X X -> Realize X -> XSelectInput X -> Map X -> draw_interior X -> XMapWindow X Here "draw_interior" is a virtual function that serves only as hook for more complicated classes (pixmap_window, see below). X Up to this stage nothing is shown on the screen. The actual exposing is performed indirectly through the event loop. Upon Map request the X server generates an expose event that invokes the Expose_CB callback. This virtual function simply calls the "redraw" function. X So the actual drawing has to be done by defining of a new "redraw" function for any derived class. This function is invoked every time the window (or parts of it) becomes visible. X The redraw function can (and will) be also called directly from other functions or callback handlers. X X * pointer and button events X Each X event correspods to a virtual function that is usually a dummy. The only exception is the Button Press 3 that serves per default as a help button which can popup a help menu for this window. For instance the button class uses the events Enter and Leave to show a changing appearance and the ButtonPress or ButtonRelease to perform some action (ie. a callback) X X * configure and resize events X If the user interactively resizes a main window (with the help of the window manager) by drawing the border or edges the X server issues a configure event. This event type is managed by the virtual function "resize". By default this method enlarges or shrinks all children recursively by the same factor. If another behaviour is intended (eg. for buttons and menubars this is of course not appropriate) it should be overwritten. X X * drawing methods X These methods can be used to change the interior of a window clear DrawString PlaceText line DrawPoint Usually they draw directly into the X window and thus are to be seen immediately. However, they are overwritten in the pixmap_window class (see below) X X * pixmaps X Pixmaps are used in X-graphics, where a complete redraw for each mapping event is too time consuming. Remember, mappings occur every time, a part of a window becomes visible. In these cases, it is better to store the content of the window in an X buffer structure called "Pixmap" and copy from it only the rectangle which is actually seen freshly (or again) onto the screen. In grafix Pixmaps are represented as "pixmap_window" (see below). X X * destructors X The proper handling of deleting windows requires some thoroughness. Firstly, one has to consider that a deletion of any window automatically deletes all of its children recursively. This also requires that each window instance has to remove its own entry in the parents children list. In this new version this task is solved. This means that destruction of windows is now completely arbitrary. Automatically, the destruction of all created windows is guaranteed since they all are descedants of the root_window, which is deleted upon program termination. However, if you delete a window beforehands, it will work too. Nevertheless, sometimes problems do arise, when windows are to be managed in a second hierarchy (besides their window hierarchy). X Consider the case of the lattice_manager, which is a normal descendant of the window class. It has some popup menus for parameter setting. Upon deletion of the lattice_manager they also should be deleted from within it's destructor, since the whole lattice_manager may be constructed dynamically. This will lead to seg faults in the case when the root_window destructor invokes the deletion process : it also deletes the popups since they are it's children and this may take place *before* the destructor of the lattice_manager is invoked -> crash. In such cases the programmer has to insure the proper deletion order. (Or, for simplicity, omit the deletion) X The function 'safe_delete' may also be used for main_windows, when the deletion order cannot be controlled easily : it deletes only if the window is still a child of the root_window, ie. it still exists. X X * general remarks about callback functions X Let us consider the example of a push button instance which shall invoke some action - eg. computing some values and then show the results in some windows. The constuctor for a simple callback_button eg. takes as argument a void function with no arguments. It is, of course, easy to define for each action a function which invokes the intended actions. However, if the action refers to a window then this window has to be defined globally (or the this pointer) to make it accessible to the callback function. X This approach is neither elegant nor does it allow more complex actions. (It is used in some examples, nevertheless). On the other hand it is not possible to define parameter types that fit to a class that will be defined in the future. X To evade this problem there are defined some button types which allow for complicated callback functions (template_button, instance_button, function_button, radio_button). For special actions the user has to define his own button classes. X 5.2 files X window.h basic include file, definition of all fundamental classes X also defines some general functions (set color, set GC ..) window.c corresp. code, lattice.h include file for lattice_manager classes lat_win.c ) reg_man.c ) the sources for these classes lat_man.c ) libwin.a an archive which combines all object files eventnames.h from Xlib for debugging icon.h the icon image palette.h include file for palette manipulations palette.c files.h for file selection box files.c clock-demo.c demo for online clock calc.c calculator demo edit-demo.c more demos pal-demo.c file-browser.c color_table.c win-demo.c cursors.c show all X cursors lat-demo.c ) lat2demo.c ) demos for the lattice class solver.c ) one-dim.c ) the one-dim example two-dim.c ) smolark.h ) the two-dim example smolark.c ) X animator.h ) classes for computing and storing 2/3-dim integrations and animator.c ) replay these "video"-files as animations, three-dim.c ) prototype for interactive 2/3-dim integration three-nxnynz.h wave.c ) very simple example : the 3-dim wave eq. integrator replay.c replayer for "video"-files *.icon some icon bitmaps tree.h/c classes for displaying tree graphs gccinc include files for the gcc-lib which possibly are not installed X on your platform scrolled_demo.c simple demo for use of scrolled_windows X 6. Some details about other basic classes : =========================================== X main_window : a direct child of the root window. It is managed by the X window manager. It can be connected with an icon (method X set_icon). Each application must have at least one main_window, X other main_windows can be used as popup windows. X defines a method "main_loop", which must be invoked to start X the user interaction. X Specific behaviour can be set by using the "polling_mode" X and "polling_handler" method. This way it is possible to X let applications run without user actions (animations a.o.) X X pixmap_window: a window for complex drawings eg. functions, figures, etc. X for which a complete redrawing upon each expose event would X be too slow. Drawing actions are performed indirectly into a X pixmap which is mapped from the expose or redraw methods. X They have an additional virtual method "draw_interior" that X MUST be overwritten by an derived class (it is a pure virtual X function). This method should perform the actual drawing X if the window interior (eg. what you want to see). X For these windows mapping and expose events do not invoke the X redraw method but they copy the pixmap onto the screen. X However, explicit (re)displaying of the windows should be done X with the usual "redraw" method. X Since pixmap_window is a virtual class, it cannot be X instantiated directly. X X coord_window : derived from pixmap_window with additional functions to X define real co-ordinates and drawing functions that operate X in these coordinates. Thus useful for displaying functions as X graphs, co-ordinate systems aso. Examples can be found in the X one-dim and two-dim demos and the lattice_window class X X menu_bar : enables a simpler definition of buttons (autoplacement) X X buttons : call an action on button press X X system_button: calls "system" with a passed string as argument X X xwd_button : makes a window dump with the "xwd" program X to get a direct hardcopy with that button define eg. : X X new xwd_button(*mb2,"hardcopy"," | xpr | lpr",this) X which will pipe the output of the xwd command directly to the X printer (assumed to be "lpr"). The "this" pointer is the window X that shall be printed (or any other window). X X pulldown_window : special main window that is not managed by the WM. It is X usually attached to a button and pops up beneath it. X X scrollbars : window with a slider to enter a numerical value interactively X X edit_window : allows editing of strings X X text_viewer : a window with scrollbar to visit text buffers X X scrolled_window : has a virtual window which can be shifted with attached X horizontal and vertical shifters (special scrollbars) if the X virtual size exceeds its real size. Thus useful for X visualization of large areas. X The attached virtual window must be derived from class X virtual_window. X See "scrolled_demo.c" for simple demo or "class-browser" and X dir-tree for other demos X X Tree_window : a scrolled window for displaying general tree graphs X (directory trees, inheritance graphs, window trees...) X 7. the window class tree (simplified) ===================================== X *** run "class-browser *.h" to get it completely *** X X these classes are defined in window.h and lattice.h X window X main_window X pulldown_window X text_popup X pixmap_window X coord_window X region_manager (lattice.h) X lattice_window " X lattice_manager " X time_lat (animator.h) X text_win X menu_bar X plate X slider X pure_scrollbar X scrollbar X display_window X edit_window X button X delete_button X quit_button X help_button X callback_button X template_button X instance_button X function_button X toggle_button X toggle_redraw_button X pulldown_button X radio_button X popup_button X unmap_button X system_button X xwd_button X X other classes are defined in palette.h lattice.h files.c X Also numerous examples are to be found in the demos. X 8. The interactive integration prototype three-dim.c ==================================================== Files : animator.*, three-dim.c, three-nxnynz.h, wave.c, replay.c X These classes allow the saving and replaying of time sequences of an finite difference integration process. During integration an arbitrary number of arrays that are computed are stored in a "video"-file. X three-dim.c serves as a prototype to hook any 2- or 3-dim finite difference time integrator (here as example used : "wave.c"). It enables interactive integration with online graphic display of the computed arrays. Its interface is very clearly defined (class "integrator") and consists mainly on the definition of three functions (init, step, exit) and the array names to display. X The class integrator implements the graphical interface and the video saving feature. The interface enables : stepwise or continuous integration, online display modification, stopping, spawning (of new windows to display other arrays), resetting. X The program "replay" allows the replaying of saved video files. Since the array descriptors are part of the video file the program is idependant of the integration program. It enables : continuous and stepwise playing (forward, backward), stopping, spawning, reloading (of other files, but only with the same header !!), synchronuous spawning (that is starting another program with a different video file, which is displayed synchron to the spawner). X 8.1. The main classes of animator.h ----------------------------------- X class animator : store time sequences of grid values (nx*ny) in a file X and to enable animated playback of them (program "replay.c") X the arrays are arranged in separate columns, which are connected X with menu-buttons for the lattice class X class time_lat : public lattice_manager X a lattice manager for display time sequences of arrays X with selector menus, clock and spawning feature X class play_lat : public time_lat X a time_lat with animator and action used for replay and integrators X class play_main : public main_window X a main window with menubar, a play_lat-window and a spawn-method X it is bound to an animator, which columns are displayable X class player : public play_main X has a new main_loop for polling, and two handlers to switch X between play and stop; to be used as primer window X upon playing the pure virtual method "step" is called X class integrator : public player X general purpose interface to invoke any program that solves time step X integrations, creates an animator (and video file) X the members init_solver, step_solver, exit_solver must be defined by X the application (see three-dim.c for use) X 8.2. The video file format (see animator.*, replay.c) ------------------------------------------------- it consists of an ASCII-header and an arbitrary number of unformatted data records, one for each time step. X header format: - headline (string) to describe the content - nx ny ncols : one text-line with grid size (nx,ny) and the number of X columns in the menu line - for each column : X nitems : number of items in the menu (see below) X for each item : X name string (terminated with NL) X gamma z0 : two formatted reals, (norm factor, z-shift for display) X record format: all data are unformatted - 1 int = integration time (in seconds) - nx*ny single floats for each item and each column X 9. portations to other platforms ================================ The platform specific handlic should be ideally restricted to the file "grafix.mk" which is included by the Makefile. X Here the paths to the compiler an Xlib can be set depending on HOSTTYPE, and possibly compiler definitions set. X X SHAR_EOF chmod 0644 HOWTO.txt || echo 'restore of HOWTO.txt failed' Wc_c="`wc -c < 'HOWTO.txt'`" test 27886 -eq "$Wc_c" || echo 'HOWTO.txt: original size 27886, current size' "$Wc_c" fi # ============= COPYING ============== if test -f 'COPYING' -a X"$1" != X"-c"; then echo 'x - skipping COPYING (File already exists)' else echo 'x - extracting COPYING (Text)' sed 's/^X//' << 'SHAR_EOF' > 'COPYING' && X GNU GENERAL PUBLIC LICENSE X Version 2, June 1991 X X Copyright (C) 1989, 1991 Free Software Foundation, Inc. X 675 Mass Ave, Cambridge, MA 02139, USA X Everyone is permitted to copy and distribute verbatim copies X of this license document, but changing it is not allowed. X X Preamble X X The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. X X When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. X X To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. X X For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. X X We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. X X Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. X X Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. X X The precise terms and conditions for copying, distribution and modification follow. X X GNU GENERAL PUBLIC LICENSE X TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION X X 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". X Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. X X 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. X You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. X X 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: X X a) You must cause the modified files to carry prominent notices X stating that you changed the files and the date of any change. X X b) You must cause any work that you distribute or publish, that in X whole or in part contains or is derived from the Program or any X part thereof, to be licensed as a whole at no charge to all third X parties under the terms of this License. X X c) If the modified program normally reads commands interactively X when run, you must cause it, when started running for such X interactive use in the most ordinary way, to print or display an X announcement including an appropriate copyright notice and a X notice that there is no warranty (or else, saying that you provide X a warranty) and that users may redistribute the program under X these conditions, and telling the user how to view a copy of this X License. (Exception: if the Program itself is interactive but X does not normally print such an announcement, your work based on X the Program is not required to print an announcement.) X These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. X Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. X In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. X X 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: X X a) Accompany it with the complete corresponding machine-readable X source code, which must be distributed under the terms of Sections X 1 and 2 above on a medium customarily used for software interchange; or, X X b) Accompany it with a written offer, valid for at least three X years, to give any third party, for a charge no more than your X cost of physically performing source distribution, a complete X machine-readable copy of the corresponding source code, to be X distributed under the terms of Sections 1 and 2 above on a medium X customarily used for software interchange; or, X X c) Accompany it with the information you received as to the offer X to distribute corresponding source code. (This alternative is X allowed only for noncommercial distribution and only if you X received the program in object code or executable form with such X an offer, in accord with Subsection b above.) X The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. X If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. X X 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. X X 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. X X 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. X X 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. X If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. X It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. X This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. X X 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. X X 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. X Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. X X 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. X X NO WARRANTY X X 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. X X 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. X X END OF TERMS AND CONDITIONS X X How to Apply These Terms to Your New Programs X X If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. X X To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. X X X Copyright (C) 19yy X X This program is free software; you can redistribute it and/or modify X it under the terms of the GNU General Public License as published by X the Free Software Foundation; either version 2 of the License, or X (at your option) any later version. X X This program is distributed in the hope that it will be useful, X but WITHOUT ANY WARRANTY; without even the implied warranty of X MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the X GNU General Public License for more details. X X You should have received a copy of the GNU General Public License X along with this program; if not, write to the Free Software X Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. X Also add information on how to contact you by electronic and paper mail. X If the program is interactive, make it output a short notice like this when it starts in an interactive mode: X X Gnomovision version 69, Copyright (C) 19yy name of author X Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. X This is free software, and you are welcome to redistribute it X under certain conditions; type `show c' for details. X The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. X You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: X X Yoyodyne, Inc., hereby disclaims all copyright interest in the program X `Gnomovision' (which makes passes at compilers) written by James Hacker. X X , 1 April 1989 X Ty Coon, President of Vice X This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. SHAR_EOF chmod 0644 COPYING || echo 'restore of COPYING failed' Wc_c="`wc -c < 'COPYING'`" test 17976 -eq "$Wc_c" || echo 'COPYING: original size 17976, current size' "$Wc_c" fi # ============= LOG.txt ============== if test -f 'LOG.txt' -a X"$1" != X"-c"; then echo 'x - skipping LOG.txt (File already exists)' else echo 'x - extracting LOG.txt (Text)' sed 's/^X//' << 'SHAR_EOF' > 'LOG.txt' && 15.12. posting package to comp.sources.misc X saved in grafix/post-15.12 X added scrolling with keys : PgUp/Dn arrow-up/down to file selection box X -> files.c X 16.12 : cleanup event mask setting; default selection_mask for the window class is only Expose and Configure, derived classes add masks by demand -> less events, more transparency -> window.c X 17.12 - 19.12: X calc.c - name conflict for Solaris (div-> divi) resolved files.c - extended for complete viewing of texts X new classes :vert_scrollbar, text_window, text_viewer (files-demo.c) - deleted , replaced by : file-browser.c - demo for file viewer with spawning and loading new files, X also with file_selection_box files.c - file_selection box extended : X now has scrollbars for directory and file selector with standard X 3-button interface (button 1/3 = pgup/dn, button 2 = draw/set) X also key-events : next,prior, arrow-keys X button-1-press (in selector) -> select file/directory X window.h - constructor delete_button for menu_bar parent def. lat_win.c - added z-axes ticks X 23.1: window.c - bug with WatchCursor fixed : it didn't vanish when other main X windows were spawned. (there was only one global pointer "watch_main") X New solution : no more restore in event loop, but explicitely X to call ResetCursor(); after computation X corrections : window.h, lat_man.c, one-dim, two-dim lattice: floating point prints (ticks, gamma) %f -> %g for better X readability X 20.2. grafix.mk : HOSTTYPE (nonportable) replaced by uname (portable) lat_win.c : z-ticks also for small heights (ntick > 0) X X 27.2 Makefile : make depend introduced (File .depend) by help of Ulrich Lauther X Weird behaviour on "Close" via window manager resolved. If it was done for a child then the whole program crashed with : X XIO: fatal IO error 32 (Broken pipe) on X server ":0.0" X after 626 requests (622 known processed) with 0 events remaining. X The connection was probably broken by a server shutdown or KillClient X X explanation (see mwm.1) X X f.kill X This function is used to terminate a client. If the X WM_DELETE_WINDOW protocol is set up, the client is sent X a client message event, indicating that the client win- X dow should be deleted. If the WM_SAVE_YOURSELF proto- X col is set up and the WM_DELETE_WINDOW protocol is not X set up, the client is sent a client message event, X indicating that the client needs to prepare to be ter- X minated. If the client does not have the X WM_DELETE_WINDOW or WM_SAVE_YOURSELF protocol set up, X this function causes a client's X connection to be ter- X minated (usually resulting in termination of the X client). Refer to the description of the quitTimeout X resource and the WM_PROTOCOLS property. solution: X XSetWMProtocols WM_DELETE_WINDOW for all main_windows; X a global top_main is declared (which is always the first created main_window) X and a event_handler main_window::ClientMsg_CB defined to handle these ev X 9.6. scrollbars (even pure_scrollbars) get a member nticks, (which is 0 by default) and determines the number of tick lines to display on x-the axis changes in window.h, window.c X 21.6. clock_win : in window.c/h added. A class to display a simple analogue clock also a demo clock_demo.c written. X 23.6. main_window - constructor allows argument fix_pos = 2 : map at center of the screen X 30.6. palette.c : handler for error "no more color cells" changed; now only warning X so more than 2 lattice applications can run at the same time on one X display X 12.7 animator and replay included in grafix (from dymos) X replay as a demo, video files are in subdirectory video X 19.7 window.c,h: bug fixed : close button of window manager used to kill the appl. X main_window class : XSetWMProtocols added, and X event handler for ClientMessage to unmap or exit. X To find the top main_window the variable top_main is used. X For this the close button invokes exit, else only unmap X (Does not work properly if an marginal window created as first mw) X 26.7. lattice.* : z0 - as shift value introduced, also as managed value X 4.8. three-dim.c (and wave.c as ex.) the prototype for any interactive integration X program, simplified interface : integrator class (s.below) animator.*, replay.c : extended with new classes : X time_lat, play_lat, play_main, player, integrator X 8.8. lattice.* : the value display window (display_cursor) is now defined as X a main window -> no more clipping. It now follows the pointer directly X -> search the nearest lattice point in 3-dim ! X lat_win.c : function "make_lattice" replaced by generalization of "make_body" X now the value display works for all types of displays, since scp X is always correct ! X 28.8. polling mode changed : now polling_handler is a virtual function in main_window X and polling_mode is member -> changes in window.*, clock-demo, animator.* X simplified ! X 1.9. replay.c : synchronization from child to parent fixed (with signals) X Now the child process can also be ended, and a new video file can X be loaded. X 28.9. switch_button : introduced in window.h/c X 2.10. scrollbar : error fixed with move & callback mechanism, since the callback was X invoked with actual slider pos (in pixels) this lead to rounding errors X now : extra methods "move" and "move_cb" are defined. On mouse positioning X move_cb is invoked, otherwise from "change" -> move and callbck_val X tick_scrollbar & play_scrollbar included in window.c/h X 20.10 new classes in window.c/h: ========================== scrolled_window : a window with virtual size that can be moved with X scrollbars if it is larger than the actual window. Proper resizing ! X twodim_input : a twodimensional "scrollbar" to get user input from mouse X derived from that : horizontal_shifter, vertical_shifter : are needed by scrolled_window X demo for these : scrolled_demo, class_browser X 26.10. files : text_viewer fixed, tabs, scrolling tree graphics ============= class_browser: nearly completed, failures if graph contains unbalancable "cycles" X eg class1 X / | X c2 | X \ | X class3 X and insertion sometimes failes ( /fgrab/ ) 27.10. tree.c/tree.h separated dir-tree.c : new simple demo for the use of tree classes, should X serve as learning model X 29.10. one-dim/two-dim : new "run" button included to match newer apps. X 30.10. gccinc : subdirectory for gcc-lib include files that are needed for X regexp parsing (class-browser), X which are not on all systems installed (Sun) X will be included in the tar file window.c/h : irint and sincos for Suns replaced by simple standards X because older SunOS seem to don't have them X 31.10. calc.c : keyboard input of numbers and arith. operators -> new X german clean : win-demo.c, edit-demo.c, one-dim.c, two-dim.c, window.h (sigh !) X window.c (sigh !) X edit_window : cursor works now correct in all color modes (8bpp, 16bpp) X 1.11. window.c : destructors cleaned up, now also the entry in parents child list is X correctly removed -> also static windows can be defined and deleted !! X Whow !! X palette.c : TrueColor mode now supported for >= 16bpp !! X minor drawback: if the palette changes, it is not visible for X lattice windows immediately, but only when next draw occurs X X 3.11. german clean : lattice.h lat_win.c lat_man.c reg_man.c (also help page) X -> it should be complete now !! X replay : help text (help button) included X class-browser : error fixed (undefined classes -> path == 0) X 4.11. popup buttons : new feature : on second press unmap the popup X (also help_button -> now a subclass of popup_button) X error in three-dim fixed : difficult to find : in animator.c was a erroneous X allocation with "char(200)" (wrong brackets) which resulted in X subsequent failures of simple "new char[8]" (but correct ones!) X ====================================================================== X 4.11. 19:07 version 1.2 uploaded to sunsite, LSM entry mailed, announce posted X ==================================================================== 6.11. animator : class replayer gets a rotate button and so "three-dim" and "replay" X have this option, help text added X polling_handler -> step_handler X window.h: irint macro does not use rint anymore -> HP error X 7.11. window.c : hash table for mapping X-IDs to window pointers implemented X -> now there is no more limit of the number of windows and they X may be constructed and deleted in any fashion !!! X SHAR_EOF chmod 0644 LOG.txt || echo 'restore of LOG.txt failed' Wc_c="`wc -c < 'LOG.txt'`" test 8540 -eq "$Wc_c" || echo 'LOG.txt: original size 8540, current size' "$Wc_c" fi # ============= TODO.txt ============== if test -f 'TODO.txt' -a X"$1" != X"-c"; then echo 'x - skipping TODO.txt (File already exists)' else echo 'x - extracting TODO.txt (Text)' sed 's/^X//' << 'SHAR_EOF' > 'TODO.txt' && * edit-windows : focus X X > Also, the text cursor in edit_window doesn't work on the HP, but does on X > the Sun server. But under the sun server and OLWM it doesn accept the X > keyboard focus properly; I have to click in the main window's title bar X > first to set the focus to the window, and then click in the edit_window. X > On the HP under MWM I can just click in the edit_window, and the focus X > changes and the title bar gets highlighted. I suspect that OLWM is less X > tolerant of applications that don't play by the rules for requesting X > keyboard focus - I'll try to see if I can fix this. X > X * lattice : X - fuer grosse z-Werte Darstellung begrenzen (Laufzeit !) X * class-browser : loop-Fehler, graph. Anordnung der buttons verbessern X * customizations : button-colors, backgrd-color, click-to-type X from .Xresources and/or local custom-file X * makefile, grafix.mk clean up X * better icons ! X * replay hangs after few steps when *both* spawn and synchron are active ! X (synchr seems to fail) X * rotate mode for lattices, region manager should open a new lattice window, X and both views can be shown simultaniously X * class_browser : popup windows should display whole file X (but scrollbar set according to class def. in text) X SHAR_EOF chmod 0644 TODO.txt || echo 'restore of TODO.txt failed' Wc_c="`wc -c < 'TODO.txt'`" test 1255 -eq "$Wc_c" || echo 'TODO.txt: original size 1255, current size' "$Wc_c" fi # ============= FAQ.txt ============== if test -f 'FAQ.txt' -a X"$1" != X"-c"; then echo 'x - skipping FAQ.txt (File already exists)' else echo 'x - extracting FAQ.txt (Text)' sed 's/^X//' << 'SHAR_EOF' > 'FAQ.txt' && X 1. Q: I can't figure out the use of PlaceText/DrawString and Line - X It seems to me that if I want to draw a horizontal red line in the X main window, I could: X X main_window *mw=new main_window("Hello",300,300); X setcolor(alloc_named_color("red")); X mw->Line(10,10,290,10); X X but it doesn't work that way... how do I use placetext/drawstring/line? X A: Indeed, drawing does not work like you wrote. Well, it's quite the *default* question about Grafix. X For drawing into a window you have to : 1. define a subclass of "window" (or some other window class) 2. overload it's "redraw" method by a specific function that does the X desired drawing 3. create an instance of this new class as subwindow in your main_window. X eg. see "win-demo.c" : /*****************************************/ .... // derived class of window class my_window : public window { public: my_window(window & parent, int w, int h, int x, int y) : X window(parent,w,h,x,y) {} X virtual void redraw() { // virtual fn replaces window::redraw X int y; X for (y=0; y < height ; y+= 3) line(0, y, width, y); X } }; .... main(int argc, char *argv[]) { X main_window *mainw = new main_window(argv[0], 300, 300); // Main Window .... -- other definititons -- X new my_window(*mainw, 60, 60, 110, 0); // user-defined window X mainw->main_loop(); } /******************************************************/ X This seems quite complicated at a first glance, however, if you understand a little bit more about X-window you will see that only this approach will work with it. X BTW. this is also explained in HOWTO.txt :-) -------------------------------------------------- X 2. Q: X > I am having trouble compiling your demos. I get the message X > cannot open -lX11. Also, I can't find any installation instructions. X > Can you help me? X X A: You probably have an unusual path for your Xlib. Try to find the file libX11.a on your system. It shoulb be located somewhere under "/usr/X11/lib...", "/usr/X11R6/lib" or similiar. Then add the path ( without the last "/lib") to the XPATH-macro in the file "grafix.mk" eg : X ifeq ($(shell uname),Linux) XXPATH = /usr/X11R6 LFLAGS = -L$(XPATH)/lib endif X and then make again. X The second possibility is you haven't installed Xlib on your system yet. SHAR_EOF chmod 0644 FAQ.txt || echo 'restore of FAQ.txt failed' Wc_c="`wc -c < 'FAQ.txt'`" test 2263 -eq "$Wc_c" || echo 'FAQ.txt: original size 2263, current size' "$Wc_c" fi # ============= Makefile ============== if test -f 'Makefile' -a X"$1" != X"-c"; then echo 'x - skipping Makefile (File already exists)' else echo 'x - extracting Makefile (Text)' sed 's/^X//' << 'SHAR_EOF' > 'Makefile' && # Makefile for grafix-applications # wolf 6/94 X include grafix.mk X DEMOS = class-browser hello win-demo edit-demo file-browser cursors calc \ X dir-tree \ X pal-demo lat-demo lat2demo one-dim two-dim clock-demo three-dim replay X PROGS = scrolled_demo X TOSHAR = window.c window.h lat_win.c lat_man.c reg_man.c lattice.h \ X palette.c palette.h files.c files.h smolark.c smolark.h solver.c \ X animator.h animator.c wave.c three-nxnynz.h \ X icon.h eventnames.h README.txt HOWTO.txt COPYING LOG.txt TODO.txt \ X FAQ.txt Makefile grafix.mk \ X calc.icon tree.h tree.c tree_icon.h gccinc \ X $(DEMOS:%=%.c) $(PROGS:%=%.c) X all: demos $(PROGS) X demos: $(DEMOS) X test: clean depend all tgz test-tgz X # make demos = ~ 100 sec P90 X # the classes to lattice.h are located in files lat_win, lat_man, reg_man LATTICE = lat_win.o lat_man.o reg_man.o X libwin.a: window.o palette.o $(LATTICE) X $(AR) libwin.a $? X ranlib libwin.a X hello: hello.o window.o win-demo: win-demo.o window.o edit-demo: edit-demo.o window.o cursors: cursors.o window.o calc: calc.o window.o pal-demo: pal-demo.o libwin.a lat-demo: lat-demo.o libwin.a lat2demo: lat2demo.o libwin.a one-dim: one-dim.o solver.o libwin.a two-dim: two-dim.o smolark.o libwin.a three-dim: three-dim.o wave.o animator.o files.o libwin.a file-browser: file-browser.o files.o window.o clock-demo: clock-demo.o window.o replay: replay.o animator.o files.o libwin.a tree: tree.o window.o files.o scrolled_demo: scrolled_demo.o window.o class-browser: class-browser.o tree.o window.o files.o dir-tree: dir-tree.o tree.o window.o files.o X clean: X \rm -f *.o *.a $(DEMOS) $(PROGS) X \rm -rf ttgz/* X masterproper: clean X \rm -f .depend X ####### make shell archives for comp.sources.misc -> subdir post ##### shar: X shar -o Grafix.shar -l 100 -n Grafix -a -s wolf@first.gmd.de \ X $(TOSHAR) X cat intro.txt Grafix.shar.01 > tmp; mv -f tmp Grafix.shar.01 X test-shar: X \rm -rf tshar/* X cp *.shar* tshar/ X cd tshar; unshar *shar*; $(MAKE) demos; X ###### generate tar-file for uploading to ##### # "make tgz" - generates grafix.tgz file X tgz: X $(TAR) -czh -f grafix.tgz $(TOSHAR) X uuencode grafix.tgz grafix.tgz > grafix.tgz.uu X test-tgz: X \rm -rf ttgz/* X cp grafix.tgz ttgz/ X cd ttgz; $(TAR) -xvzf grafix.tgz; $(MAKE) all X # runs all the demos : demorun: $(DEMOS) X @for demo in $(DEMOS); do (echo "running $$demo"; exec $$demo;); done X # make dependencies: depend: X $(CC) -MM $(CFLAGS) *.c > .depend X -include .depend X X SHAR_EOF chmod 0644 Makefile || echo 'restore of Makefile failed' Wc_c="`wc -c < 'Makefile'`" test 2469 -eq "$Wc_c" || echo 'Makefile: original size 2469, current size' "$Wc_c" fi # ============= grafix.mk ============== if test -f 'grafix.mk' -a X"$1" != X"-c"; then echo 'x - skipping grafix.mk (File already exists)' else echo 'x - extracting grafix.mk (Text)' sed 's/^X//' << 'SHAR_EOF' > 'grafix.mk' && # grafix.mk wolf 11/94 # to be included in the Makefiles # # used for OS-adaptation : set the following macros # GCCINC : path for gcc-lib includes (eg "regex.h") # XPATH : path for X11R6 (for includes and libs) # # uname = Linux : GCCINC not needed # uname = SunOS : GCCINC : in ./ copied X X TAR = tar GCCINC = ./gccinc X ifeq ($(shell uname),Linux) XXPATH = /usr/X11R6 LFLAGS = -L$(XPATH)/lib CFLAGS = -Wall -I$(GCCINC) -DLINUX endif X ifeq ($(shell uname),SunOS) XXPATH = /opt/X11R6 CFLAGS = -I$(XPATH)/include -I$(GCCINC) -O2 -DSPARC LFLAGS = -L$(XPATH)/lib TAR = gtar endif X ifeq ($(shell uname),HP-UX) XXPATH = /usr LFLAGS = -L$(XPATH)/lib/X11R5 CFLAGS = -I$(XPATH)/include/X11R5 -I$(GCCINC) -DHP endif X # CFLAGS += -DNDEBUG for final release CFLAGS += -c LFLAGS += -lm -lX11 X CC = g++ AR = ar rc X # clear suffixes list .SUFFIXES: X # pattern rules: %.o: %.C X $(CC) $(CFLAGS) $< X %.o: %.c X $(CC) $(CFLAGS) $< X %: %.o X $(CC) -o $@ $^ $(LFLAGS) X SHAR_EOF chmod 0644 grafix.mk || echo 'restore of grafix.mk failed' Wc_c="`wc -c < 'grafix.mk'`" test 967 -eq "$Wc_c" || echo 'grafix.mk: original size 967, current size' "$Wc_c" fi # ============= calc.icon ============== if test -f 'calc.icon' -a X"$1" != X"-c"; then echo 'x - skipping calc.icon (File already exists)' else echo 'x - extracting calc.icon (Text)' sed 's/^X//' << 'SHAR_EOF' > 'calc.icon' && #define icon_width 80 #define icon_height 55 static char icon_bits[] = { X 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, X 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, X 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, X 0xff, 0xff, 0xff, 0xbf, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, X 0x00, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0xe7, 0x9c, 0xa2, X 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x84, 0x90, 0x62, 0x06, 0x00, X 0x00, 0x00, 0x00, 0x00, 0x28, 0x84, 0x9c, 0xa3, 0x05, 0x00, 0x00, 0x00, X 0x00, 0x00, 0x28, 0x84, 0x10, 0x62, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, X 0x38, 0x84, 0x1c, 0xa2, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, X 0x00, 0x60, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, X 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, X 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, X 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xfa, 0xfd, 0x7e, 0xbf, 0xfa, 0xfb, X 0xf7, 0xef, 0xdf, 0xaf, 0x9d, 0xe5, 0x42, 0x61, 0x6d, 0x2b, 0x76, 0x6c, X 0x58, 0x5b, 0x6a, 0xd5, 0x7a, 0xbd, 0x6a, 0xab, 0x76, 0xed, 0x5b, 0xab, X 0xed, 0xb5, 0x7a, 0x7d, 0x6d, 0xab, 0x76, 0xed, 0x5b, 0x5b, 0xea, 0xb5, X 0x62, 0xb1, 0x0a, 0xab, 0x76, 0x6c, 0x58, 0xab, 0x6d, 0xd5, 0x7a, 0x7d, X 0x6d, 0xab, 0x76, 0x6d, 0x5f, 0x5b, 0x9a, 0xe5, 0x42, 0xbd, 0x6a, 0x2b, X 0x76, 0x6c, 0x58, 0xa8, 0xfd, 0xfd, 0x7e, 0x7f, 0xfd, 0xfb, 0xf7, 0xef, X 0xdf, 0x5f, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, X 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xfa, 0xfd, X 0x7e, 0xbf, 0xfa, 0xfd, 0x7e, 0xbf, 0xdf, 0xaf, 0x0d, 0x85, 0x66, 0x71, X 0xfd, 0xfd, 0x7e, 0xaf, 0x56, 0x5e, 0x6a, 0xb5, 0x5a, 0xad, 0xfa, 0xfd, X 0x5a, 0xa7, 0xd6, 0xac, 0x6d, 0xb5, 0x5a, 0x6d, 0xdd, 0xfd, 0x66, 0xb7, X 0xdb, 0x5f, 0x0a, 0x85, 0x42, 0xb1, 0x8a, 0xc5, 0x42, 0xb3, 0xdd, 0xaf, X 0x6d, 0xbd, 0x5a, 0x6d, 0xdd, 0xfd, 0x66, 0xb9, 0xd4, 0x5f, 0x0a, 0xbd, X 0x5a, 0xb1, 0xfa, 0xfd, 0x5a, 0xbd, 0xd6, 0xaf, 0xfd, 0xfd, 0x7e, 0x7f, X 0xfd, 0xfd, 0x7e, 0xbf, 0xdf, 0x5f, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, X 0xaa, 0x55, 0x55, 0xa5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xaa, X 0xaa, 0x5a, 0xfa, 0xfd, 0x7e, 0xbf, 0xfa, 0xfd, 0x7e, 0xbf, 0xdf, 0xaf, X 0x6d, 0x85, 0x7a, 0x61, 0xdd, 0xc5, 0x7e, 0xbf, 0xdf, 0x5a, 0x6a, 0xf5, X 0x7a, 0xaf, 0xda, 0xd5, 0x6a, 0xab, 0x59, 0x8d, 0x6d, 0xf5, 0x7a, 0x6f, X 0xdd, 0xe5, 0x56, 0xb5, 0xd6, 0x5f, 0x0a, 0xc5, 0x42, 0xaf, 0xda, 0x95, X 0x56, 0xb5, 0xdf, 0x8f, 0x7d, 0xbd, 0x5a, 0x6f, 0xdd, 0xd5, 0x6a, 0xab, X 0xdf, 0x5f, 0x7a, 0xc5, 0x42, 0xaf, 0xda, 0x85, 0x7e, 0xbf, 0xdf, 0x9f, X 0xfd, 0xfd, 0x7e, 0x7f, 0xfd, 0xfd, 0x7e, 0xbf, 0xdf, 0x4f, 0xaa, 0xaa, X 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0xb5, 0x55, 0x55, 0x55, 0x55, X 0x55, 0x55, 0x55, 0xaa, 0xaa, 0x5a, 0xfa, 0xfd, 0x7e, 0xbf, 0xfa, 0xfd, X 0xdf, 0xff, 0xfd, 0xbf, 0x0d, 0xdd, 0x66, 0x61, 0xfd, 0x8d, 0xd8, 0xc8, X 0x8d, 0x58, 0x6a, 0xcd, 0x5a, 0xaf, 0x0a, 0xed, 0xde, 0xae, 0xed, 0xba, X 0x6d, 0xdd, 0x5e, 0x6f, 0xfd, 0xed, 0xde, 0xae, 0xed, 0x5a, 0x6a, 0xdd, X 0x6e, 0xa3, 0xfa, 0xed, 0xd8, 0xae, 0xed, 0xb8, 0x6d, 0xdd, 0x76, 0x6f, X 0x0d, 0xed, 0xde, 0xae, 0xed, 0x5a, 0x0a, 0x8d, 0x42, 0xa1, 0xfa, 0x8d, X 0xd8, 0xc8, 0x8d, 0xba, 0xfd, 0xfd, 0x7e, 0x7f, 0xfd, 0xfd, 0xdf, 0xff, X 0xfd, 0x5f, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, X 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55}; SHAR_EOF chmod 0644 calc.icon || echo 'restore of calc.icon failed' Wc_c="`wc -c < 'calc.icon'`" test 3512 -eq "$Wc_c" || echo 'calc.icon: original size 3512, current size' "$Wc_c" fi # ============= tree.h ============== if test -f 'tree.h' -a X"$1" != X"-c"; then echo 'x - skipping tree.h (File already exists)' else echo 'x - extracting tree.h (Text)' sed 's/^X//' << 'SHAR_EOF' > 'tree.h' && // tree.h : include file for tree.c // used to build tree-grafix (class-browser, dir-tree) X #include "window.h" X template class list { public: X T *car; list *cdr; X list(T *car) : car(car) { cdr = NULL; } X list *push(T *vx) { // push item T in front of list, return new X list *gx = new list(vx); gx->cdr = this; X return gx; X } X void append(list *hx) { // append to the end of list, slow !! X list *h = this; while(h->cdr) h= h->cdr; X h->cdr = hx; X } X int length() { X int n = 0; X list *h = this; while(h) { h= h->cdr; n++; } X return n; X } X list *nth(int n) { // return the n-th element, slow !! X int i; list *h = this; X for (i=0; icdr; X return h; X } X T *last() { // return last car X list *h = this; while (h->cdr) h = h->cdr; X return h->car; X } X list *remove(T *xcar) { X list *cl = this; X if (this->car == xcar) { cl = this->cdr; delete this; return cl; } X X while (cl) { X list *pred = cl; cl = pred->cdr; X if (cl->car == xcar) { pred->cdr = cl->cdr; delete cl; break; } X } X return this; X } X void print() { // call print methods of all elements : -> incomplete type X list *h = this; while(h) { /* h->car->print(); */ h= h->cdr; } X } }; X struct GC3 { GC forgr, bright, dark; }; // 3 GCs for buttons X extern void color_GC(unsigned short r, unsigned short g, unsigned short b, X GC3 *gc3); X // a button with special colors class color_button : public window { X GC forgr,bright,dark; X char *Name; public: X color_button(window & parent, char *Name, int w, int h, int x, int y); X virtual void redraw(); X void set_GC(struct GC3 *gc3); X X virtual void BRelease_CB(XButtonEvent) { rise(); } X virtual void BPress_CB(XButtonEvent) { drop(); } protected: X void rise(); X void drop(); }; X class Node; X class Node_button : public color_button { X window *infw; // to inform for Enter X Node *ci; public: X Node_button(window &parent, window *infw, Node *ci); X virtual void Enter_CB(XCrossingEvent); X virtual void BPress_1_CB(XButtonEvent ev); }; X class Node { public: X int depth; // balanced depth in graph X int xp,yp,w,h; // drawing position and size X char *name; X Node_button *nb; X int descendants; // total # of all desc X Node(char *name); X virtual void Enter_cb(window *infw) {} X virtual void Press_cb(XButtonEvent *ev) {} // activated from button press }; X class Tree; typedef list Tlist; X class Tree : public Node { public: X Tlist *children; // a linked list of Tree-pointers X int nch; // number of children X Tree(char *name); X void rec_depth(int d); // recursively set depth X void rec_breadth(int depthp, int maxdepth, int counter[]); X int rec_descendants(); X int rec_geometry(int ytop[], Tlist* tcol[], int ypar, int dbmax); X int rec_insert(Tlist *tcol[], int &vheight, int &vwidth); }; X // class for displaying the tree-graph in a scrolled_window class Tree_window : public virtual_window { X Tlist *cll; // linear list of all nodes (AllNodes) public: X Tree_window(scrolled_window *scr, window *infw, Tlist *cll); X virtual void redraw(); }; X // Tree_main contains all subwindows for displaying the Tree class Tree_main : public main_window { protected: X scrolled_window *scr; X Tree_window *grw; X menu_bar *mb; X window *infow; // to show infos about class on button EnterCB X int vwidth, vheight,yroot; // virtual size and y of root X int hinf,hmb; // height of info window, menubar X Tlist *tll; // linear list of all nodes X Tlist *tcol[100];// vector of linear lists for each depth column (depth < 100) X // for easy geometry parsing, generated in rec_geometry public: X Tree_main(char * WMName, int w, int h, Tlist *tll); X virtual void init(); X virtual void resize(int w, int h); X virtual void make_graph(); X void make_tree(Tree *top); }; SHAR_EOF chmod 0644 tree.h || echo 'restore of tree.h failed' Wc_c="`wc -c < 'tree.h'`" test 3843 -eq "$Wc_c" || echo 'tree.h: original size 3843, current size' "$Wc_c" fi # ============= tree.c ============== if test -f 'tree.c' -a X"$1" != X"-c"; then echo 'x - skipping tree.c (File already exists)' else echo 'x - extracting tree.c (Text)' sed 's/^X//' << 'SHAR_EOF' > 'tree.c' && // tree.c : // wolf 10/95 // classes and functions used to build tree-grafix (class-browser, dir-tree) X #include "tree.h" #include "tree_icon.h" X static void rect3d(Window Win, short x, short y, short w, short h, X GC left_top, GC right_bot) { X int i, thickness = 2; X for (i = 0; i < thickness; i++) { X short xa = x+i, ya = y+i, xe = x+w-i, ye = y+h-i ; X XPoint xp[5] = { {xa,ye}, {xa,ya}, {xe,ya}, {xe,ye}, {xa,ye}}; // short x,y X XDrawLines(display,Win, left_top, xp, 3, CoordModeOrigin); X XDrawLines(display,Win, right_bot, xp+2, 3, CoordModeOrigin); X } } X // calculation of GCs for button colors, outside class definition, // since many buttons can use the same GC // give the brightest colors, the other 2 are set proportional void color_GC(unsigned short r, unsigned short g, unsigned short b, GC3 *gc3) { X int fg_pix = alloc_color(3*r/4,3*g/4,3*b/4); // inner part X int br_pix = alloc_color(r,g,b); // bright rim X int lw_pix = alloc_color(r/2,g/2,b/2); // dark rim X XGCValues values; X X values.foreground = fg_pix; X gc3->forgr = CreateGC(GCForeground, &values); X values.foreground = br_pix; X gc3->bright = CreateGC(GCForeground, &values); X values.foreground = lw_pix; X gc3->dark = CreateGC(GCForeground, &values); } X // a button with special colors X color_button::color_button(window &parent, char *Name, int w,int h,int x,int y) : window(parent, w, h, x, y, 0), Name(Name) { X selection_mask |= EnterWindowMask | LeaveWindowMask | X ButtonPressMask | ButtonReleaseMask; X // by default use button colors X forgr = button_fg_gc; bright = button_br_gc; dark = button_lw_gc; } X void color_button::redraw() { X XFillRectangle(display,Win,forgr,0,0,width,height); X PlaceText(Name); X rise(); } X void color_button::set_GC(struct GC3 *gc3) { X forgr = gc3->forgr; bright = gc3->bright; dark = gc3->dark; } X void color_button::rise() { rect3d(Win,0,0,width-1,height-1, bright, dark); } void color_button::drop() { rect3d(Win,0,0,width-1,height-1, dark, bright); } X static int bwmax = 100; // max button width static int bhgt = 20; // button height static int yoff = bhgt + 2; // vertical offset (between buttons) X // class Node Node::Node(char *name) : name(name) { X depth = 0; descendants = 0; X xp = yp = -1; X w = bwmax name,ci->w,ci->h,ci->xp,ci->yp), infw(infw), ci(ci) {} void Node_button::Enter_CB(XCrossingEvent) { ci->Enter_cb(infw); } void Node_button::BPress_1_CB(XButtonEvent ev) { ci->Press_cb(&ev); } X // compare function for qsort : use total number of descendants static int qcomp(const Tree **e1, const Tree **e2); typedef int (*IVPVP)(const void *,const void *); // the correct type for qsort X // class Tree : public Node X Tree::Tree(char *name) : Node(name) { X children = 0; nch = 0; } X void Tree::rec_depth(int d) { // recursively set depth X depth = d; X for (Tlist *ch = children; ch; ch = ch->cdr) ch->car->rec_depth(d+1); } X // recursively tree-parsing downwards, compute cumulative treebreadth // at each depth on vector counter, depth is computed independently // so it works from any level, depth = 0 -> always 1 (myself) void Tree::rec_breadth(int depthp, int maxdepth, int counter[]) { X if (depthp == maxdepth) return; X counter[depthp++]++; X if (depthp == maxdepth) return; // no need to parse further X for (Tlist *ch = children; ch; ch = ch->cdr) X ch->car->rec_breadth(depthp, maxdepth, counter); } X // count all descendants (all depths), include myself, but only once !! int Tree::rec_descendants() { X if (descendants == 0) { // else :already computed X nch = children->length(); X for (Tlist *ch = children; ch; ch = ch->cdr) X descendants += ch->car->rec_descendants(); X descendants++; // include myself X } X return (descendants); } X // recursively parse geometry, ytop is the current ymax for all depths // ypar the parent height (if known), dbmax the depth with max breadth // returns the own yp for parent node int Tree::rec_geometry(int ytop[], Tlist* tcol[], int ypar, int dbmax) { X tcol[depth] = tcol[depth]->push(this); X // tcol-lists for later dynamically inserting; sorted from bottom -> top X int yc; X if (nch > 0) { X int ic; Tlist *cl = children; X Tree *ctemp[nch]; // for sorting children we must use a temp vector X for (ic = 0; cl; cl = cl->cdr, ic++) ctemp[ic] = cl->car; X qsort(ctemp, nch, sizeof(void*), (IVPVP) qcomp); // sort with qcomp X int y = ypar >? ytop[depth]; yc = 0; X for (ic = 0; ic < nch; ic++) { X int cyprop = y + (ic - (nch-1)/2)*yoff; // proposed child y X yc += ctemp[ic]->rec_geometry(ytop, tcol, cyprop, dbmax); X } X yc /= nch; // mean of all children X } X // for depths lower dbmax use child mean, else parent value X if (depth < dbmax) yp = yc; else yp = ypar; X yp = yp >? ytop[depth]; // make sure no overlapping takes place X xp = 5 + (bwmax+5)*depth; X ytop[depth] = yp + yoff; X return yp; } X // dynamically inserting subtrees into existing graph (recursively) // by use the column-list of depth, arranged from bottom upwards int Tree::rec_insert(Tlist *tcol[], int &vheight, int &vwidth) { X if (yp > 0) return yp; // already inserted !! X // printf("%s %d %d\n",name,depth,vheight); X int yc = 0; // used if no children X if (nch > 0) { // first insert children and compute their mean y X for (Tlist *ch = children; ch; ch = ch->cdr) X yc += ch->car->rec_insert(tcol, vheight,vwidth); X yc /= nch; X } X int ylast = vheight+2*yoff, // to have at least space for one button on bottom X dmin = ylast, yopt; X Tlist *cp1,*cp2, *clast = NULL; X // the loop goes one step behind list end to catch the lower bound = 0 X for (Tlist *cact = tcol[depth]; ; cact = cact->cdr) { X int yact = (cact) ? cact->car->yp : 0; X if (yc - yact > yoff && ylast - yc > yoff) { // we have optimal place X cp1 = cact; cp2 = clast; X dmin = 0; yopt = yc; X break; // no need to search further X } X if (ylast - yact > 2*yoff) { // there is space for another button X int yx = yact+yoff, diff = abs(yc-yx); X if (diff < dmin) { // find the space with minimal distance to children yc X dmin = diff; yopt = yx; X cp1 = cact; cp2 = clast; X } X } X if (cact == 0) break; // loop ends X clast = cact; ylast = yact; X } X // insert new value into tcol-list between cp2 -> cnew -> cp1 X Tlist *cnew = cp1->push(this); X if (cp2) cp2->cdr = cnew; else tcol[depth] = cnew; X X yp = yopt; xp = 5 + (bwmax+5)*depth; X vheight = vheight >? yp+yoff; X vwidth = vwidth >? xp+bwmax; X return yp; } X // compare function for qsort : sorting of child nodes static int qcomp(const Tree **e1, const Tree **e2) { X return ((*e2)->descendants - (*e1)->descendants); X // return (strcmp((*e1)->name,(*e2)->name)); } X // class for displaying the tree-graph in a scrolled_window // class Tree_window : public virtual_window Tree_window::Tree_window(scrolled_window *scr, window *infw, Tlist *cll) : X virtual_window(scr), cll(cll) { X for (Tlist *cl = cll; cl; cl = cl->cdr) { X Node *ci = cl->car; X if (ci->w > 0) // callbacks for ci are activated on BPress, Enter X ci->nb = new Node_button(*this,infw,ci); X } } X void Tree_window::redraw() { X // draw lines between all buttons and their children (not recursive !) X for (Tlist *cl = cll; cl; cl = cl->cdr) { X Tree *ci = cl->car; X int x = ci->xp + ci->w, y = ci->yp+10; // point behind the button X for (Tlist *ch = ci->children; ch; ch = ch->cdr) { // child-list X line(x,y,ch->car->xp,ch->car->yp+10); X } X } } X // Tree_main contains all subwindows for displaying the Tree // class Tree_main : public main_window X Tree_main::Tree_main(char * WMName, int w, int h, Tlist *tll) : X main_window(WMName,w,h), tll(tll) { X hinf = 20; hmb = 20; X set_icon(tree_icon_bits, tree_icon_width, tree_icon_height); X mb = new menu_bar(*this,w,hmb,0,0,0); X new quit_button(*mb); X infow = new window(*this,w,hinf,0,h-hinf); X } X void Tree_main::init() { // to be called after constructor !! (uses virtual fns) X make_graph(); // compute graph-nodes (xp,yp) and virtual size X scr = new scrolled_window(*this,width,height-hmb-hinf,vwidth,vheight,0,hmb); X grw = new Tree_window(scr, infow, tll); // the virtual window X // hardcopy only the clipped region of scrolled window (more not visible :-) X new xwd_button(*mb,"hardcopy"," | xpr | lpr",scr->clip); X width += 1; // hack to force resize on configure } X void Tree_main::resize(int w, int h) { X // printf("resize %d %d %d %d\n",w,h,width,height); X if (width == w && height == h) return; X width = w; height = h; X mb->resize(width, hmb); X scr->resize(width, height - hmb - hinf); X infow->resize(width, hinf); X XMoveWindow(display,infow->Win, 0, height - hinf); X X twodim_input *vs = scr->vs; // centre vertical slider X if (vs) vs->set_slider(0,vs->yspan*yroot/vheight); } X // build geometrical graph for display // vwidth and vheight return size of needed virtual window // simple default : use *last* element of tll as top ??? void Tree_main::make_graph() { X Tree *top = tll->last(); X top->rec_depth(0); int nd = top->rec_descendants(); X printf("%s %d %d\n",top->name,nd,tll->length()); X //for (Tlist *ch=top->children;ch;ch=ch->cdr) printf("%s\n",ch->car->name); X make_tree(top); } X void Tree_main::make_tree(Tree *top) { X // compute depth with max breadth X int d, dbmax = 0, bmax = 0, dtot, bcount[100]; // max depth = 100 X for (d = 0; d < 100; d++) bcount[d] = 0; X top->rec_breadth(0,100,bcount); X for (d = 0; d < 100; d++) { X if (bcount[d] > bmax) { bmax = bcount[d]; dbmax = d; } X if (bcount[d] == 0) break; X } X dtot = d; // total depth X // printf("top = %s dbmax %d bmax %d depth %d\n", X // top->name, dbmax, bmax, dtot); X int ytop[dtot]; X for (d = 0; d < dtot; d++) { X ytop[d] = 2; // leave space 2 pixel X tcol[d] = NULL; // init the column list X } X yroot = top->rec_geometry(ytop,tcol,0,dbmax); X vwidth = bwmax*d + 10; vheight = 0; X for (d = 0; d < dtot; d++) vheight = vheight >? ytop[d]; X vheight += 2; X printf("%d %d\n",vwidth,vheight); X // for (Tlist *tl= tcol[2]; tl; tl= tl->cdr) printf("%s\n",tl->car->name); } X SHAR_EOF chmod 0644 tree.c || echo 'restore of tree.c failed' Wc_c="`wc -c < 'tree.c'`" test 10325 -eq "$Wc_c" || echo 'tree.c: original size 10325, current size' "$Wc_c" fi # ============= tree_icon.h ============== if test -f 'tree_icon.h' -a X"$1" != X"-c"; then echo 'x - skipping tree_icon.h (File already exists)' else echo 'x - extracting tree_icon.h (Text)' sed 's/^X//' << 'SHAR_EOF' > 'tree_icon.h' && #define tree_icon_width 32 #define tree_icon_height 32 static char tree_icon_bits[] = { X 0x00, 0x00, 0xc0, 0xff, 0x38, 0x00, 0xa0, 0x00, 0x44, 0x00, 0x10, 0x01, X 0x44, 0x00, 0x08, 0x02, 0x44, 0x00, 0x04, 0x04, 0x78, 0x00, 0x02, 0x08, X 0x40, 0x00, 0x01, 0x10, 0x40, 0x80, 0x00, 0x20, 0x48, 0x40, 0x00, 0x40, X 0x30, 0x20, 0x00, 0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x26, 0x00, 0x00, X 0x80, 0x41, 0x00, 0x20, 0x60, 0x80, 0x00, 0x10, 0x18, 0x00, 0x01, 0x08, X 0x06, 0x00, 0x02, 0x04, 0x01, 0x00, 0x04, 0x02, 0x02, 0x00, 0x08, 0x01, X 0x04, 0x00, 0x90, 0x00, 0x08, 0x00, 0x60, 0x00, 0x08, 0x00, 0xc0, 0x7f, X 0x10, 0x00, 0x80, 0x00, 0x20, 0x00, 0x00, 0x01, 0x40, 0x00, 0x20, 0x02, X 0x80, 0x00, 0x10, 0x04, 0x00, 0x01, 0x08, 0x08, 0x00, 0x02, 0x04, 0x10, X 0x00, 0x04, 0x02, 0x20, 0x00, 0x04, 0x01, 0x00, 0x00, 0x88, 0x00, 0x00, X 0x00, 0x50, 0x00, 0x00, 0x00, 0xe0, 0xff, 0x00}; SHAR_EOF chmod 0644 tree_icon.h || echo 'restore of tree_icon.h failed' Wc_c="`wc -c < 'tree_icon.h'`" test 890 -eq "$Wc_c" || echo 'tree_icon.h: original size 890, current size' "$Wc_c" fi # ============= gccinc/features.h ============== if test ! -d 'gccinc'; then echo 'x - creating directory gccinc' mkdir 'gccinc' fi if test -f 'gccinc/features.h' -a X"$1" != X"-c"; then echo 'x - skipping gccinc/features.h (File already exists)' else echo 'x - extracting gccinc/features.h (Text)' sed 's/^X//' << 'SHAR_EOF' > 'gccinc/features.h' && /* Copyright (C) 1991, 1992 Free Software Foundation, Inc. This file is part of the GNU C Library. X The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. X The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. X You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ X #ifndef _FEATURES_H X #define _FEATURES_H 1 X /* These are defined by the user (or the compiler) X to specify the desired environment: X X __STRICT_ANSI__ ANSI Standard C. X _POSIX_SOURCE IEEE Std 1003.1. X _POSIX_C_SOURCE If ==1, like _POSIX_SOURCE; if ==2 add IEEE Std 1003.2. X _BSD_SOURCE ANSI, POSIX, and 4.3BSD things. X _SVID_SOURCE ANSI, POSIX, and SVID things. X _GNU_SOURCE All of the above, plus GNU extensions. X X The `-ansi' switch to the GNU C compiler defines __STRICT_ANSI__. X If none of these are defined, the default is _GNU_SOURCE. X If more than one of these are defined, they accumulate. X For example __STRICT_ANSI__, _POSIX_SOURCE and _POSIX_C_SOURCE X together give you ANSI C, 1003.1, and 1003.2, but nothing else. X X These are defined by this file and are used by the X header files to decide what to declare or define: X X __USE_POSIX Define IEEE Std 1003.1 things. X __USE_POSIX2 Define IEEE Std 1003.2 things. X __USE_BSD Define 4.3BSD things. X __USE_SVID Define SVID things. X __USE_MISC Define things common to BSD and System V Unix. X __USE_GNU Define GNU extensions. X __FAVOR_BSD Favor 4.3BSD things in cases of conflict. X X The macro `__GNU_LIBRARY__' is defined by this file unconditionally. X X All macros defined by this file are defined as 1. X All macros listed above as possibly being defined by this file are X explicitly undefined if they are not explicitly defined. X Feature-test macros that are not defined by the user or compiler X but are implied by the other feature-test macros defined (or by the X lack of any definitions) are defined by the file. */ X X /* Undefine everything, so we get a clean slate. */ #undef __USE_POSIX #undef __USE_POSIX2 #undef __USE_BSD #undef __USE_SVID #undef __USE_MISC #undef __USE_GNU #undef __FAVOR_BSD X X /* If nothing is defined, define _GNU_SOURCE. */ #if (!defined(_GNU_SOURCE) && !defined(__STRICT_ANSI__) && \ X !defined(_POSIX_SOURCE) && !defined(_POSIX_C_SOURCE) && \ X !defined(_BSD_SOURCE) && !defined(_SVID_SOURCE)) #define _GNU_SOURCE 1 #endif X X /* Always use ANSI things. */ #define __USE_ANSI 1 X X /* If _BSD_SOURCE was defined by the user, favor BSD over POSIX. */ #ifdef _BSD_SOURCE #define __FAVOR_BSD 1 #endif X X /* If nothing (other than _GNU_SOURCE) is defined, X define _BSD_SOURCE and _SVID_SOURCE. */ #if (!defined(__STRICT_ANSI__) && !defined(_POSIX_SOURCE) && \ X !defined(_POSIX_C_SOURCE) && !defined(_BSD_SOURCE) && \ X !defined(_SVID_SOURCE)) #define _BSD_SOURCE 1 #define _SVID_SOURCE 1 #endif X /* If none of the ANSI/POSIX macros are defined, use POSIX.1 and POSIX.2. */ #if (!defined(__STRICT_ANSI__) && !defined(_POSIX_SOURCE) && \ X !defined(_POSIX_C_SOURCE)) #define _POSIX_SOURCE 1 #define _POSIX_C_SOURCE 2 #endif X #if defined(_POSIX_SOURCE) || _POSIX_C_SOURCE >= 1 #define __USE_POSIX 1 #endif X #if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 2 #define __USE_POSIX2 1 #endif X #if defined(_BSD_SOURCE) || defined(_SVID_SOURCE) #define __USE_MISC 1 #endif X #ifdef _BSD_SOURCE #define __USE_BSD 1 #endif X #ifdef _SVID_SOURCE #define __USE_SVID 1 #endif X #ifdef _GNU_SOURCE #define __USE_GNU 1 #endif X X #undef __GNU_LIBRARY__ #define __GNU_LIBRARY__ 1 X X /* This is here only because every header file already includes this one. */ #include X #endif /* __features.h */ SHAR_EOF chmod 0644 gccinc/features.h || echo 'restore of gccinc/features.h failed' Wc_c="`wc -c < 'gccinc/features.h'`" test 4186 -eq "$Wc_c" || echo 'gccinc/features.h: original size 4186, current size' "$Wc_c" fi # ============= gccinc/regex.h ============== if test -f 'gccinc/regex.h' -a X"$1" != X"-c"; then echo 'x - skipping gccinc/regex.h (File already exists)' else echo 'x - extracting gccinc/regex.h (Text)' sed 's/^X//' << 'SHAR_EOF' > 'gccinc/regex.h' && #include "rx.h" SHAR_EOF chmod 0644 gccinc/regex.h || echo 'restore of gccinc/regex.h failed' Wc_c="`wc -c < 'gccinc/regex.h'`" test 16 -eq "$Wc_c" || echo 'gccinc/regex.h: original size 16, current size' "$Wc_c" fi true || echo 'restore of gccinc/rx.h failed' echo End of part 3, continue with part 4 exit 0