DockApps HOWTO (fwd)

James (
Mon, 26 Apr 1999 17:12:49 +0100 (BST)

here's an email i sent someone when they asked me how to write a wharf applet.
(note: i use the WindowMaker method of doing things, but it's all the same)

---------- Forwarded message ----------
Ok. Writing dockapps is easy.

All you need is an existing dockapp to follow and you're all set.
Find a copy of wmitime and unpack it. make a directory for your own DA and
copy the makefile and wmgeneral stuff into it. wmgeneral provides nice and
easy routines for opening X windows and stuff.

You'll need to edit the makefile so it compiles your code and not wmitime.

Now. if you look in the top part of the main wmitime c source you'll see it
#includes a load of stuff including the xpm image.

suppose your DA xpm was called foobar.xpm then you'd do something similar

#include "foobar.xpm"
char foobar_mask_bits[64*64];
int foobar_mask_width = 64;
int foobar_mask_height = 64;

Ok, so that provides the XPM. Now you need these variables...

Display *display;
int screen_num;

static char *progname;

Now we get onto the main() function....

void main (int argc, char **argv)
    XEvent Event;
    int but_stat = -1;

These are needed, the Event holds info about events (mouse movements, clicking,
windows being covered etc). The but_stat is used to test if a button has been

this sets the program name...

progname = argv[0];

this does something! It appears to chop out the correct part of the XPM image
(note: it is normal to have one XPM image containing all the graphics
used by your DA. you then use offsets to get at the right image)

    createXBMfromXPM (as3pc_mask_bits, AS3pc_panel_xpm, as3pc_mask_width,

This opens an X window

    openXwindow (argc, argv, AS3pc_panel_xpm, as3pc_mask_bits,
        as3pc_mask_width, as3pc_mask_height);

These add mouse regions (think Image Map)
The first thing (TICK, CROSS) is an integer that references that particular
button. #define TICK 0 .. #define CROSS 1 ... and so on. The last 4 ints are
the co-ords...

    AddMouseRegion (TICK, 4, 49, 15, 60);
    AddMouseRegion (CROSS, 49, 50, 60, 61);

This makes the window appear.


Now we get onto the main event loop. This is an infinite loop.

    /* event loop */
    while (1)

draw the window...


handle normal X events...

        while (XPending (display))

This gets the next event...

            XNextEvent (display, &Event);
            switch (Event.type)

window was uncovered...

                case Expose:
                    RedrawWindow ();

window was killed...

                case DestroyNotify:
                    XCloseDisplay (display);
                    exit (0);

MOUSE button pressed...

                case ButtonPress:

this checks to see where it happened.

                    i = CheckMouseRegion (Event.xbutton.x, Event.xbutton.y);
                    but_stat = i;

MOUSE button released...

                case ButtonRelease:

See where it happened (you act when the button is released)

                    i = CheckMouseRegion (Event.xbutton.x, Event.xbutton.y);

see which button-area was pressed...

                    if (but_stat == i && but_stat >= 0)
                        switch (but_stat)
                            case TICK:
				/* insert code here */
                            case CROSS:
				/* insert code here */
                    but_stat = -1;

VERY IMPORTANT! DO NOT REMOVE (you can fiddle) this stops the X app
running away and eating up all the available processing power. Remove it
and see what i mean...

        usleep (100000);

There. That's it. Down here you'd have any functions you want etc...
look in the wmgeneral.c file to see what the functions do, they are usually
just convenient ways of calling the standard X stuff (and read their manpages,
it's how i worked out the copyXPM thing)

+++      The program isn't debugged until the last user is dead.     +++