WHAM Windows by Allegro & Martijn version 2 beta

(if somebody can think of a better acronym which includes the H please tell me)


If you feel like correcting my typos, thats FINE. email the corrected file to me (address at the bottom). if you think parts of this document are unclear, please tell me (preferably tell me a way to write those parts clearer as well) for I know I'm not a good writer.

To use WHAM I think it is necessary to read the whole document at least once. I know that's boring, but I make some silly jokes along the way (marked with ';)', so you won't forget to laugh) to make the task lighter. But if you really don't want to read all, the following sections are neccesary to understand the rest:

WinSystem Wobject Window Wham_Secretary helper functions the pitfalls section ( so if you're sure you won't use BillWin, you don't really need to read that section)

some notes on these docs: because INFO doesn't understand '::' as part of a node-name, I used _CM_ (ClassMember) in this document as a replacement for '::'. so Wobject::move becomes Wobject_CM_move. In the text version (and perhaps the html version as well ?) you can change all _CM_'s back to :: to make it more readable. (dos edit: ALT-S,c,_CM_,TAB,::,TAB,TAB,TAB,TAB,ENTER done :)

also, sometimes there is a loose '_' at the start of a line this '_' is just to help makedoc, please ignore them :)

Another problem is that I sometimes group several variables/functions in one section with the name of the first as section name. When I do this the indentation screws up in the .inf file. Sorry for that, I'll try to fix it next time. (It has cost me most of my day-off to even get the info file working, and to reformat these docs, and right now I'm kinde tired of it:)




Legal Obligations.

I'm not responsible for any damage/misfortune this code may do/bring to you. Use it at your own risk.

(not that I'm doing any weird things, just to be on the safe side)

Copyright Info

WHAM is ,like Allegro, swapware. that means that if you like it, send me something in return, 'something' can be: a program you made, a postcard, some money(always useful...:), a photograph of you, your family and all your 101 dalmatians, an unknown Only Ones or Syd Barrett CD ;),... Anyway,.. ye know what I mean.

It would be nice if you mentioned me in the credits of your program, but you don't have to if you don't want to.

Please tell other people how to obtain WHAM(or spread it around).


Contents


Introduction

Q. Why write another windowing system for DJGPP, when there's SWORD & TWS? A. -I Needed a windowing system that could work together with Allegro -I Needed a simple System for I didn't want to rewrite all my old code to fit-in the interface. Q. In What does this system differ from other systems like SWORD and TWS? A. -It does no things like event handling and all that stuff, it just provides display space in windows. -It leaves you completely free to design your own window styles for it doesn't draw any borders by default, although there is an example class which does provide ready-to-use windows (including borders&drag-bars etc) and some mouse handling

Short Overview

What does Wham provide at the moment The Base system provides -Windowed display space for your program, in the form of overlapped windows(with or without shadow), each of which contains a drawable bitmap. windows can be: -resized -rescaled -moved -a viewport on the window can be set(so that the actual window is larger than the displayed part) -displayed -hidden -activated -locked at a bottom or top position ( like a root window, or a window for a clock which should always be visible) -locked in size/position -A coordinate helper function which translates screen coordinates into coordinates relative to a window and returns the window in which the coordinates lie.(useful to translate mouse coordinates to window coordinates) -Windows can be child windows of another window, that means they use the parent window as display.

The example class WhamWin provides -ready to use windows that include -a title bar -rescaling by dragging the right or bottom border with the mouse -maximize/minimize/original size buttons The example class BorderWin provides -ready to use windows that include: -a border/titlebar -rescaling/ moving by dragging the borders with the mouse -a function to add systemboxes to the window, which will invoke a callback function when clicked

The class FrameWin provides -the same functionality as borderwin, but with a simpler border

-the example class GuiContainer provides -ready to use windows that incorporate an Allegro-style dialog

-the class BillWin provides -windows that look a lot like the windows of a certain DOS shell type of 'OS' (hope they don't sue me for Look&Feel) - functionality like borderwin except for the systemboxes - they can be minimised to an icon - the icon can be re-stored by right-clicking it with the mouse

-the class OClock contains: - a round clock

- the class Sunglass contains - an example of a translucent object

- the class Pager contains a pager window

- the class Panel contains a non-rescalable panel for information messages/logos etc

Standard Procedure for writing Wham programs

-initialize Allegro (install timer/keyboard/mouse/gfxmode)
-initialize Wham by setting all the static members and then create a new manager with :

WHAM = new WinSystem;

(see examples\quick.cc for an example of what I mean).
-create your application's main windows.
-in your main program loop call

Wham_Secretary.process_mouse();

to give the system the opportunity to respond to the mouse/keyboard. (if you don't have a main loop, make sure you call Wham_Secretary.process_mouse() regularly. - when you're finished use

delete WHAM;

the destructor of WinSystem will delete all windows and remove the manager.


WinSystem class

WinSystem is the Window manager, it contains all the stuff that has to do with all windows. There exists a global WinSystem *WHAM, this needs to point to an instance of WinSystem. You can do this in two ways: -before you use any windows use the statement: WHAM = new WinSystem; -just don't set WHAM. In this case WHAM will be set by the first window that is opened and deleted when the last window is closed. If your program doesn't exit after the last window closes, but ,for example, again opens new windows, then I think the first way is the safest, for the User-functions from the WinSystem class will not be available when WHAM isn't set.WHAM will be NULL when not initialized, so you can test this.

Before you create any instance of WinSystem you can set the following statics to influence the way WinSystem will work:

static int WinSystem_CM_UseSpecialSegvHandler;
when this is set to TRUE whamwin installs a different signal handler for segmentation faults, this handler does not try to remove wham from memory on SIGSEGV, but it just exits. as long as you use CWSDPMI this is no problem, but if you use PMODE (or another extender which doesn't automatically free alloc'd memory on exit) this can cause garbage to be left in the memory. the advantage of this flag is that it prevents the system from hanging on crash, for with segmentation faults there always is a chance that something vital was corrupted and WHAM cannot be unloaded anymore. default FALSE (only set this to true if you program hangs, it might help giving you a decent stack trace)

static int WinSystem_CM_UseBoxes
when this is set to TRUE the manager will use the boxlist-algorithm for displaying the windows, this is MUCH faster and looks better in unbuffered mode. BUT: -it uses more memory (not much). -most speed advantages disappear when shadow or non square objects are used ( though it is still a bit faster) - when you have a *lot* of *small* windows, the administration overhead cancels out the speed advantage.

it is best to set this to true when you have large windows just try both and see which is fastest for your program

default FALSE.

furthermore there are a few static variables you can set before the creation of EACH WinSystem object:

static int WinSystem_CM_InitialBufferSize;
this is the initial size that WinSystem will allocate for it's administration tables(default = 100, meaning 100 windows, which should be enough for most programs :) you might even want to set this lower)

static int WinSystem_CM_Buffer_Increment;
when the initial buffersize is exceeded, the buffer will be enlarged in steps of this size(to prevent too much memory fragmentation) (This variable really doesn't belong in this section, for it can be changed anytime, and will take effect for all WinSystem objects, but it is described here because InitialBufferSize is) (default 100)

static int WinSystem_CM_Buffered;
when this TRUE WinSystem will create a scratch buffer the size of the screen and do all it's output there, blitting only the final result to 'the_screen', looks much better, but consumes memory. (default FALSE) When TheScreen != screen this will always be taken as FALSE no matter what you specify. It is slower if UseBoxes is TRUE, but faster if UseBoxes is FALSE.

static int WinSystem_CM_ShadowStyle
possible values are: WHAM_NO_SHADOW - windows have no shadow WHAM_SIMPLE_SHADOW - windows have a solid shadow defined by WinSystem_CM_Shadow_Color WHAM_FAST_SHADOW - windows have a shadow made by XOR-ing the underlying image with color WinSystem_CM_Shadow_Color WHAM_SLOW_SHADOW - windows have a shadow by darkening the background image how much the background image is darkened depends on WinSystem_CM_Shadow_Color 0 means black 255 means no darkening. This shadow mode means the global variable color_map(from ALLEGRO) must point to a lightning map for the current palette. If color_map = NULL WinSys will set up an appropriate color map for the current palette. WHAM_PATTERN_SHADOW - windows have a shadow made by using a checkered pattern mask to draw a shadow of color WinSystem_CM_Shadow_Color

default is WHAM_NO_SHADOW. WHAM_FAST_SHADOW and WHAM_SLOW_SHADOW make it necessary to do a lot more redrawing so they slow down the system a lot. WHAM_PATTERN_SHADOW and WHAM_SIMPLE_SHADOW also slow down the system, but only if the boxlist algorithm (Use_Boxes = TRUE) is used. ( the boxlist algorithm is still faster mostly).

static int WinSystem_CM_ShadowColor
see above. default 128.

static int WinSystem_CM_ShadowSize
the size of the shadow , this should not be larger than the minimum size of your windows, for that will give strange looking results. default 4


static BITMAP *WinSystem_CM_TheScreen;
the bitmap WinSystem uses for it's screen output defaults to 'screen', but you can let it point to any allegro bitmap.

static int WinSystem_CM_BackgroundColor
the background color. default 1.

also there are some static variables you can change anytime and which will take effect immediately.

static int WinSystem_CM_Vsynced;
this cause wham to do a vsync() before blitting anything to the screen slower, but looks better.(currently only works for buffered mode) default FALSE. Ignored when this winsystem does not use 'screen' for output (i.e. TheScreen != screen)

static int WinSystem_CM_Full_Remove;
when set to false, the desktop is not updated, which can give slight speed improvement for programs that use a root window which completely covers the desktop. default TRUE;



static int WinSystem_CM_Minimum_Size_x
static int WinSystem_CM_Minimum_Size_y
the minimum dimensions of a window, a window can never be rescaled/resizedsmaller than this unless they were created smaller. default for both is 32

static int WinSystem_CM_Message_System_Active;
when this is FALSE the message system is disabled. default TRUE;

static int WinSystem_CM_Show_Effect;
this can be one of: W_EFFECT_NO_EFFECT W_EFFECT_HLINES W_EFFECT_VLINES W_EFFECT_DOTS W_EFFECT_PRERECT W_EFFECT_BUNCH

these cause different effects on showinf/hiding windows (only work in Buffered mode) static int WinSystem_CM_Show_Effect_Param;
parameter for the effect, generally if this is 2 the effect will be twice as slow as when this is 1. default 1.

static WinSystem_CM_Mouse_Cursor *Mouse_Cursor0;
static WinSystem_CM_Mouse_Cursor *Mouse_Cursor1; static WinSystem_CM_Mouse_Cursor *Mouse_Cursor2; static WinSystem_CM_Mouse_Cursor *Mouse_Cursor3; static WinSystem_CM_Mouse_Cursor *Mouse_Cursor4; static WinSystem_CM_Mouse_Cursor *Mouse_Cursor5; static WinSystem_CM_Mouse_Cursor *Mouse_Cursor6; static WinSystem_CM_Mouse_Cursor *Mouse_Cursor7; static WinSystem_CM_Mouse_Cursor *Mouse_Cursor8; static WinSystem_CM_Mouse_Cursor *Mouse_Cursor9; these are a set of mouse cursors you can select with the set_mouse_cursor(Mouse_Cursor *m); function from helpers.cc by default they are all NULL, resulting in the standard arrow, but you can set them to something else with

WinSystem_CM_mouse_cursor? = new Mouse_Cursor(BITMAP *picture, int hotspotx,int hotspoty);

All the predefined window classes set the mouse to mouse_cursor1 for moving the object, and to mouse_cursor2 for rescaling the object( you won't notice this as long as they're both NULL), so my suggestion is that your objects do the same. (if you use the wclass utility the generated mouse handler will do this). By using this set of mouse_cursors all classes can reach, you can get uniform behavior of the mouse cursor, and you can easily change the mouse cursors adapted to your taste.

WinSystem has some userfunctions(these should only be used when WHAM is initialized)

char const *WinSystem_CM_get_version();
returns the version of wham in case you want to print it somewhere.

Wobject *WinSystem_CM_get_wobject(int tag);
returns the object with tag 'tag'. returns NULL when there is no object with tag 'tag'.

int WinSystem_CM_get_number_of_wobjects();
returns the number of objects this manager handles

Wobject *WinSystem_CM_get_wobject_from_hierarchy(int place);
gets the object from place place in the drawing hierarchy usefull to find out what the top/bottom object is. It will ignore top-locked objects.

void WinSystem_CM_shift_all(x,y);
shifts all windows, except those that are shift_locked x to the right an y down shift_all(0,0) will reset all windows to their original positions

Wobject *WinSystem_CM_get_top_object();
returns the top window, ignoring top-locked windows (contrary to get_wobject_from_hierarchy(0); which can also return a top locked object)

Wobject *WinSystem_CM_process_coordinates(int x,int y, int *x_out, int *y_out, int *flag);
this can be used to process mouse coordinates. it returns the object in which the coordinates lie, and it fills the both '_out' parameters with the coordinates relative to the upper left corner of the user area of that object and rescaled to the real size of that window.

the flag parameter will be set to 1 when the border of a window is clicked, in this case the _out parameters are not rescaled, only translated relative to the upper left corner of the window it returns NULL when (x,y) does not lie within a window.

int WinSystem_CM_get_TheScreen_();
returns a pointer to TheScreen this manager uses, or to the buffer is uses m you'll have to be careful using this function because WinSystem cannot keep track of what you draw on this bitmap so it may cause strange effects, also you may not destroy this bitmap.

int WinSystem_CM_get_TheScreen_size_x();
int WinSystem_CM_get_TheScreen_size_y();
these return the dimensions of TheScreen, in case you don't know

Wobject *WinSystem_CM_get_parent()
this returns a pointer to the object used for output, or NULL if this manager displays directly onto the screen.

void WinSystem_CM_refresh_all_visible_objects();
refreshes all visible objects, you can call this if you changed something in the borders (for example) or after returning from a screensaver or something;

void WinSystem_CM_remove_wobject(int tag);
void WinSystem_CM_display_wobject(int tag,int mode);
void WinSystem_CM_remove_wobject(int tag,xfrom,yfrom,xto,yto); void WinSystem_CM_display_wobject(int tag,xfrom,yfrom,xto,yto); note: these are fairly low_level functions, they can mess up the system note2: you always need to call update_screen() after these; note3: these are mainly to be used when writing a new window class (see window.cc for an example) these functions remove/display the window from/on the screen. other than show()/hide() these don't alter the state of the Wobject so WinSystem doesn't know about it. For this reason you should only use them to remove and re-show a window inside one function. They are faster than show()/hide(), but don't check if the window is really visible, so calling this could result in a hidden window appearing on the screen. For an example of safe usage of these functions see the source of the Window class(window.cc) tag identifies the object. mode can be :DISPLAY_MODE_FULL or DISPLAY_MODE_NOBORDER one updates the full window, the other updates only the window itself.

void WinSystem_CM_update_screen(int xfrom, yfrom, xto, yto);
This function copies a part of the buffer to the screen. (in unbuffered mode it doesn't do anything). you'll only need this after using the above two functions, since all other functions call it for you.

void WinSystem_CM_switch_gfx_mode(int mode,int w, int h, int virtual w, int virtual h);
switches graphicsmode where mode is one of the allegro gfx modes ignored(does nothing) if this manager outputs to a window instead of the screen.

void WinSystem_CM_let_user_choose_gfx_mode();
displays an Allegro graphicsmode selector and lets the user choose a graphics mode. Does nothing if this manager outputs to a window instead of the screen.

BITMAP *WinSystem_CM_get_scratch_bmp(int minimum_size_x, int minimum_size_y,int color_depth = 0);
this function returns a pointer to a scratch bitmap you can use for whatever you like ( my window classes use it for conversion of 8 bit -> 15,16,24,32 bit color images) If colordepth is set the returned bitmap will have that colordepth else the returned bitmap will have the current screen colordepth, you should avoid using lots of different colordepths with this function since each time the colordepth is not the same as in the last call, a new bitmap must be created (and the old one deleted). The advantage of using this function instead of just making and destroying bitmaps, is that this one allocates the bitmap once, and reuses it (if it's large enough) so it's faster than creating new bitmaps all the time. The buffer will be deleted when WHAM is deleted. A disadvantage is that the largest size used will be kept in memory so you'd probably better not do something like WHAM->get_scratch_bmp(10000,10000); because this will result in a 10000x10000 bitmap in memory, which will only be destroyed when WHAM is deleted.

void WinSystem_CM_claim_coordinates(Wobject *w)
void WinSystem_CM_release_coordinates()
These functions claim all screen coordinates for a specific object. Afther the coordiantes are claimed process_coordinates will always calculate coordinates relative to this object ( this may return coordinates that lie outside the object). example: -there are two objects -they both are as high as the whole screen(sized 320x200) -object A takes the left half of the screen, say from 0 to 159 -object B takes the right half, form 160 to 319

the normal situation: now if you call process_coordinates(100, 100, &outx, &ouy, &flag) it will return object A and outx will be set to 100, and if you call process_coordinates(200, 100, int *outx, int *ouy, int *flag) it will return object B and outx will be 200 - 160 = 40.

now if you do WHAM->claim_coordinates(B); and then call process_coordinates(100,100,&outx,&outy,&flag) it will return B and set outx to -60.

void WinSystem_CM_claim_keyboard(Wobject *w)
void WinSystem_CM_release_keyboard()
These functions claim the keyboard for an object. All keystrokes will be passed to the process_keyboard( ) function of this_object, even if the mouse is over an other object. A more logical place for this function would be in Wham_Secretary, since WinSystem doesn't know anything about a mouse, but since claim_coordinates is here, I put this function here as well (it just sets a variable, which is checked by Wham_Secretary).


_ Furthermore

there are also some functions to send messages to windows: int WinSystem_CM_send_message(Wobject *from, int MSG, Wobject *to); int WinSystem_CM_broadcast_message(Wobject *from, int MSG); void WinSystem_CM_set_user_msg_processor(int (*user_processor) (WObject *from, in MSG));

for an explanation of these functions see the section 'messages'



Wobject class

This class is the base object for all objects the WinSystem class can handle, the class itself is of not much use since the draw_function is to be defined in the derived objects.

The functions it contains are available to all derived objects(WhamWin, Window,BorderWin,Frame,GuiContainer, your own objects)

_ Wobject_CM_Wobject(char *name,int size_x, size_y,pos_x,pos_y);
Wobject_CM_Wobject(char *name,int size_x,size_y,pos_x,pos_y, WinSystem *its_manager); Wobject_CM_Wobject(char *name,int size_x,size_y,pos_x,pos_y, int (*draw_border)(lots of arguments)); Wobject_CM_Wobject(char *name,int size_x,size_y,pos_x,pos_y, WinSystem *its_manager,int (*draw_border)(lots of arguments)); you normally never call these directly, but only from within the constructor of your derived classes (see frame.cc for an example of a derived class) WinSystem specifies the manager this window is tied to draw_border specifies a border_drawing routine (see frame.cc for an example and the Window class for an explanation).

void *Wobject_CM_user_data;
you can use this to tie some additional data to a Wobject, without writing a new window class (the constructor of Wobject sets it to NULL) (well... you *do* need to write a new class, but it can be the bare output of the wclass utility)

int Wobject_CM_magic_number;
not really used anymore use it for whatever you like

int Wobject_CM_see_through;
this needs to be set to TRUE if the object contains translucent parts (for example a non square object see ex14.cc) because the manager needs to know this. (translucent objects involve a lot more updating of the objects below them)

int Wobject_CM_show();
int Wobject_CM_hide();
void Wobject_CM_update();
void Wobject_CM_update(int x, int y, int w, int h);

these show/hide your object, update() calls show() if the object is already visible, and leaves hidden objects hidden. show()/hide() return FALSE if the object was visibility_locked. show() returns FALSE if the object was frozen. In all other cases they return TRUE.

int Wobject_CM_raise();
make this object the top object(on the screen). if there are top-locked objects, it will stay under them. returns FALSE if locked

int Wobject_CM_lower();
make this object the bottom object(on the screen). if there are bottm-locked objects, it will stay above them. returns FALSE if locked

int Wobject_CM_raise_and_lock();
raises the window, and locks it in a top position. Even if there are top-locked objects it will be raised to the top position (over the top-locked).

void Wobject_CM_attach_to(Wobject *other,int corner_this, int corner_that, int offset_x, int offset_y);
attaches one object to another. if the other object is raised/lowered/locked/hidden/shown this object will follow. the corners can be: WINDOW_UL_CORNER upper left WINDOW_UR_CORNER upper right WINDOW_LL_CORNER lower left WINDOW_LR_CORNER lower right the corner + offset pair determines the position this window will take relative to the other window. attaching is not mutual by default, but you can attach two objects to eachother like: a->attach_to(b,WINDOW_UL_CORNER,WINDOW_UR_CORNER,0,0: b->attach_to(a,WINDOW_UR_CORNER,WINDOW_UL_CORNER,0,0: if the corners/offsets don't match, those of the last call are taken.

do not attach more than two objects in a circle for example: a->attach_to(b, ) b->attach_to(c, ) c->attach_to(a, ) will result in an endless loop + stack overflow since a follows b follows c follows a follows b follows c follows a follows b follows c follows a follows b follows c follows a follows b follows c follows a follows b follows c follows a fol... you get it?

void Wobject_CM_set_lock(int lock);
lock can be TRUE or FALSE this will lock the object in the drawing hierarchy. a locked object cannot be raised, so once it arrives at the bottom it stays there, (top and bottom are the dimension *into* your screen 'bottom' is 'closer' to the electron gun of your monitor, while 'top' is 'closer' to you) even if you call raise(); When the top window is locked it will stay on top and new windows will be created under it. Unless *all* windows are locked, in which case the manager can not decide if they are locked to the top or the bottom, and will open the new window on top. There is one subtle pitfall in top locked windows: For example, you top-lock window A and then window B, next you unlock window A. Now window B will 'fall down' until it it bottom-locked. How come? The manager decides that a window is top-locked when there are only locked windows above it, so when A is above B and B is locked, it decides B is bottom-locked, and won't raise it anymore. So when you unlock a top locked window, always call lower( ) directly afterwards. (hiding it won't help, since a hidden window is still considered to be on top).

other locking functions if lock is TRUE
void Wobject_CM_set_lock_position(int lock); cannot be moved
void Wobject_CM_set_lock_size(int lock); cannot be resized (default TRUE)
void Wobject_CM_set_lock_scale(int lock); cannot be rescaled
void Wobject_CM_set_lock_viewport_position(int lock); viewport cannot be moved
void Wobject_CM_set_lock_viewport_size(int lock); viewport cannot be resized
void Wobject_CM_set_lock_visibility(int lock); object cannot be shown or hidden
void Wobject_CM_set_lock_shift(int lock) object won't respond to the shift_all function
lock can be TRUE or FALSE all are default false, except for lock_size which is default TRUE;

virtual BITMAP *Wobject_CM_bmp();
this function can return a bitmap attached to the object, if you don't define the function in your derived class it will return NULL (all objects need to have this function, because otherwise the implementation of child windows is very hard)

GeoInfo const *Wobject_CM_get_geoinfo();
returns a geoinfo class, since most information in this class is used in Window it will be described in that section (not all the information is used by default.for example: not all objects need to define a viewport, so they can ignore the information about it that is in GeoInfo)

int Wobject_CM_move(int new_x,new_y);
moves the Wobject to a new location returns TRUE on success or FALSE if the Wobject was position-locked

int Wobject_CM_rescale(int nw_size_x, int nw_size_y)
sets the size the Wobject will be when displayed on the screen. this does not change the real size of the Wobject, only the way it looks on the screen. returns TRUE on success, FALSE if Wobject was scale-locked

int Wobject_CM_move_rescale(int nw_pos_x,nw_pos_y,nw_size_x,nw_size_y);
does a combination of move & rescale, handy for minimizing functions etc. This returns FALSE if position_is_locked or scale_is_locked are set to TRUE;

WinSystem *Wobject_CM_get_manager();
returns the manager of this Wobject

RGB *Wobject_CM_get_its_palette();
returns a pointer to the palette the borders are drawn in;

void Wobject_CM_transform_coordinates(int *x, int *y);
transforms screen coordinates (x,y) to Wobject coordinates, unlike WinSystem_CM_process_coordinates(......) this will always transform the coordinates to this Wobject, even it (x,y) lies outside this Wobject.

void Wobject_CM_freeze();
void Wobject_CM_thaw();
int Wobject_CM_is_frozen();
if the object is frozen, it will not be updated on the screen. useful if you know you are going to call update() a lot of times and only really need to see the end result (for example when sending a MSG_DRAW message to a dialog, like in the GuiContainer class since wham_dialog_message( ) is implemented as a loop off calls to WHAM_SEND_MESSAGE( ) and each WHAM_SEND_MESSAGE results in an update() this would mean a lot of unnecessary updates) (BTW this last example is only true for the wham_* dialog functions, since the native Allegro functions don't call update())

void Wobject_CM_notify_children()
must be called when a window can have children( that is, bmp() doesn not return NULL) and something in the situation of the bitmap is changed (different size, for example) this function is mainly used in the Window_CM_resize( ) function.

virtual void Wobject_CM_set_user_area(pos_x,pos_y,size_x,size_y);
sets the size & location of the user area in the wobject since the Wobject itself doesn't have anything like a user_area it just sets the parameters in GeoInfo, unless your derived class defines it differently(like Window does)

virtual int Wobject_CM_resize(int nw_size_x, int nw_size_y);
sets the size of the object remember that size means the true size (it could be the size of the bitmap attached to it, like in Window) since Wobject doesn't know how to handle resizing your derived class should define this if it can be resized, the definition in Wobject just fills in the approproiate values. it leaves screen_size and viewport_size alone so noting will change on screen. for example: you have a 100x100 object with a viewport of 100x100 when you call resize(200,200) the viewport will still be 100x100 and the object will look the same on screen, but now the viewport could be enlarged to 200x200 with resize_viewport.

virtual int Wobject_CM_resize_viewport(int nw_size_x,nw_size_y);
virtual int Wobject_CM_resize_s_viewport(int nw_size_x,nw_size_y);
These resize the viewport, the former takes sizes relative to the object. The latter takes sizes relative to the_screen, you use the former if you need a viewport of a special size, you use the latter if you need the object to have a special size on screen (don't forget the borders are added so the resulting object will be sized (Left_Border_Size + nw_size_x + Right_Border_Size X Upper_Border_Size + nw_size_y + Lower_Border_Size ) returns true on success or FALSE if viewport_size_is_locked

int Wobject_CM_move_viewport(int nw_pos_x,nw_pos_y);
moves the vieport. returns true on success, false if viewport_pos_is_locked.

virtual int Wobject_CM_process_keyboard();
the default definition just returns 0. it will be called by the Wham_Secretary each time there is something in the keyboard buffer and the mouse is on this object.

furthermore there is one private function which is pure virtual so your derived classes need to define it, that's the function:

void Wobject_CM_draw(BITMAP *onto,int from_x,from_y,to_x,to_y);
onto - the bitmap to draw onto
from_x,from_y,to_x,to_y - the rectangle to draw in.
This function needs to draw the part of the object that's inside the specified rectangle(in screen coordinates) it is called by WinSystem often so make it as efficient as possible. Prior to calling this WinSystem sets the clipping rectangle of onto to the same rectangle, so you cannot draw outside it.

and as a last thing there are private functions, which are virtual and can be overloaded if necessary:

int Wobject_CM_inquire_mouse(int x, int y)
this function is called by WinSystem to determine if the point (x,y), (in the window's coordinate-system), is part of the window. the default implementation just returns TRUE but you can overload it in your derived class(see example 14). This provides a way to make a 'hole' in your object, which is not part of the object. WinSystem_CM_process_coordinates( ) will always consult this function, before deciding if a point lies within a window.

_ More_Wobject_functions:
int Wobject_CM_process_message(Wobject *from,int MSG); see section 'messages' for an explanation of this function

Window class


use #include <window.h> when you use this class (winsys & wobject will be included by window)

This class provides a basic Window. It contains the following userfunctions

Window_CM_Window(char *name,int size_x,int size_y, int pos_x, int pos_y);
this constructor creates a window with it's upper left corner at pos_x,pos_y an with size size_x X size_y, it sets the user area to (0,0)-(size_x,size_y) and it sets the on_screen size also to size_x X size_y. It sets is_locked,pos_is_locked and scale_is_locked to FALSE and size_is_locked to TRUE.

Window_CM_Window(char *name, BITMAP *bmp, int pos_x, int pos_y); Same as the above, only this one uses bmp as its memory buffer and takes its sizes from bmp, when the window is destroyed, bmp will remain intact.

Window_CM_Window(char *name,int size_x,int size_y,int pos_x, int pos_y,WinSystem *its_manager); Window_CM_Window(char *name,BITMAP *bmp,int pos_x, int pos_y,WinSystem *its_manager); Same as the above, but these take a pointer to a specific manager. This can be used to tie the window to another manager than WHAM.

Window_CM_Window(char *name,int size_x,int size_y, int pos_x, int pos_y,void (*draw_border)(BITMAP *onto, Geoinfo const *g,int from_x,int from_y,int to_x,int to_y) ); Window_CM_Window(char *name, BITMAP *bmp, int pos_x, int pos_y, void (*draw_border)(BITMAP *onto, Geoinfo const *g,int from_x,int from_y,int to_x,int to_y) ); Window_CM_Window(char *name,int size_x,int size_y,int pos_x, int pos_y,WinSystem *its_manager, void (*draw_border)(BITMAP *onto, Geoinfo const *g,int from_x,int from_y,int to_x,int to_y) ); Window_CM_Window(char *name,BITMAP *bmp,int pos_x, int pos_y,WinSystem *its_manager, void (*draw_border)(BITMAP *onto, Geoinfo const *g,int from_x,int from_y,int to_x,int to_y) ); Same as the above, but these take a pointer to a border drawing function, this function should work as follows: When passed NULL for 'onto' it must return the border sizes according to the value in from_x. If from_x = UPPER_BORDER_SIZE it must return the height of the upper border etc. other possible values for from_x are LOWER_BORDER_SIZE,LEFT_BORDER_SIZE, RIGHT_BORDER_SIZE . When 'onto' is not NULL it must draw a border fitting around the window,whose sizes can be obtained from geoinfo, but it cannot draw outside the rectangle specified by from_x,from_y,to_x,to_y since WinSYstem will set onto's clipping rectangle accordingly (geoinfo is a reference to the data of the actual window, that's why it must be declared 'const')

to see how this is done take a look at the border drawing function of the BorderWin or the Frame class.

Window contains two static variables which influence the text output

int Window_CM_Text_Color;
the color of textoutput

int Window_CM_Scroll_Behaviour
this can be WINDOW_SCROLL_SHIFT or WINDOW_SCROLL_OVERLAY in the first case the whole window is shifted up one line when textouput reaches the last line of the window (like a text mode screen). In the second case the textcursor will flip back to the top of the window when it reaches the bottom.

void Window_CM_printf ()
like printf() outputs text to the window in color Text_Color using the specified Scroll_Behaviour

BITMAP *Window_CM_bmp();
returns a pointer to the user area of the window bitmap

void Window_CM_set_user_area(pos_x,pos_y,size_x,size_y);
sets the size & location of the user area in the window by making this smaller than the window itself, you can prevent drawing over your borders/dragbars etc.

int Window_CM_resize(int nw_size_x, int nw_size_y);
resizes the bitmap associated with the window. look out, this will make a new memory bitmap for the window so any pointers to the old bitmap will be invalid after this. returns TRUE on success, FALSE if window was size-locked

Wobject, from which Window is derived, contains a GeoInfo object which can be retrieved using Wobject_CM_get_geoinfo(); it is discussed here since Window uses a lot of it's contents

_ Geoinfo class
the members of GeoInfo are int size_x the size of the window bitmap buffer size_y viewport_size_x size of the viewport viewport_size_y viewport_pos_x position of the viewport on the buffer viewport_pos_y screen_size_x width of the window on the screen screen_size_y height ,,, user_size_x width of the user area user_size_y height ,,, pos_x position of the window pos_y user_pos_x position of the user area within the window user_pos_y tag a number identifying each window is_locked TRUE if the window is locked on a top/bottom position in the drawing hierarchy pos_is_locked TRUE if window cannot be moved size_is_locked TRUE if the window cannot be resized scale_is_locked TRUE if the window cannot be resized viewport_pos_is_locked TRUE if the viewport cannot be moved viewport_size_is_locked TRUE if the viewport cannot be resized is_displayed boolean True if the window is displayed Upper_Border_Size border sizes Lower_Border_Size Right_Border_Size Left_Border_Size char *name name of this window float scale_x scaling factors: screen_size_x = viewport_size_x * scale_x float scale_y

the geometry of a window:

(pos_x - Left_Border_Size,pos_y - Right_Border_size) (pos_x + screen _size_x +Right_Border_Size -1, pos_y - Upper_Border_Size) \_____________________________________________________________________/ | (pos_x,pos_y) border (pos_x + screen_size_x - 1 , pos_y) | \______________________________________________________________/ | | |\ window / | | | | (viewport_pos_x,viewport_pos_y / | | | | (viewport_size_x - 1,viewport_pos_y) | | | | (viewport_pos_x+viewport_size_x-1,viewport_pos_y+viewport_size_y-1) | | (viewport_pos_x,viewport_pos_y+viewport_size_y - 1) \ | | | |/____________________________________________________________\| | | / \ | |(pos_x,pos_y + screen_size_y - 1) (pos_x + screen_size_x - 1, pos_y+screen_size_y -1) |_____________________________________________________________________| / \ (pos_x - Left_Border_Size, pos_y + screen_size_y +Lower_Border_Size - 1) (pos_x + screen_size_x + Right_Border_Size - 1, pos_y+screen_size_y + Lower_Border_Size - 1) geometry of the viewport: (0,0) \ _____________________________________________________________________ | (viewport_pos_x,viewport_pos_y) | | \______________________ window bitmap | | | viewport | | | |______________________| | | \ | | (viewport_pos_x + viewport_size_x - 1,viewport_pos_y,viewport_size_y -1) |_____________________________________________________________________| \ (size_x - 1, size_y -1)


WhamWin class


use #include <whamwin.h> when you use this class( you won't need window.h anymore, for WhamWin is derived from Window and it will include window.h for you)


the example class WhamWin provides some more functionality + all the functionality of the bare Window class


_ WhamWin_CM_WhamWin(int size_x, int size_x,int pos_x,int pos_y,char *name);
WhamWin_CM_WhamWin(BITMAP *bmp,int pos_x,int pos_y,char *name);

these do the same as the corresponding Window_CM_ constructors they will return a window containing a drag bar an minimize/maximize/original-size buttons

Wobject *WhamWin_process_mouse(int *x, int *y);
this function returns the window in which the mouse currently is (NULL if it's not inside a window) and it stores the relative mouse (x,y) position in x and y (relative to the origin and the original size of the window). Wham_Secretary will call it for you if you call Wham_Secretary.process_mouse() in your main loop

BorderWin class

use #include <bordered.h>


_ BorderWin_CM_BorderWin(int size_x,int size_y,int pos_x,int pos_y, char *title);
BorderWin_CM_BorderWin(BITMAP *bmp,int pos_x,int pos_y,char *title); BorderWin_CM_BorderWin(int size_x,int size_y,int pos_x,int pos_y, char *title,WinSystem *its_manager); BorderWin_CM_BorderWin(BITMAP *bmp,int pos_x,int pos_y,char *title,WinSystem *its_manager); which , I hope, are self explaining;

User functions are:

Wobject *BorderWin_process_mouse(int *x, int *y);
for an explanation see the WhamWin_process_mouse function of the WhamWin class

static void BorderWin_CM_add_system_box(BITMAP *sprite, void (*callback)(Window *win));
this function adds a systembox to all BorderWins, the systemboxes are drawn in the top border, from right to left, the width of the systembox will be taken from the width of 'sprite' , the height will be the height of the border, when the systembox is clicked, the callback function will be called with a pointer to the window whose systembox was clicked, so you can use this to do thing like maximize/minimize etc.

static void BorderWin_CM_destroy_system_boxes();
this removes all the systemboxes from all the windows, so you can start from scratch.

there are some static variables which can be set prior to opening the first window that will influence the look of the window

static char *BorderWin_CM_DatafileName;
this points to an Allegro datafile containing Bitmaps & palette for the border, it's default is "whamdat.dat". To see how this datafile is organized, have a look in the provided examples with the allegro grabber program.

static int BorderWin_CM_RemapPalette;
when this is set to TRUE the bitmaps read from the above datafile will be remapped to look (approximately) the same in the current palette;

static BITMAP *BorderWin_CM_UpperBorderBitmap;
static BITMAP *BorderWin_CM_LowerBorderBitmap; static BITMAP *BorderWin_CM_RightBorderBitmap; static BITMAP *BorderWin_CM_LeftBorderBitmap; static BITMAP *BorderWin_CM_UpperLeftCorner; static BITMAP *BorderWin_CM_UpperRightCorner; static BITMAP *BorderWin_CM_LowerLeftCorner; static BITMAP *BorderWin_CM_LowerRightCorner; these are pointers to the bitmaps used to draw the borders, you should not change these after the first window is opened, but when you set them prior to opening the first window, BorderWin will not try to read the bitmaps from a datafile, note that BorderWin_CM_remap_palette has no influence when you use this method.

static int BorderWin_CM_Move_Style;
this can be BORDERWIN_OPAQUE or BORDERWIN_CLEAR, default is MOVE_OPAQUE

Frame class

#include <frame.h>

the class frame doesn't do much of interest, it's just the output of the commando 'wclass Frame frame' with some comment added and is merely an example of how to derive your own class from Wobject (though you could use it to derive window classes from, for it defines a (simple) border drawing function).

Wobject *Frame_process_mouse(int *x = 0, int *y = 0);
Frame's mouse processor (it sounds like some sort of butcher, mouse processor)

GuiContainer class

#include <guicon.h>

constructor: _ GuiContainer_CM_GuiContainer(int size_x,int size_y,int pos_x,int pos_y,char *name,DIALOG *d);
this creates a window containing an allegro like dialog, make sure the window is big enough for your dialog. the d parameter is a standard Allegro dialog, BUT all the dialog procedures must be specially written for a wham dialog(see section gui) the standard dialog procedures of Allegro 2.2 are ported to wham under the name wham_* where * is the original name. the dialog will not yet be started, and the window will not yet be visible (use show())

int GuiContainer_CM_get_closer_object();
Returns the dialog object that closed the dialog. or -1 if the dialog is still running or not closed by an object.

void GuiContainer_CM_start(int focus_obj = -1);
starts the dialog, when the dialog is running, it will respond to user input.

void GuiContainer_CM_stop();
stops the dialog, this is also called when the dialog is closed by itself


int GuiContainer_CM_is_running();
return TRUE if the dialog is not yet closed.

static int GuiContainer_CM_Border_Color;
static int GuiContainer_CM_Title_Color;
specifies the color of the border surrounding the dialog and the tile printed in it.

int GuiContainer_CM_process_keyboard();
causes the dialog to examine the keyboard buffer, and use the keys in it ( you don't need to call this sinec Wham_Secretary will)

AlGuiContainer class

This provides the same functionality as GuiContainer, but it can take a standard Allegro dialog (currently this is the only way to use Allegro 3.0 dialog features) because these dialog procedures are not specially written for wham this is less efficient than using the specialised wham_ dialog, but it and since I need to fiddle around with the global screen parameter, the mouse get's a bit jerky, but it works and allows you to use Allegro 3.0 dialog procedures.

it has the same members as GuiContainer , but it has one extra static member:

static int AlGuiContainer_CM_Refresh_Rate;
since the dialog procedures don't send update commands to the window manager, the window manager cannot know when it needs to update the dialog window, therefore it just updates it every Refresh_Rate steps.

int whamgui_raise_style
this is not really a member of Guicontainer, but it is defined in whamgui.cc (in this way other windows can also access it). it can be RAISE_IMMEDIATE or RAISE_CLICK,

Gui

the wham gui is just the Allegro 2.2 gui, somewhat modified to work with wham since it is almost the same I will only discuss the differences, I'm sorry for all those who never worked with the allegro 2.2 gui and only know the 3.0version, they'll have to lookup in allegro's changelog what has changed between the two versions (some extra objects, slighly different menu system).

I probably won't update this gui, but concentrate on get the native Allegro gui to work smoothly,but I leave it in in case I cannot get the Allegro gui to work.

- all the dialog procedures are prefixed with wham_ (d_button_proc -> wham_d_button_proc) - a wham dialog procedure works the same way as an Allegro dialog procedure except: 1. it should draw on 'wham_guiscreen' instead of 'screen' 2. it must use __wham_mouse_x() and __wham_mouse_y() to obtain the mouse position 3. it must use WHAM_SEND_MESSAGE( ) and wham_dialog_message( ) and never SEND_MESSAGE( ) or dialog_message( )

- wham_dialog_message(DIALOG *d, int message, int c, int *object, GuiContainer *container= 0); should be used instead of dialog_message( ), container must be specified if another than the current dialog is called

-wham_do_dialog(DIALOG *d, int object, Window *container); needs a window to draw on it completely takes over control so make sure the window is the top window, or you might end up not being able to see your dialog's close button.

-wham_popup_dialog(DIALOG *d,int object); like wham_do_dialog, but creates it's own window

-look in whamgui.h if you need any of the other gui functions if it's not in there, use the standard allegro form+ ( alert( ), file_select( ) etc )

- whamgui still takes fg color etc. from the Allegro globals.

extras:

int wham_d_3dbutton_proc(DIALOG *d, int MSG, int c);
like wham_button_proc, but looks 3d (like some commercial window systems:) it ignores the fg and bg members of DIALOG and takes it's colors from:

int whamgui_white_color;
int whamgui_light_color; int whamgui_middle_color; int whamgui_dark_color; int whamgui_black_color; which need to be set by YOU( the defaults are mostly useless).

int wham_d_3dbox_proc(DIALOG *d, int MSG, int c);
like d_box_proc, but... @

   if (fg)
      high box
   else
      hollow box ( see ex13.cc)
   @

int whamgui_raise_style
see Guicontainer documentation.

BillWin class


#include <billwin>


NOTE!!! BillWin cannot handle on-the-fly colordepth switching, so don't use BillWin if you need to alter the colordepth while the program is running.


_ BillWin_CM_BillWin(int size_x,size_y,pos_x,pos_y,char *name,int flags = 0);
BillWin_CM_BillWin(int size_x,size_y,pos_x,pos_y,char *name,WinSystem *its_manager,int flags = 0); flags can be: BILLWIN_STYLE_RESCALE - which causes the window to be rescaled on border-dragging (default the viewport is resized)

(hope to add more flags later)

it contains nearly the same functionality as the Window class, so I'll only describe what's extra

some int's describing colors etc.

static int BillWin_CM_Text_Color;
static int BillWin_CM_Bar_Color; static int BillWin_CM_Black_Color; static int BillWin_CM_Dark_Color; static int BillWin_CM_Middle_Color; static int BillWin_CM_Light_Color; static int BillWin_CM_White_Color; static int BillWin_CM_BorderSize; // can be set only once (at program start) static int BillWin_CM_Border_Color;

int BillWin_CM_get_state();
returns BILLWIN_STATE_MINIMISED,BILLWIN_STATE_MEDIUMISED, or BILLWIN_STATE_MAXIMISED.

void BillWin_CM_set_icon(BITMAP *icon);
sets an icon for when it's minimized, this must have the minimal dimensions of (WinSystem_CM_Minimum_Size_x + 4 +BillWin_CM_Border_Size,WinSystem_CM_Minimum_Size_y + 23 +BillWin_CM_Border_Size)

void BillWin_CM_set_state(int state);
state can be one of BILLWIN_STATE_MINIMISED,BILLWIN_STATE_MEDIUMISED, or BILLWIN_STATE_MAXIMISED.

FrameWin class

this class provides the same functionality as BorderWin, but it uses simple one color borders, for this reason, it doesn't have all the static variables connected with the border bitmaps (DatafileName, UpperBorderBitmap etc)

it has some extra static's

int FrameWin_CM_Border_Color;
int FrameWin_CM_Title_Color;
int FrameWin_CM_Outline_Color;
which are, how surprising, the color of the border/title/outline. for the rest see the documentation of borderwin

Pager class

constructor: _ Pager_CM_Pager(int from_x,int from_y,int to_x,int to_y,int scale);
the coordinates define the area to map, scale defines the scale a pager is a small map of the (virtual) screen when you click on the pager, the shift_all function is used to shift the clicked area to the center of the screen.

static int Pager_CM_Border_Color;
static int Pager_CM_Passive_Color; static int Pager_CM_Active_Color; static int Pager_CM_Pager_Color; static int Pager_CM_Background_Color; various colors

OClock class

constructor _ OClock_CM_OClock(int radius, pos_x, pos_y);
this creates a clock derived from wobject so it can be raised/lowered etc size/scale is locked

int Oclock_CM_Fg_Color;
int Oclock_CM_Bg_COlor; define the colors of the clock;

Sunglass class

constructor _ Sunglass_CM_Sunglass(int w,int h, int x ,int y, char *name);
greates a dark tinted translucent frame it needs the color_map set up to a lightning map for the current palette. (Uttely useless, but I made it just because it was possible)

Panel class

#include <panel.h> panels cannot be rescaled with the mouse but they can be moved with the mouse panels are usefule for displaying startup logo's , warning messages etc

this class is derived from window, so it has all the functionality of window plus: constructor _ Panel_CM_Panel(int size_x,int size_y,int pos_x,int pos_y,char *name);

static int Panel_CM_Light_Outline_Color;
static int Panel_CM_Dark_Outline_Color; static int Panel_CM_Background_Color; colors

int Panel_CM_printf(char *format,...);
like printf

ScrollBar class

#include <scrolbar.h>

the scrollbar object is an object you can attach to other objects they'll show themselves as soon as the viewport_size is smaller than the size of the object. And they allow the user to scroll the viewport by dragging the scrollbars

constructor _ ScrollBar_CM_ScrollBar(Wobject *onto,int type);
this creates a scrollbar and attaches it to 'onto'. type can be one of TYPE_VERTICAL_SCROLLBAR TYPE_HORIZONTAL_SCROLLBAR

the following statics determine the way the scrollbar looks static int ScrollBar_CM_White_Color;
static int ScrollBar_CM_Light_Color; static int ScrollBar_CM_Middle_Color; static int ScrollBar_CM_Dark_Color; static int ScrollBar_CM_Black_Color;

TextWindow class

#include <wtext.h>

TextWindow are windows that can contain only text, they don't contain a bitmap, so they use ver little memory. They cannot be rescaled/resized, and the viewport cannot be changed (though the last restriction will probably change in future versions)

TextWindow_CM_TextWindow(int size_x,int size_y,int pos_x, int pos_y,char *name, FONT *_font = NULL);
this creates a new TextWindow, if no font is specified, the default is used. note that size_x and size_y are in characters, not pixels!

_font must be a fixed width font.

void TextWindow_CM_printf(int x, int y, char *format, ...);
This prints a string on cursorlocation x,y in the window. it does not wrap around, and it does not change the position of the cursor. newlines are ignored.

void TextWindow_CM_printf(char *format,...); prints a string at the current cursor location. linefeeds are handled correct, when the bottom of the window is reached, the window will scroll up. lines longer than the window are wrapped. this function calls update(), so the effect is immediately visible.

void TextWindow_CM_gotoxy(int x,y);
sets the cursorlocation to x,y;

void TextWindow_CM_clear();
sets the cursor to 0,0 and clears the window, update() is called by this function, so the effect is immediately visible.

void TextWindow_CM_scrollup(int lines = 1);

scrolls the window 'lines' lines up.

void TextWindow_CM_set_colors(int fg,bg);
sets the foreground and background colors for the text. if bg is -1 the window will be translucent (sort of HUD display).

the class contains two statics:

int TextWindow_CM_Border_color;
the color of the border.

int TextWindow_CM_Title_Color
the color of the title;

Wham_Secretary class

#include <secretar.h>

Wham_Secretary is the only instance (you don't need more) of the RegisterBin class. it provides the following functions:

Wobject *Wham_Secretary.process_mouse(int *x = NULL, int *y = NULL);
this function calls the appropriate mouse function for each object and returns the object the mouse is currently in. (see WhamWin for an explanation of how these process_mouse functions work)

void Wham_Secretary.set_key_catching(int catch);
catch can be TRUE or FALSE if key_catching is TRUE Wham_Secretary.process_mouse() will 'eat up' unused keys when the mouse is not in an object if the mouse is in an object it will call the objects process_keyboard() function to get rid of the keys. default key_catching is on(TRUE). Set it to FALSE if your program handles its own keyboard input, keyboard shortcuts in GuiContainers may behave strange if key_catching is disabled.

void Wham_Secretary.set_screen_saver(void (*screensaver)(), int time, char *name = NULL);
sets a screensaver routine which will be called after time seconds of inactivity from mouse or keyboard. the screen will be redrawn after the function returns, so your screensaver function needs not worry about that, also wham will restore the palette afterwards. If 'name' is not specified , it will default to "User Defined".

void Wham_Secretary.set_screen_saver_time(int new_time);
resets the screensaver trigger time to new_time seconds

int Wham_Secretary.load_screen_saver(char *filename,int time);
loads a screensaver from a wham screensaver (.wss) file, to learn how to create these files see readme.txt in the wss directory. since a .wss file is in essention a .dxe, it can be unloaded anymore. for this reason this function keeps a list of which files are already in memory, so two requests for the same screensaver wont result in loading it twice.

char *Wham_Secretary.get_current_screen_saver_name();
returns the name of the currently active screensaver. this name comes from the wss file, or from the call to set_screen_saver;

void Wham_Secretary.set_screensaver_suspension(int susp);
when susp == TRUE it causes the screensaver to be blocked ( it won't go off after t seconds) handy if you're displaying an animation, or something else the user has to wait for

void Wham_Secretary.schedule(int (*fun)(void *arg),void *arg,int time);
this adds a function to Wham_Secretary's scheduler list, it will be called every time seconds ( or perhaps later if Wham_Secretary can't keep up).If fun returns nonzero it will be thrown off the list. Each time Wham_Secretary.process_mouse() is called, it checks it's scheduler list to see if it needs to call a function in it, this means that if it can't keep up, or Wham_Secretary.process_mouse isn't called often enough, things might get behind on the schedule, this can give sometimes strange results. For example when in the demo program the screensaver is acivated, process_mouse is no longer called, so when you touch a key the clock window gets updated very often in a short period of time, since the scheduler tries to catch-up.

Helper Functions


In helpers.cc and helpers.h are some helper functions and classes defined:


class Mouse_Cursor
contains the BITMAP and the hotspots of a mouse cursor constructor:

_ Mouse_Cursor_CM_Mouse_Cursor(BITMAP *cursor, int hotspot_x,hotspot_y);

Mouse_Cursor *set_mouse_cursor(Mouse_Cursor m);
sets a new mouse cursor returns the old one

void wham_trans_calc_progress(int pos)
called while setting up the shade table when using WHAM_SLOW_SHADOW

void cleanup_wobjects();
deletes all wobjects, but does not delete WHAM

void trace(char *format,...);
for debugging purposes takes printf style arguments. prints them on the screen and waits for a keypress

void ttrace(char *format,...)
like trace( ), but waits just 1 second instead of waiting for a keypress ( handy if keypresses mess up your program)

FILE *DEBUG_OUTPUT_FILE;
if this is not NULL, trace will print to this file instead of the screen;

void fatal(char *format,...);
takes a printf style message shuts down the program and prints the message to stderr

void out_of_mem(char *message);
prints the message and exits, but does not use any extra memory nor tries to remove wham from memory ( because that also costs some extra memory, which can cause the program to hang the computer) and thus leaves garbage in the memory with DPMI-servers that don't clean up on exit (such as PMODE).

void remap_bitmap(BITMAP *b,PALETTE old);
remaps a bitmap that uses palette 'old' so that it'll look approximately the same in the current palette.

void w_textout(BITMAP* onto, FONT *font,unsigned char *txt,int x,y, int color,mode);
void w_textout_centre(BITMAP* onto, FONT *font,unsigned char *txt,int x,y, int color,mode);
these just call text_mode(mode) followed by the approprisete textout function.

void mouse_off()
void mouse_off() void freeze_mouse() void thaw_mouse() these are shortcuts for show_mouse(NULL)/show_mouse(screen)/mouse_freeze_flag = TRUE/FALSE

void show_progress(char *msg, int now, int max); shows a progressbar, you must make sure max is really reached for the bar is erased only when now == max;

char *message_string(inyt msg); returns a string containing a description of message msg you must not delete this string.

Messages

Wham contains a simple message system, which can be used to send messages from one window to the other or to all windows. The use of this is demonstrated in the demo program, where the system reacts to a W_MSG_HIDDEN message, sent by the BillEx window when it is hidden, by unselecting the BillWin button.

the following messages are predefined in Wham:

W_MSG_RAISE W_MSG_HIDE W_MSG_SHOW W_MSG_UPDATE W_MSG_LOWER these can be sent to a Wobject and correspond to the member functions of the same name

W_MSG_RAISED W_MSG_GOING_TO_RAISE W_MSG_HIDDEN W_MSG_SHOWN W_MSG_MOVED W_MSG_MOVE_RESCALED W_MSG_RESIZED W_MSG_RESCALED W_MSG_VIEWPORT_RESIZED W_MSG_CREATED W_MSG_DESTROYED W_MSG_USER_AREA_SET W_MSG_GOING_TO_LOWER W_MSG_UPDATED W_MSG_LOWERED W_MSG_RAISE_AND_LOCKED W_MSG_LOCKED W_MSG_UNLOCKED W_MSG_VIEWPORT_MOVED these are sent by Wobjects to all other objects (using broadcast_message( )) when the corresponding userfunctions are done

W_MSG_ATTACHED is sent by an object to the object it is attched to (see attach_to)

W_MSG_SHIFTED is sent to all objects by the shift_all function, so they can take actions

W_MSG_MANAGER_DELETE sent by the manager when it is deleted to all wobjects prior to deleting them so they can pray their last prayers.

W_MSG_GOING_TO_RAISE W_MSG_GOING_TO_LOWER sent by objects just before raising/lowering this is needed by mutually attached objects so that they can respond correctly to each others raising and lowering

W_MSG_UPDATED sent by a window just after update( ) was called

W_MSG_LOCKED W_MSG_UNLOCKED W_MSG_RAISE_AND_LOCKED sent when the window is locked/unlocked

W_MSG_LOSTMOUSE W_MSG_GOTMOUSE sent by the manager to objects when they loose/get mouse focus

W_MSG_FROZEN W_MSG_THAWN send by a wobject when it is frozen/thawn

All wham messages are defined in WinSys.h to be negative integers, so if you define your own messages, please use positive integers. I promise to use only negative numbers in future releases of wham so there won't be any clashes with user defined messages.

the following functions are available for message processing

int WinSystem_CM_send_message(Wobject *from, int msg, Wobject *to, Wobject **accepted);
This sends a message to object 'to', by calling it's process_message( ) function with the specified object and message and returning the value this function returns.

'from' may be set to NULL, if it's not a window that's sending the message or if it's not important for the receiver to know who sent it.

if 'to' is set to NULL, all objects are tried (from the top objetc down) until a process_message( ) function returns non-zero, then this value is returned and no further object are tried. This implies a process_function( ) should return non-zero if it has used the message. if accepted != NULL then *accepted is set to a pointer to the object that accepted the message.

int WinSystem_CM_broadcast_message(WObject *from, int msg);
sends a message to all objects. returns TRUE if one of the objects returned non-zero

void WinSystem_CM_set_user_msg_processor(int (*my_processor) (Wobject *from, int msg));

This can be used to hook a user-defined message processor into the system. It will get all the messages sent with broadcast_message( ), and all messages sent with send_message(from, msg,NULL) that are rejected by all other objects. The function has to be of the form int my_msg_processor(Wobject *from, int msg); it should return 0 if it doesn't use the message, or a nonzero int which will be passed back to the caller of send_message( ) if it does use it.

virtual int Wobject_CM_process_message(Wobjetc *from, int msg);
this function processes the message. because it's declared virtual, it can redeclared in derived classes. please remeber to call the original Wobject_CM_process_message( ) from your redefined functions, to allow it to react properly to the standard messages.

Pitfalls

-the defenition of a border_drawing function is a very precise work drawing a border of width 11 or 9 while reporting 10 will almost certainly lead to garbage on the screen, take a look at the Frame example class to see how to do it. -while processing a message, be sure not to call a function which generates that same message for the same window (such as raise for the message W_MSG_RAISED) or you might get trapped in an endless loop. -some of the window functions change the text_mode, since there is no way to get the previous text_mode from allegro, they cannot restore it so alway explicitly set your text_mode before using text_out or use the helperfunctions w_textout( ) and w_textout_centre( ) -send your messages to the right window manager, for they are passed on to child windows, but not to parent windows. -The window class handles colordepth differences between the window bitmap and the screen gracefully (and consequently BorderWin,FrameWin,WhamWin,Panel,GuiContainer, as well) But Billwin is not derived from Window, so if you for example need to display 8 bit images on a 24 bit display, don't use BillWin, or rescaling won't work.

Wham Init

the file whaminit.cc contains two shortcut functions to initialise wham

void wham_standardinit(char *filename= NULL);
initialises wham, filename points to an allegro datafile containing bitmaps for the borders for the borderwin class if you use this function, it is perhaps a good Idea to copy the contents of this function to your own init function, so you can alter the settings. You can also alter the settings in whaminit.cc and recompile wham.

void wham_total_init(int pause = TRUE);
-initialises alegro,graphicsmode & wham -sets the palette , especially colors 251,252,253,254,255 are important for the system, but if you use borderwins, you should not alter the rest of the palette either. -installs an at_exit function to automatically remove wham on program exit

Addresses

   email:
      m.versteegh cpedu.rug.nl (while I'm still studying)
      vsteegh dds.nl   (parents,if the other on doesn't work)
   telephone:
      none
   mail:
      Martijn Versteegh
      postbox 1443
      9701 BK
      Groningen
      The Netherlands
   living:
      somewhere on the Dutch waterways on the
      motorship 'Aaltje'.

Thanks

DJ Delorie - for DJGPP Shawn Hargreaves - for Allegro FB - for teaching me C/C++ H.D.Zelle - for playing with the computer when we ought to write reports

that's all folks

Index