The Official FVWM Homepage - Module-to-Fvwm Communication
Module Writing
Before you write a module, you will want to look at a few different
fvwm modules. The techniques used have evolved over time, and no
one module contains all the best techniques. Some of them may be on
this page, but undoubtedly some of them are buried in the source code.
Module communications protocol
Modules communicate with fvwm via a simple protocol. In essence, a
textual command line, similar to a command line which could be bound
to a mouse, or key-stroke in the .fvwm2rc, is transmitted to fvwm.
First, the module should send the ID of the window which should be
manipulated. A window ID of ``None'' may be used, in which case Fvwm
will prompt the user to select a window if needed. Next, length of
the the command line is send as an integer. After that, the command
line itself is sent. Finally, an integer 1 is sent if the module plans
to continue operating, or 0 if the module is finished. The following
subroutine is provided as an example of a suitable method of sending
messages to fvwm:
void SendText(int *fd, char *message, unsigned long window) {
int w;
if (message != NULL) {
write(fd[0],&win,sizeof(Window));
w=strlen(message); /* calc the length of the message */
write(fd[0],&w,sizeof(int)); /* send the message length */
write(fd[0],message,w); /* send the message itself */
/* send a 1, indicating that this module will keep going */
/* a 0 would mean that this module is done */
w=1;
write(fd[0],&w,sizeof(int));
}
}
This routine is available as a library function in libfvwm.
For compatibility with older code, there is a macro "SendInfo"
which can be used instead of the function name SentText.
Module information requests
There are special built-in functions, Send_WindowList and
Send_ConfigInfo.
Send_WindowList causes fvwm to transmit everything that it is
currently thinking about to the module which requests the information.
This information contains the paging status (enabled/disabled),
current desktop number, position on the desktop, current focus and,
for each window, the window configuration, window, icon, and class
names, and, if the window is iconified, the icon location and size.
For example, some modules during start up want to know the state of
all current windows. The would ask fvwm for this information like this:
SendText(Channel,"Send_WindowList",0);
Send_ConfigInfo causes fvwm to send the module a list of all
commands it has received which start with a ``*'', as well as the
PixmapPath, IconPath, ColorLimit, and ClickTime commands that fvwm is
currently using.
This is implemented in fvwm/modconf.c.
Note that "SendConfigInfo" is sort of a memory dump type request,
and the number of commands a module might get from this request
may change over time. The module should be prepared to ignore commands
it is not interested in without generating a warning or error.
This request is normally made during module startup for a module
to read its current configuration and some general information.
Fvwm provides some subroutines to make this process fairly painless.
Here is an example from FvwmAnimate.c:
static void ParseOptions() {
char *buf;
while (GetConfigLine(Channel,&buf), buf != NULL) {
ParseConfigLine(buf);
} /* end config lines */
} /* end function */
Controlling information sent to
modules
fvwm lets each module control exactly what
information is passed to the module. A module can send the
command Set_Mask, followed by
a number which is the bitwise OR of the packet-types the
module wishes to receive. If the module never sends the Set_Mask
command, then all message types in the default mask are sent. The
default mask is defined in fvwm/module.h as "MAX_MASK". This
currently (October 1998) includes all messages except M_LOCKONSEND and
M_SENDCONFIG. A library function, SetMessageMask, makes it
easy to set this mask. Here is an example from FvwmBacker.c:
SetMessageMask(Fvwm_fd,M_NEW_DESK|M_CONFIG_INFO|M_END_CONFIG_INFO);
This mask is used to reduce the amount of communication
between fvwm and its modules so that a module only gets the messages it
needs.
Synchronous vs. Asynchronous Operation
A module normally runs asynchrously with fvwm2. For example FvwmPager
may be updating its display to show a window being iconified while fvwm2
may have already iconfied and de-iconified the window. This is usually
desirable.
Other modules might need to synchronize their processing with fvwm.
If this is the case, a module will include in its message mask
"M_LOCKONSEND". When this mask bit is on, every message sent to the
module from fvwm must be answered with an "UNLOCK" message.
FvwmAnimate is (was?) the first module to implement this and should be
used as a reference implementation. Note that FvwmAnimate sends the command
"UNLOCK 1". The "1" is currently ignored but may be used in the future.
This whole facility comes from Afterstep, and we are just tracking what they
have done. The Afterstep documentation doesn't seem to say, but most
likely this is the time in seconds that fvwm should wait for the module
to respond with "UNLOCK" before it proceeds without the module's response.