/* FvwmBacker Module for Fvwm. * * Copyright 1994, Mike Finger (mfinger@mermaid.micro.umn.edu or * Mike_Finger@atk.com) * * The author makes not guarantees or warantees, either express or * implied. Feel free to use any contained here for any purpose, as long * and this and any other applicible copyrights are kept intact. * The functions in this source file that are based on part of the FvwmIdent * module for Fvwm are noted by a small copyright atop that function, all others * are copyrighted by Mike Finger. For those functions modified/used, here is * the full, origonal copyright: * * Copyright 1994, Robert Nation and Nobutaka Suzuki. * No guarantees or warantees 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. */ /* Modified to directly manipulate the X server if a solid color * background is requested. To use this, usr "-solid " * as the command to be executed. * * A. Davison * Septmber 1994. */ #include "config.h" #include #include #include #include #include #include #ifdef HAVE_SYS_SELECT_H #include #endif #include #include #ifdef HAVE_SYS_BSDTYPES_H #include /* Saul */ #endif /* Saul */ #include #include "../../fvwm/module.h" #include "FvwmBacker.h" #include "Mallocs.h" #include unsigned long GetColor(char *color); typedef struct { int type; /* The command type. * -1 = no command. * 0 = command to be spawned * 1 = a solid color to be set */ char* cmdStr; /* The command string (Type 0) */ unsigned long solidColor; /* A solid color after X parsing (Type 1) */ } Command; Command *commands; int DeskCount=0; int Fvwm_fd[2]; int fd_width; char *Module; /* X Display information. */ Display* dpy; Window root; int screen; FILE* logFile; /* Comment this out if you don't want a logfile. */ /* #define LOGFILE "/tmp/FvwmBacker.log"*/ int main(int argc, char **argv) { char *temp, *s; char* displayName = NULL; commands=NULL; /* Save the program name for error messages and config parsing */ temp = argv[0]; s=strrchr(argv[0], '/'); if (s != NULL) temp = s + 1; Module=temp; if((argc != 6)&&(argc != 7)) { fprintf(stderr,"%s Version %s should only be executed by fvwm!\n",Module, VERSION); exit(1); } Fvwm_fd[0] = atoi(argv[1]); Fvwm_fd[1] = atoi(argv[2]); /* Grab the X display information now. */ dpy = XOpenDisplay(displayName); if (!dpy) { fprintf(stderr, "%s: unable to open display '%s'\n", Module, XDisplayName (displayName)); exit (2); } screen = DefaultScreen(dpy); root = RootWindow(dpy, screen); /* Open a log file if necessary */ # ifdef LOGFILE logFile = fopen(LOGFILE,"a"); fprintf(logFile,"Initialising FvwmBacker\n"); # endif signal (SIGPIPE, DeadPipe); /* Parse the config file */ ParseConfig(); fd_width = GetFdWidth(); SetMessageMask(Fvwm_fd,M_NEW_DESK|M_CONFIG_INFO|M_END_CONFIG_INFO); /* ** we really only want the current desk, and window list sends it */ SendInfo(Fvwm_fd,"Send_WindowList",0); /* Recieve all messages from Fvwm */ EndLessLoop(); /* Should never get here! */ return 1; } /****************************************************************************** EndLessLoop - Read until we get killed, blocking when can't read ******************************************************************************/ void EndLessLoop() { fd_set readset; struct timeval tv; while(1) { FD_ZERO(&readset); FD_SET(Fvwm_fd[1],&readset); tv.tv_sec=0; tv.tv_usec=0; if (!select(fd_width,SELECT_TYPE_ARG234 &readset,NULL,NULL,&tv)) { FD_ZERO(&readset); FD_SET(Fvwm_fd[1],&readset); select(fd_width,SELECT_TYPE_ARG234 &readset,NULL,NULL,NULL); } if (!FD_ISSET(Fvwm_fd[1],&readset)) continue; ReadFvwmPipe(); } } /****************************************************************************** ReadFvwmPipe - Read a single message from the pipe from Fvwm Originally Loop() from FvwmIdent: Copyright 1994, Robert Nation and Nobutaka Suzuki. ******************************************************************************/ void ReadFvwmPipe() { int count; unsigned long header[HEADER_SIZE],*body; body = NULL; if((count = ReadFvwmPacket(Fvwm_fd[1],header,&body)) > 0) { ProcessMessage(header[1],body); free(body); } } /****************************************************************************** ProcessMessage - Process the message coming from Fvwm Skeleton based on processmessage() from FvwmIdent: Copyright 1994, Robert Nation and Nobutaka Suzuki. ******************************************************************************/ void ProcessMessage(unsigned long type,unsigned long *body) { if (type==M_NEW_DESK) { if (body[0]>DeskCount || commands[body[0]].type == -1) { return; } #ifdef LOGFILE fprintf(logFile,"Desk: %d\n",body[0]); fprintf(logFile,"Command type: %d\n",commands[body[0]].type); if (commands[body[0]].type == 0) fprintf(logFile,"Command String: %s\n",commands[body[0]].cmdStr); else if (commands[body[0]].type == 1) fprintf(logFile,"Color Number: %d\n",commands[body[0]].solidColor); else if (commands[body[0]].type == -1) fprintf(logFile,"No Command\n"); else { fprintf(logFile,"Illegal command type !\n"); exit(1); } fflush(logFile); # endif if (commands[body[0]].type == 1) { /* Process a solid color request */ XSetWindowBackground(dpy, root, commands[body[0]].solidColor); XClearWindow(dpy, root); XFlush(dpy); /* XSetWindowBackground(dpy, root, commands[body[0]].solidColor); */ # ifdef LOGFILE fprintf(logFile,"Color set.\n"); fflush(logFile); # endif } else if(commands[body[0]].cmdStr != NULL) { #if 0 system(commands[body[0]].cmdStr); #else /* much more useful: */ SendFvwmPipe(commands[body[0]].cmdStr, (unsigned long)0); #endif } } } /****************************************************************************** SendFvwmPipe - Send a message back to fvwm Based on SendInfo() from FvwmIdent: Copyright 1994, Robert Nation and Nobutaka Suzuki. ******************************************************************************/ void SendFvwmPipe(char *message,unsigned long window) { int w; char *hold,*temp,*temp_msg; hold=message; while(1) { temp=strchr(hold,','); if (temp!=NULL) { temp_msg=malloc(temp-hold+1); strncpy(temp_msg,hold,(temp-hold)); temp_msg[(temp-hold)]='\0'; hold=temp+1; } else temp_msg=hold; write(Fvwm_fd[0],&window, sizeof(unsigned long)); w=strlen(temp_msg); write(Fvwm_fd[0],&w,sizeof(int)); write(Fvwm_fd[0],temp_msg,w); /* keep going */ w=1; write(Fvwm_fd[0],&w,sizeof(int)); if(temp_msg!=hold) free(temp_msg); else break; } } /*********************************************************************** Detected a broken pipe - time to exit Based on DeadPipe() from FvwmIdent: Copyright 1994, Robert Nation and Nobutaka Suzuki. **********************************************************************/ void DeadPipe(int nonsense) { exit(1); } /****************************************************************************** ParseConfig - Parse the configuration file fvwm to us to use Based on part of main() from FvwmIdent: Copyright 1994, Robert Nation and Nobutaka Suzuki. ******************************************************************************/ void ParseConfig() { char line2[40]; char *tline; sprintf(line2,"*%sDesk",Module); GetConfigLine(Fvwm_fd,&tline); while(tline != (char *)0) { if(strlen(tline)>1) { if(strncasecmp(tline,line2,strlen(line2))==0) AddCommand(&tline[strlen(line2)]); } GetConfigLine(Fvwm_fd,&tline); } } /****************************************************************************** AddCommand - Add a command to the correct spot on the dynamic array. ******************************************************************************/ void AddCommand(char *string) { char *temp; int num; temp=string; while(isspace(*temp)) temp++; num=atoi(temp); while(!isspace(*temp)) temp++; while(isspace(*temp)) temp++; if (DeskCount<1) { commands=(Command*)safemalloc((num+1)*sizeof(Command)); while(DeskCountDeskCount) { commands=(Command*)realloc(commands,(num+1)*sizeof(Command)); while(DeskCount