#include "FvwmIconMan.h"
#include "../../fvwm/module.h"
static int fd_width;
static FILE *console = NULL;
static char *VERSION = "0.4";
#if !defined (__GNUC__) || defined (PRINT_DEBUG)
char *actionNames[] = {
"click1",
"click2",
"click3",
"select"
};
#endif
typedef enum {
READ_LINE = 1,
READ_OPTION = 2,
READ_ARG = 4,
READ_REST_OF_LINE = 12
} ReadOption;
void Free (void *p)
{
if (p != NULL)
free (p);
}
static int iswhite (char c)
{
if (c == ' ' || c == '\t' || c == '\0')
return 1;
return 0;
}
static void skip_space (char **p)
{
while (**p == ' ' || **p == '\t')
(*p)++;
}
#if FVWM_VERSION == 1
static FILE *config_fp = NULL;
#endif
static int init_config_file (char *file)
{
#if FVWM_VERSION == 1
if ((config_fp = fopen (file, "r")) == NULL) {
ConsoleMessage ("Couldn't open file: %s\n", file);
return 0;
}
#endif
return 1;
}
static void close_config_file (void)
{
#if FVWM_VERSION == 1
if (config_fp)
fclose (config_fp);
#endif
}
static int GetConfigLineWrapper (int *fd, char **tline)
{
#if FVWM_VERSION == 1
static char buffer[1024];
char *temp;
if (fgets (buffer, 1024, config_fp)) {
*tline = buffer;
temp = strchr (*tline, '\n');
if (temp) {
*temp = '\0';
}
else {
fprintf (stderr, "line too long\n");
exit (1);
}
return 1;
}
#else
char *temp;
GetConfigLine (fd, tline);
if (*tline) {
temp = strchr (*tline, '\n');
if (temp) {
*temp = '\0';
}
return 1;
}
#endif
return 0;
}
static char *read_next_cmd (ReadOption flag)
{
static ReadOption status;
static char *buffer;
static char *retstring, displaced, *cur_pos;
retstring = NULL;
if (flag != READ_LINE && !(flag & status))
return NULL;
switch (flag) {
case READ_LINE:
while (GetConfigLineWrapper (Fvwm_fd, &buffer)) {
cur_pos = buffer;
skip_space (&cur_pos);
if (!strncasecmp (Module, cur_pos, ModuleLen)) {
retstring = cur_pos;
cur_pos += ModuleLen;
displaced = *cur_pos;
if (displaced == '*')
status = READ_OPTION;
else if (displaced == '\0')
status = READ_LINE;
else if (iswhite (displaced))
status = READ_ARG;
else
status = READ_LINE;
break;
}
}
break;
case READ_OPTION:
*cur_pos = displaced;
retstring = ++cur_pos;
while (*cur_pos != '*' && !iswhite (*cur_pos))
cur_pos++;
displaced = *cur_pos;
*cur_pos = '\0';
if (displaced == '*')
status = READ_OPTION;
else if (displaced == '\0')
status = READ_LINE;
else if (iswhite (displaced))
status = READ_ARG;
else
status = READ_LINE;
break;
case READ_ARG:
*cur_pos = displaced;
skip_space (&cur_pos);
retstring = cur_pos;
while (!iswhite (*cur_pos))
cur_pos++;
displaced = *cur_pos;
*cur_pos = '\0';
if (displaced == '\0')
status = READ_LINE;
else if (iswhite (displaced))
status = READ_ARG;
else
status = READ_LINE;
break;
case READ_REST_OF_LINE:
status = READ_LINE;
*cur_pos = displaced;
skip_space (&cur_pos);
retstring = cur_pos;
break;
}
if (retstring && retstring[0] == '\0')
retstring = NULL;
return retstring;
}
int OpenConsole()
{
#ifdef PRINT_CONSOLE
if ((console=fopen("/dev/console","w"))==NULL) {
fprintf(stderr,"%s: cannot open console\n",Module);
return 0;
}
#endif
return 1;
}
void ShutMeDown (int flag)
{
ConsoleDebug ("Bye Bye\n");
exit (flag);
}
void ConsoleMessage(char *fmt, ...)
{
#ifdef PRINT_CONSOLE
va_list args;
FILE *filep;
if (console==NULL) filep=stderr;
else filep=console;
va_start(args,fmt);
vfprintf(filep,fmt,args);
va_end(args);
#endif
}
#if defined(PRINT_DEBUG) || !defined(__GNUC__)
void ConsoleDebug (char *fmt, ...) {
#ifdef PRINT_CONSOLE
#ifdef PRINT_DEBUG
va_list args;
FILE *filep;
if (console==NULL) filep=stderr;
else filep=console;
va_start(args,fmt);
vfprintf(filep,fmt,args);
va_end(args);
#endif
#endif
}
#endif
void DeadPipe (int nothing)
{
ConsoleDebug ("Bye Bye\n");
ShutMeDown (0);
}
void SendFvwmPipe (char *message,unsigned long window)
{
char *hold,*temp,*temp_msg;
hold=message;
while(1) {
temp=strchr(hold,',');
if (temp!=NULL) {
temp_msg= (char *)safemalloc(temp-hold+1);
strncpy(temp_msg,hold,(temp-hold));
temp_msg[(temp-hold)]='\0';
hold=temp+1;
} else temp_msg=hold;
SendText(Fvwm_fd, temp_msg, window);
if(temp_msg!=hold) free(temp_msg);
else break;
}
}
static void main_loop (void)
{
fd_set readset;
struct timeval tv;
while(1) {
FD_ZERO( &readset);
FD_SET (Fvwm_fd[1],&readset);
FD_SET (x_fd,&readset);
tv.tv_sec=0;
tv.tv_usec=0;
if (!select(fd_width,&readset,NULL,NULL,&tv)) {
FD_ZERO (&readset);
FD_SET (Fvwm_fd[1],&readset);
FD_SET (x_fd, &readset);
select(fd_width,&readset,NULL,NULL,NULL);
}
if (FD_ISSET (x_fd, &readset) || XPending (theDisplay)) {
xevent_loop();
}
if (FD_ISSET(Fvwm_fd[1],&readset)) {
ReadFvwmPipe();
}
}
}
static int extract_int (char *p, int *n)
{
char *s;
for (s = p; *s; s++) {
if (*s < '0' || *s > '9') {
return 0;
}
}
*n = atoi (p);
return 1;
}
char *copy_string (char **target, char *src)
{
int len = strlen (src);
if (*target)
Free (*target);
*target = (char *)safemalloc ((len + 1) * sizeof (char));
strcpy (*target, src);
return *target;
}
static char *conditional_copy_string (char **s1, char *s2)
{
if (*s1)
return *s1;
else
return copy_string (s1, s2);
}
#if __GNUC__ > 2
#define SET_MANAGER(manager,field,value) \
do { \
int id = manager; \
if (id == -1) { \
for (id = 0; id < globals.num_managers; id++) { \
globals.managers[id].field = value; \
} \
} \
else if (id < globals.num_managers) { \
globals.managers[id].field = value; \
} \
else { \
ConsoleMessage ("Internal error in SET_MANAGER: %d\n", id); \
} \
} while (0)
#else
#define SET_MANAGER(manager,field,value) \
do { \
int id = manager; \
if (id == -1) { \
for (id = 0; id < globals.num_managers; id++) { \
globals.managers[id].##field = value; \
} \
} \
else if (id < globals.num_managers) { \
globals.managers[id].##field = value; \
} \
else { \
ConsoleMessage ("Internal error in SET_MANAGER: %d\n", id); \
} \
} while (0)
#endif /* GCC 2 */
static void read_in_resources (char *file)
{
char *p, *q;
int i, n, manager;
char *option1;
Resolution r;
ButtonState state;
if (!init_config_file (file))
return;
while ((p = read_next_cmd (READ_LINE))) {
ConsoleDebug ("line: %s\n", p);
option1 = read_next_cmd (READ_OPTION);
if (option1 == NULL)
continue;
ConsoleDebug ("option1: %s\n", option1);
if (!strcasecmp (option1, "nummanagers")) {
p = read_next_cmd (READ_ARG);
if (!option1) {
ConsoleMessage ("Error in input file\n");
continue;
}
if (extract_int (p, &n) == 0) {
ConsoleMessage ("This is not a number: %s\n", p);
continue;
}
if (n > 0) {
allocate_managers (n);
ConsoleDebug ("num managers: %d\n", n);
}
else {
ConsoleMessage ("You can't have zero managers. I'll give you one.\n");
allocate_managers (1);
}
}
else {
/* these all can specify a specific manager */
if (globals.managers == NULL) {
ConsoleDebug ("I'm assuming you only want one manager\n");
allocate_managers (1);
}
manager = 0;
if (option1[0] >= '0' && option1[0] <= '9') {
if (extract_int (option1, &manager) == 0 ||
manager <= 0 || manager > globals.num_managers) {
ConsoleMessage ("This is not a valid manager: %s.\n", option1);
manager = 0;
}
option1 = read_next_cmd (READ_OPTION);
if (!option1) {
ConsoleMessage ("Error in input file\n");
continue;
}
}
manager--; /* -1 means global */
ConsoleDebug ("Applying %s to manager %d\n", option1, manager);
if (!strcasecmp (option1, "resolution")) {
p = read_next_cmd (READ_ARG);
if (!p) {
ConsoleMessage ("Error in input file\n");
continue;
}
ConsoleDebug ("resolution: %s\n", p);
if (!strcasecmp (p, "global"))
r = SHOW_GLOBAL;
else if (!strcasecmp (p, "desk"))
r = SHOW_DESKTOP;
else if (!strcasecmp (p, "page"))
r = SHOW_PAGE;
SET_MANAGER (manager, res, r);
}
else if (!strcasecmp (option1, "font")) {
p = read_next_cmd (READ_ARG);
if (!p) {
ConsoleMessage ("Error in input file\n");
continue;
}
ConsoleDebug ("font: %s\n", p);
SET_MANAGER (manager, fontname,
copy_string (&globals.managers[id].fontname, p));
}
else if (!strcasecmp (option1, "geometry")) {
p = read_next_cmd (READ_ARG);
if (!p) {
ConsoleMessage ("Error in input file\n");
continue;
}
SET_MANAGER (manager, geometry,
copy_string (&globals.managers[id].geometry, p));
}
else if (!strcasecmp (option1, "dontshow")) {
p = read_next_cmd (READ_ARG);
if (!p) {
ConsoleMessage ("Error in input_file\n");
continue;
}
do {
ConsoleDebug ("dont show: %s\n", p);
if (manager == -1) {
int i;
for (i = 0; i < globals.num_managers; i++)
add_to_stringlist (&globals.managers[i].dontshow, p);
}
else {
add_to_stringlist (&globals.managers[manager].dontshow, p);
}
p = read_next_cmd (READ_ARG);
} while (p);
}
else if (!strcasecmp (option1, "show")) {
p = read_next_cmd (READ_ARG);
if (!p) {
ConsoleMessage ("Error in input_file\n");
continue;
}
do {
ConsoleDebug ("show: %s\n", p);
if (manager == -1) {
int i;
for (i = 0; i < globals.num_managers; i++)
add_to_stringlist (&globals.managers[i].show, p);
}
else {
add_to_stringlist (&globals.managers[manager].show, p);
}
p = read_next_cmd (READ_ARG);
} while (p);
}
else if (!strcasecmp (option1, "background")) {
p = read_next_cmd (READ_ARG);
if (!p) {
ConsoleMessage ("Error in input file\n");
continue;
}
ConsoleDebug ("default background: %s\n", p);
for ( i = 0; i < NUM_CONTEXTS; i++ )
SET_MANAGER (manager, backColorName[i],
conditional_copy_string (&globals.managers[id].backColorName[i],
p));
}
else if (!strcasecmp (option1, "foreground")) {
p = read_next_cmd (READ_ARG);
if (!p) {
ConsoleMessage ("Error in input file\n");
continue;
}
ConsoleDebug ("default foreground: %s\n", p);
for ( i = 0; i < NUM_CONTEXTS; i++ )
SET_MANAGER (manager, foreColorName[i],
conditional_copy_string (&globals.managers[id].foreColorName[i],
p));
}
else if (!strcasecmp (option1, "action")) {
p = read_next_cmd (READ_ARG);
if (!p) {
ConsoleMessage ("Error in input file: need arguments to action\n");
continue;
}
if (!strcasecmp (p, "click1")) {
i = CLICK1;
}
else if (!strcasecmp (p, "click2")) {
i = CLICK2;
}
else if (!strcasecmp (p, "click3")) {
i = CLICK3;
}
else if (!strcasecmp (p, "select")) {
i = SELECT;
}
else {
ConsoleMessage ("Error in input file: this isn't a valid action name: %s\n", p);
continue;
}
q = read_next_cmd (READ_REST_OF_LINE);
if (!q) {
ConsoleMessage ("Error in input file: need an action\n");
continue;
}
ConsoleDebug ("Setting action for %s: %s\n", actionNames[i], q);
SET_MANAGER (manager, actions[i],
copy_string (&globals.managers[id].actions[i], q));
}
else if (!strcasecmp (option1, "showtitle")) {
p = read_next_cmd (READ_ARG);
if (!p) {
ConsoleMessage ("Error in input file: need argument to showtitle\n");
continue;
}
if (!strcasecmp (p, "true")) {
i = 1;
}
else if (!strcasecmp (p, "false")) {
i = 0;
}
else {
ConsoleMessage ("Error in input file. What is this: %s?\n", p);
continue;
}
ConsoleDebug ("Setting showtitle to: %d\n", i);
SET_MANAGER (manager, use_titlename, i);
}
else if (!strcasecmp (option1, "plainButton") ||
!strcasecmp (option1, "selectButton") ||
!strcasecmp (option1, "focusButton") ||
!strcasecmp (option1, "focusandselectButton")) {
if ( !strcasecmp (option1, "plainButton") )
i = PLAIN_CONTEXT;
else if ( !strcasecmp (option1, "selectButton") )
i = SELECT_CONTEXT;
else if (!strcasecmp (option1, "focusandselectButton"))
i = FOCUS_SELECT_CONTEXT;
else
i = FOCUS_CONTEXT;
p = read_next_cmd (READ_ARG);
if (!p) {
ConsoleMessage ("Error in input file: need argument to %s\n",
option1);
continue;
}
else if (!strcasecmp (p, "flat")) {
state = BUTTON_FLAT;
}
else if (!strcasecmp (p, "up")) {
state = BUTTON_UP;
}
else if (!strcasecmp (p, "down")) {
state = BUTTON_DOWN;
}
else {
ConsoleMessage ("Error in input file: this isn't a valid button state: %s\n", p);
continue;
}
ConsoleDebug ("Setting buttonState[%s] to %s\n",
contextDefaults[i].name, p);
SET_MANAGER (manager, buttonState[i], state);
/* check for optional fore color */
p = read_next_cmd (READ_ARG);
if ( !p )
continue;
ConsoleDebug ("Setting foreColorName[%s] to %s\n",
contextDefaults[i].name, p);
SET_MANAGER (manager, foreColorName[i],
copy_string (&globals.managers[id].foreColorName[i], p));
/* check for optional back color */
p = read_next_cmd (READ_ARG);
if ( !p )
continue;
ConsoleDebug ("Setting backColorName[%s] to %s\n",
contextDefaults[i].name, p);
SET_MANAGER (manager, backColorName[i],
copy_string (&globals.managers[id].backColorName[i], p));
}
else if (!strcasecmp (option1, "followfocus")) {
p = read_next_cmd (READ_ARG);
if (!p) {
ConsoleMessage ("Error in input file: need argument to followfocus\n");
continue;
}
if (!strcasecmp (p, "true")) {
i = 1;
}
else if (!strcasecmp (p, "false")) {
i = 0;
}
else {
ConsoleMessage ("Error in input file. What is this: %s?\n", p);
continue;
}
ConsoleDebug ("Setting followfocus to: %d\n", i);
SET_MANAGER (manager, followFocus, i);
}
else if (!strcasecmp (option1, "sort")) {
p = read_next_cmd (READ_ARG);
if (!p) {
ConsoleMessage ("Error in input file: need argument to sort\n");
continue;
}
if (!strcasecmp (p, "true")) {
i = 1;
}
else if (!strcasecmp (p, "false")) {
i = 0;
}
else {
ConsoleMessage ("Error in input file. What is this: %s?\n", p);
continue;
}
ConsoleDebug ("Setting sort to: %d\n", i);
SET_MANAGER (manager, sort, i);
}
else {
ConsoleMessage ("Unknown option: %s\n", p);
}
}
}
if (globals.managers == NULL) {
ConsoleDebug ("I'm assuming you only want one manager\n");
allocate_managers (1);
}
print_managers();
close_config_file();
}
int main (int argc, char **argv)
{
char *temp, *s;
FvwmPacketBody temppacket;
if ((char *)&temppacket.add_config_data.window_gravity -
(char *)&temppacket != 21 * sizeof (long)) {
fprintf (stderr, "Bad packet structure. Can't run. Sorry\n");
exit (1);
}
OpenConsole();
init_globals();
init_winlists();
temp = argv[0];
s = strrchr (argv[0], '/');
if (s != NULL)
temp = s + 1;
if((argc != 6) && (argc != 7)) {
fprintf(stderr,"%s Version %s should only be executed by fvwm!\n",Module,
VERSION);
ShutMeDown (1);
}
Fvwm_fd[0] = atoi(argv[1]);
Fvwm_fd[1] = atoi(argv[2]);
init_display();
init_boxes();
signal (SIGPIPE, DeadPipe);
read_in_resources (argv[3]);
assert (globals.managers);
fd_width = sysconf(_SC_OPEN_MAX);
SetMessageMask(Fvwm_fd,M_CONFIGURE_WINDOW | M_RES_CLASS | M_RES_NAME |
M_ADD_WINDOW | M_DESTROY_WINDOW | M_ICON_NAME |
M_DEICONIFY | M_ICONIFY | M_END_WINDOWLIST |
M_NEW_DESK | M_NEW_PAGE | M_FOCUS_CHANGE | M_WINDOW_NAME);
SendInfo (Fvwm_fd, "Send_WindowList", 0);
main_loop();
ConsoleMessage ("Shouldn't be here\n");
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1