/* -*-c-*- */
/* Copyright (C) 2002 the late Joey Shutup.
*
* http://www.streetmap.co.uk/streetmap.dll?postcode2map?BS24+9TZ
*
* No guarantees or warranties or anything are provided or implied in any way
* whatsoever. Use this program at your own risk. Permission to use this
* program for any purpose is given, as long as the copyright is kept intact.
*/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "config.h"
#include <stdio.h>
#include <signal.h>
#include "libs/fvwmlib.h"
#include "libs/Module.h"
#include "libs/fvwmsignal.h"
#include "libs/Parse.h"
#include "libs/Strings.h"
/* Globals */
static ModuleArgs* module;
static int fd[2]; /* communication pipes */
/* forward declarations */
static RETSIGTYPE signal_handler(int signal);
static void set_signals(void);
static void parse_config(void);
static void parse_config_line(char *line);
static void parse_message_line(char *line);
static void main_loop(void) __attribute__((__noreturn__));
static void parse_colorset(char *line);
int main(int argc, char **argv)
{
module = ParseModuleArgs(argc,argv,0); /* no alias allowed */
if (module==NULL)
{
fprintf(stderr,
"FvwmTheme "VERSION" should only be executed by fvwm!\n"
);
exit(1);
}
fprintf(
stderr,
"%s is obsolete, see the Colorset section of the fvwm(1) man"
" page\n", module->name);
set_signals();
/* note the communication pipes */
fd[0] = module->to_fvwm;
fd[1] = module->from_fvwm;
/* get the initial configuration options */
parse_config();
/* tell fvwm we're running */
SendFinishedStartupNotification(fd);
/* sit around waiting for something to do */
main_loop();
}
static void main_loop(void)
{
FvwmPacket *packet;
fd_set_size_t fd_width;
fd_set in_fdset;
fd_width = fd[1] + 1;
FD_ZERO(&in_fdset);
while (True)
{
/* garbage collect */
alloca(0);
FD_SET(fd[1], &in_fdset);
/* wait for an instruction from fvwm or a timeout */
if (fvwmSelect(fd_width, &in_fdset, NULL, NULL, NULL) < 0)
{
fprintf(stderr, "%s: select error!\n", module->name);
exit(-1);
}
packet = ReadFvwmPacket(fd[1]);
if (!packet)
exit(0);
/* handle dynamic config lines and text messages */
switch (packet->type)
{
case M_CONFIG_INFO:
parse_config_line((char *)&packet->body[3]);
SendUnlockNotification(fd);
break;
case M_STRING:
parse_message_line((char *)&packet->body[3]);
SendUnlockNotification(fd);
break;
}
}
}
/* config options, the first NULL is replaced with *FvwmThemeColorset */
/* the second NULL is replaced with *FvwmThemeReadWriteColors */
/* FvwmTheme ignores any "colorset" lines since it causes them */
static char *config_options[] =
{
"ImagePath",
"ColorLimit",
NULL,
NULL,
NULL
};
static void parse_config_line(char *line)
{
char *rest;
switch(GetTokenIndex(line, config_options, -1, &rest))
{
case 0: /* ImagePath */
break;
case 1: /* ColorLimit */
break;
case 2: /* *FvwmThemColorset */
parse_colorset(rest);
break;
case 3: /* *FvwmThemeReadWriteColors */
SendText(fd, "ReadWriteColors", 0);
break;
}
}
/* translate a colorset spec into a colorset structure */
static void parse_colorset(char *line)
{
SendText(fd, CatString2("Colorset ", line), 0);
}
/* SendToModule options */
static char *message_options[] = {"Colorset", NULL};
static void parse_message_line(char *line)
{
char *rest;
switch(GetTokenIndex(line, message_options, -1, &rest))
{
case 0:
parse_colorset(rest);
break;
}
}
static void parse_config(void)
{
char *line;
/* prepare the tokenizer array, [0,1] are ImagePath and ColorLimit */
config_options[2] = safemalloc(module->namelen + 10);
sprintf(config_options[2], "*%sColorset", module->name);
config_options[3] = safemalloc(module->namelen + 17);
sprintf(config_options[3], "*%sReadWriteColors", module->name);
/* set a filter on the config lines sent */
line = safemalloc(module->namelen + 2);
sprintf(line, "*%s", module->name);
InitGetConfigLine(fd, line);
free(line);
/* tell fvwm what we want to receive */
SetMessageMask(fd, M_CONFIG_INFO | M_END_CONFIG_INFO | M_SENDCONFIG
| M_STRING);
/* loop on config lines, a bit strange looking because GetConfigLine
* is a void(), have to test $line */
while (GetConfigLine(fd, &line), line)
parse_config_line(line);
SetSyncMask(fd, M_CONFIG_INFO | M_STRING);
}
static void set_signals(void) {
#ifdef HAVE_SIGACTION
struct sigaction sigact;
sigemptyset(&sigact.sa_mask);
sigaddset(&sigact.sa_mask, SIGPIPE);
sigaddset(&sigact.sa_mask, SIGINT);
sigaddset(&sigact.sa_mask, SIGHUP);
sigaddset(&sigact.sa_mask, SIGTERM);
# ifdef SA_INTERRUPT
sigact.sa_flags = SA_INTERRUPT;
# else
sigact.sa_flags = 0;
# endif
sigact.sa_handler = signal_handler;
sigaction(SIGPIPE, &sigact, NULL);
sigaction(SIGINT, &sigact, NULL);
sigaction(SIGHUP, &sigact, NULL);
sigaction(SIGTERM, &sigact, NULL);
#else
/* We don't have sigaction(), so fall back to less robust methods. */
#ifdef USE_BSD_SIGNALS
fvwmSetSignalMask(sigmask(SIGPIPE)
| sigmask(SIGINT)
| sigmask(SIGHUP)
| sigmask(SIGTERM));
#endif
signal(SIGPIPE, signal_handler);
signal(SIGINT, signal_handler);
signal(SIGHUP, signal_handler);
signal(SIGTERM, signal_handler);
#ifdef HAVE_SIGINTERRUPT
siginterrupt(SIGPIPE, 1);
siginterrupt(SIGINT, 1);
siginterrupt(SIGHUP, 1);
siginterrupt(SIGTERM, 1);
#endif
#endif
}
static RETSIGTYPE signal_handler(int signal)
{
fprintf(stderr, "%s quiting on signal %d\n", module->name, signal);
exit(signal);
SIGNAL_RETURN;
}
syntax highlighted by Code2HTML, v. 0.9.1