Copy purify.fvwm2rc to /tmp - add instructions in README.
[fvwm.git] / modules / FvwmSave / FvwmSave.c
blob866dbb9e771405017aee349f3c781b0571056f99
1 /* -*-c-*- */
2 /* This module, and the entire FvwmSaveDesktop program, and the concept for
3 * interfacing this module to the Window Manager, are all original work
4 * by Robert Nation and Mr. Per Persson <pp@solace.mh.se>
6 * Copyright 1994, Robert Nation and Mr. Per Persson.
7 * No guarantees or warantees or anything
8 * are provided or implied in any way whatsoever. Use this program at your
9 * own risk. Permission to use this program for any purpose is given,
10 * as long as the copyright is kept intact. */
12 /* This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #include "config.h"
29 #include <stdio.h>
30 #include <signal.h>
31 #include <fcntl.h>
32 #include <sys/wait.h>
33 #include "libs/ftime.h"
34 #include <unistd.h>
35 #include <ctype.h>
36 #include <X11/Xlib.h>
37 #include <X11/Xutil.h>
38 #include <X11/Xproto.h>
39 #include <X11/Xatom.h>
40 #include <X11/Intrinsic.h>
42 #include "libs/Module.h"
44 #include "FvwmSave.h"
46 static ModuleArgs *module;
47 int fd[2];
49 struct list *list_root = NULL;
51 Display *dpy; /* which display are we talking to */
52 int ScreenWidth, ScreenHeight;
53 int screen;
55 long Vx, Vy;
59 * Procedure:
60 * main - start of module
63 int main(int argc, char **argv)
65 char *display_name = NULL;
67 module = ParseModuleArgs(argc,argv,0); /* don't accept an alias */
68 if (module == NULL)
70 fprintf(stderr,"FvwmSave Version %s should only be executed by fvwm!\n",
71 VERSION);
72 exit(1);
75 /* Open the X display */
76 if (!(dpy = XOpenDisplay(display_name)))
78 fprintf(stderr,"%s: can't open display %s", module->name,
79 XDisplayName(display_name));
80 exit (1);
82 screen= DefaultScreen(dpy);
83 ScreenHeight = DisplayHeight(dpy,screen);
84 ScreenWidth = DisplayWidth(dpy,screen);
86 /* We should exit if our fvwm pipes die */
87 signal (SIGPIPE, DeadPipe);
89 fd[0] = module->to_fvwm;
90 fd[1] = module->from_fvwm;
92 /* Create a list of all windows */
93 /* Request a list of all windows,
94 * wait for ConfigureWindow packets */
95 SendInfo(fd,"Send_WindowList",0);
97 /* tell fvwm we're running */
98 SendFinishedStartupNotification(fd);
100 Loop(fd);
101 return 0;
107 * Procedure:
108 * Loop - wait for data to process
111 void Loop(int *fd)
113 while(1) {
114 FvwmPacket* packet = ReadFvwmPacket(fd[1]);
115 if ( packet == NULL )
116 exit(0);
117 else
118 process_message( packet->type, packet->body );
125 * Procedure:
126 * Process message - examines packet types, and takes appropriate action
129 void process_message(unsigned long type,unsigned long *body)
131 switch(type)
133 case M_CONFIGURE_WINDOW:
134 if(!find_window(body[0]))
135 add_window(body[0],body);
136 break;
137 case M_NEW_PAGE:
138 list_new_page(body);
139 break;
140 case M_END_WINDOWLIST:
141 do_save();
142 break;
143 default:
144 break;
154 * Procedure:
155 * find_window - find a window in the current window list
158 struct list *find_window(unsigned long id)
160 struct list *l;
162 if(list_root == NULL)
163 return NULL;
165 for(l = list_root; l!= NULL; l= l->next)
167 if(l->id == id)
168 return l;
170 return NULL;
177 * Procedure:
178 * add_window - add a new window in the current window list
181 void add_window(unsigned long new_win, unsigned long *body)
183 struct list *t;
184 struct ConfigWinPacket *cfgpacket = (void *)body;
186 if(new_win == 0)
187 return;
189 t = (struct list *)safemalloc(sizeof(struct list));
190 t->id = new_win;
191 t->next = list_root;
192 t->frame_height = cfgpacket->frame_height;
193 t->frame_width = cfgpacket->frame_width;
194 t->base_width = cfgpacket->hints_base_width;
195 t->base_height = cfgpacket->hints_base_height;
196 t->width_inc = cfgpacket->hints_width_inc;
197 t->height_inc = cfgpacket->hints_height_inc;
198 t->frame_x = cfgpacket->frame_x;
199 t->frame_y = cfgpacket->frame_y;
200 t->title_height = cfgpacket->title_height;
201 t->boundary_width = cfgpacket->border_width;
202 memcpy(&(t->flags), &(cfgpacket->flags), sizeof(t->flags));
203 t->gravity = cfgpacket->hints_win_gravity;
204 list_root = t;
211 * Procedure:
212 * list_new_page - capture new-page info
215 void list_new_page(unsigned long *body)
217 Vx = (long)body[0];
218 Vy = (long)body[1];
222 * Procedure:
223 * SIGPIPE handler - SIGPIPE means fvwm is dying
226 RETSIGTYPE DeadPipe(int nonsense)
228 exit(0);
229 SIGNAL_RETURN;
235 * Procedure:
236 * writes a command line argument to file "out"
237 * checks for qoutes and stuff
240 void write_string(FILE *out, char *line)
242 int len,space = 0, qoute = 0,i;
244 len = strlen(line);
246 for(i=0;i<len;i++)
248 if(isspace((unsigned char)(line[i])))
249 space = 1;
250 if(line[i]=='\"')
251 qoute = 1;
253 if(space == 1)
254 fprintf(out,"\"");
255 if(qoute == 0)
256 fprintf(out,"%s",line);
257 else
259 for(i=0;i<len;i++)
261 if(line[i]=='\"')
262 fprintf(out,"\\\"");
263 else
264 fprintf(out,"%c",line[i]);
267 if(space == 1)
268 fprintf(out,"\"");
269 fprintf(out," ");
277 * Procedure:
278 * checks to see if we are supposed to take some action now,
279 * finds time for next action to be performed.
282 void do_save(void)
284 struct list *t;
285 char tname[200],loc[30];
286 FILE *out;
287 char **command_list;
288 int dwidth,dheight,xtermline = 0;
289 int x1,x2,y1,y2,i,command_count;
290 long tVx, tVy;
292 sprintf(tname, "%s/new.xinitrc", getenv( "HOME" ) );
293 out = fopen( tname, "w+" );
294 for (t = list_root; t != NULL; t = t->next)
296 tname[0]=0;
298 x1 = t->frame_x;
299 x2 = ScreenWidth - x1 - t->frame_width - 2;
300 if(x2 < 0)
301 x2 = 0;
302 y1 = t->frame_y;
303 y2 = ScreenHeight - y1 - t->frame_height - 2;
304 if(y2 < 0)
305 y2 = 0;
306 dheight = t->frame_height - t->title_height - 2*t->boundary_width;
307 dwidth = t->frame_width - 2*t->boundary_width;
308 dwidth -= t->base_width ;
309 dheight -= t->base_height ;
310 dwidth /= t->width_inc;
311 dheight /= t->height_inc;
313 if (IS_STICKY_ACROSS_PAGES(t))
315 tVx = 0;
316 tVy = 0;
318 else
320 tVx = Vx;
321 tVy = Vy;
323 sprintf(tname,"%dx%d",dwidth,dheight);
324 if ((t->gravity == EastGravity) ||
325 (t->gravity == NorthEastGravity) ||
326 (t->gravity == SouthEastGravity))
327 sprintf(loc,"-%d",x2);
328 else
329 sprintf(loc,"+%d",x1+(int)tVx);
330 strcat(tname, loc);
332 if((t->gravity == SouthGravity)||
333 (t->gravity == SouthEastGravity)||
334 (t->gravity == SouthWestGravity))
335 sprintf(loc,"-%d",y2);
336 else
337 sprintf(loc,"+%d",y1+(int)tVy);
338 strcat(tname, loc);
340 if ( XGetCommand( dpy, t->id, &command_list, &command_count ) )
342 for (i=0; i < command_count; i++)
344 if ( strncmp( "-geo", command_list[i], 4) == 0)
346 i++;
347 continue;
349 if ( strncmp( "-ic", command_list[i], 3) == 0)
350 continue;
351 if ( strncmp( "-display", command_list[i], 8) == 0)
353 i++;
354 continue;
356 write_string(out,command_list[i]);
357 if(strstr(command_list[i], "xterm"))
359 fprintf( out, "-geometry %s ", tname );
360 if (IS_ICONIFIED(t))
361 fprintf(out, "-ic ");
362 xtermline = 1;
365 if ( command_count > 0 )
367 if ( xtermline == 0 )
369 if (IS_ICONIFIED(t))
370 fprintf(out, "-ic ");
371 fprintf( out, "-geometry %s &\n", tname );
373 else
375 fprintf( out, "&\n");
378 XFreeStringList( command_list );
379 xtermline = 0;
382 fprintf(out, "fvwm\n");
383 fclose( out );
384 exit(0);