/* -*-c-*- */ /* This module, and the entire FvwmSaveDesktop program, and the concept for * interfacing this module to the Window Manager, are all original work * by Robert Nation and Mr. Per Persson * * The concept to write an function definition instead of an new.xinitrc * is from Carsten Paeth * * Copyright 1994, Robert Nation and Mr. Per Persson. * 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. * * Copyright 1995, Carsten Paeth. * 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. * */ /* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include #include #include #include #include "libs/ftime.h" #include #include #include #include #include #include #include #include "libs/Module.h" #include "FvwmSaveDesk.h" static ModuleArgs *module; int fd[2]; struct list *list_root = NULL; Display *dpy; /* which display are we talking to */ int ScreenWidth, ScreenHeight; int screen; long Vx, Vy; long CurDesk = 1; /* actual Desktop while being called */ /* * * Procedure: * main - start of module * */ int main(int argc, char **argv) { char *display_name = NULL; module = ParseModuleArgs(argc,argv,0); /* no alias */ if (module == NULL) { fprintf(stderr,"FvwmSaveDesk Version %s should only be executed by fvwm!\n", VERSION); exit(1); } /* Open the X display */ if (!(dpy = XOpenDisplay(display_name))) { fprintf(stderr,"%s: can't open display %s", module->name, XDisplayName(display_name)); exit (1); } screen= DefaultScreen(dpy); ScreenHeight = DisplayHeight(dpy,screen); ScreenWidth = DisplayWidth(dpy,screen); /* We should exit if our fvwm pipes die */ signal (SIGPIPE, DeadPipe); fd[0] = module->to_fvwm; fd[1] = module->from_fvwm; /* Create a list of all windows */ /* Request a list of all windows, * wait for ConfigureWindow packets */ SendInfo(fd,"Send_WindowList",0); /* tell fvwm we're running */ SendFinishedStartupNotification(fd); Loop(fd); return 0; } /* * * Procedure: * Loop - wait for data to process * */ void Loop(int *fd) { while(1) { FvwmPacket* packet = ReadFvwmPacket(fd[1]); if ( packet == NULL ) exit(0); else process_message( packet->type, packet->body ); } } /* * * Procedure: * Process message - examines packet types, and takes appropriate action * */ void process_message(unsigned long type,unsigned long *body) { switch(type) { case M_CONFIGURE_WINDOW: if(!find_window(body[0])) add_window(body[0],body); break; case M_WINDOW_NAME: { struct list *l; if ((l = find_window(body[0])) != 0) { l->name = (char *)safemalloc(strlen((char *)&body[3])+1); strcpy(l->name,(char *)&body[3]); } } break; case M_NEW_PAGE: list_new_page(body); break; case M_NEW_DESK: CurDesk = (long)body[0]; break; case M_END_WINDOWLIST: do_save(); break; default: break; } } /* * * Procedure: * find_window - find a window in the current window list * */ struct list *find_window(unsigned long id) { struct list *l; if(list_root == NULL) return NULL; for(l = list_root; l!= NULL; l= l->next) { if(l->id == id) return l; } return NULL; } /* * * Procedure: * add_window - add a new window in the current window list * */ void add_window(unsigned long new_win, unsigned long *body) { struct list *t; struct ConfigWinPacket *cfgpacket = (void *)body; if(new_win == 0) return; t = (struct list *)safemalloc(sizeof(struct list)); t->id = new_win; t->next = list_root; t->frame_height = cfgpacket->frame_height; t->frame_width = cfgpacket->frame_width; t->base_width = cfgpacket->hints_base_width; t->base_height = cfgpacket->hints_base_height; t->width_inc = cfgpacket->hints_width_inc; t->height_inc = cfgpacket->hints_height_inc; t->frame_x = cfgpacket->frame_x; t->frame_y = cfgpacket->frame_y; t->title_height = cfgpacket->title_height; t->boundary_width = cfgpacket->border_width; memcpy(&(t->flags), &(cfgpacket->flags), sizeof(t->flags)); t->gravity = cfgpacket->hints_win_gravity; t->desk = cfgpacket->desk; t->name = 0; list_root = t; } /* * * Procedure: * list_new_page - capture new-page info * */ void list_new_page(unsigned long *body) { Vx = (long)body[0]; Vy = (long)body[1]; } /* * * Procedure: * SIGPIPE handler - SIGPIPE means fvwm is dying * */ RETSIGTYPE DeadPipe(int nonsense) { exit(0); SIGNAL_RETURN; } /* * * Procedure: * writes a command line argument to file "out" * checks for qoutes and stuff * */ void write_string(FILE *out, char *line) { int len,space = 0, qoute = 0,i; len = strlen(line); for(i=0;iframe_x; x2 = ScreenWidth - x1 - t->frame_width - 2; if(x2 < 0) x2 = 0; y1 = t->frame_y; y2 = ScreenHeight - y1 - t->frame_height - 2; if(y2 < 0) y2 = 0; dheight = t->frame_height - t->title_height - 2*t->boundary_width; dwidth = t->frame_width - 2*t->boundary_width; dwidth -= t->base_width ; dheight -= t->base_height ; dwidth /= t->width_inc; dheight /= t->height_inc; if (IS_STICKY_ACROSS_PAGES(t)) { tVx = 0; tVy = 0; } else { tVx = Vx; tVy = Vy; } sprintf(tname,"%dx%d",dwidth,dheight); if ((t->gravity == EastGravity) || (t->gravity == NorthEastGravity) || (t->gravity == SouthEastGravity)) sprintf(loc,"-%d",x2); else sprintf(loc,"+%d",x1+(int)tVx); strcat(tname, loc); if((t->gravity == SouthGravity)|| (t->gravity == SouthEastGravity)|| (t->gravity == SouthWestGravity)) sprintf(loc,"-%d",y2); else sprintf(loc,"+%d",y1+(int)tVy); strcat(tname, loc); if ( XGetCommand( dpy, t->id, &command_list, &command_count ) ) { if (*curdesk != t->desk) { fprintf( out, "%s\t\"I\" Desk 0 %ld\n", *isfirstline ? "" : "+", t->desk); fflush ( out ); if (*isfirstline) *isfirstline = 0; *curdesk = t->desk; } fprintf( out, "%s\t\t\"I\" Exec ", *isfirstline ? "" : "+"); if (*isfirstline) *isfirstline = 0; fflush ( out ); for (i=0; i < command_count; i++) { if ( strncmp( "-geo", command_list[i], 4) == 0) { i++; continue; } if ( strncmp( "-ic", command_list[i], 3) == 0) continue; if ( strncmp( "-display", command_list[i], 8) == 0) { i++; continue; } write_string(out,command_list[i]); fflush ( out ); if(strstr(command_list[i], "xterm")) { fprintf( out, "-geometry %s ", tname ); if (IS_ICONIFIED(t)) fprintf(out, "-ic "); xtermline = 1; fflush ( out ); } } if ( command_count > 0 ) { if ( xtermline == 0 ) { if (IS_ICONIFIED(t)) fprintf(out, "-ic "); fprintf( out, "-geometry %s &\n", tname); } else { fprintf( out, "&\n"); } } if (emit_wait) { if (t->name) fprintf( out, "+\t\t\"I\" Wait %s\n", t->name); else fprintf( out, "+\t\t\"I\" Wait %s\n", command_list[0]); fflush( out ); } XFreeStringList( command_list ); xtermline = 0; } } /* * * Procedure: * checks to see if we are supposed to take some action now, * finds time for next action to be performed. * */ void do_save(void) { struct list *t; char fnbuf[200]; FILE *out; int maxdesk = 0; int actdesk = -1; int curdesk; int isfirstline = 1; for (t = list_root; t != NULL; t = t->next) if (t->desk > maxdesk) maxdesk = t->desk; sprintf(fnbuf, "%s/.fvwm2desk", getenv( "HOME" ) ); out = fopen( fnbuf, "w" ); fprintf( out, "AddToFunc InitFunction"); fflush ( out ); /* * Generate all Desks except 'CurDesk' */ for (curdesk = 0; curdesk <= maxdesk; curdesk++) { for (t = list_root; t != NULL; t = t->next) { if (t->desk != CurDesk && curdesk == t->desk) do_save_command(out, t, &actdesk, 1, &isfirstline); } } /* * Generate 'CurDesk' */ for (t = list_root; t != NULL; t = t->next) { if (t->desk == CurDesk) do_save_command(out, t, &actdesk, 0, &isfirstline); } if (actdesk != CurDesk) fprintf( out, "+\t\"I\" Desk 0 %ld\n", CurDesk); fflush( out ); fclose( out ); exit(0); }