Copy purify.fvwm2rc to /tmp - add instructions in README.
[fvwm.git] / modules / FvwmSaveDesk / FvwmSaveDesk.c
blob47b590af8ceba2365ade743e099caad5371bb58d
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 * The concept to write an function definition instead of an new.xinitrc
7 * is from Carsten Paeth <calle@calle.in-berlin.de>
9 * Copyright 1994, Robert Nation and Mr. Per Persson.
10 * No guarantees or warantees or anything
11 * are provided or implied in any way whatsoever. Use this program at your
12 * own risk. Permission to use this program for any purpose is given,
13 * as long as the copyright is kept intact.
15 * Copyright 1995, Carsten Paeth.
16 * No guarantees or warantees or anything
17 * are provided or implied in any way whatsoever. Use this program at your
18 * own risk. Permission to use this program for any purpose is given,
19 * as long as the copyright is kept intact.
23 /* This program is free software; you can redistribute it and/or modify
24 * it under the terms of the GNU General Public License as published by
25 * the Free Software Foundation; either version 2 of the License, or
26 * (at your option) any later version.
28 * This program is distributed in the hope that it will be useful,
29 * but WITHOUT ANY WARRANTY; without even the implied warranty of
30 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 * GNU General Public License for more details.
33 * You should have received a copy of the GNU General Public License
34 * along with this program; if not, write to the Free Software
35 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
38 #include "config.h"
40 #include <stdio.h>
41 #include <signal.h>
42 #include <fcntl.h>
43 #include <sys/wait.h>
44 #include "libs/ftime.h"
45 #include <unistd.h>
46 #include <ctype.h>
47 #include <X11/Xlib.h>
48 #include <X11/Xutil.h>
49 #include <X11/Xproto.h>
50 #include <X11/Xatom.h>
51 #include <X11/Intrinsic.h>
53 #include "libs/Module.h"
55 #include "FvwmSaveDesk.h"
57 static ModuleArgs *module;
58 int fd[2];
60 struct list *list_root = NULL;
62 Display *dpy; /* which display are we talking to */
63 int ScreenWidth, ScreenHeight;
64 int screen;
66 long Vx, Vy;
68 long CurDesk = 1; /* actual Desktop while being called */
72 * Procedure:
73 * main - start of module
76 int main(int argc, char **argv)
78 char *display_name = NULL;
80 module = ParseModuleArgs(argc,argv,0); /* no alias */
81 if (module == NULL)
83 fprintf(stderr,"FvwmSaveDesk Version %s should only be executed by fvwm!\n",
84 VERSION);
85 exit(1);
88 /* Open the X display */
89 if (!(dpy = XOpenDisplay(display_name)))
91 fprintf(stderr,"%s: can't open display %s", module->name,
92 XDisplayName(display_name));
93 exit (1);
95 screen= DefaultScreen(dpy);
96 ScreenHeight = DisplayHeight(dpy,screen);
97 ScreenWidth = DisplayWidth(dpy,screen);
99 /* We should exit if our fvwm pipes die */
100 signal (SIGPIPE, DeadPipe);
102 fd[0] = module->to_fvwm;
103 fd[1] = module->from_fvwm;
105 /* Create a list of all windows */
106 /* Request a list of all windows,
107 * wait for ConfigureWindow packets */
108 SendInfo(fd,"Send_WindowList",0);
110 /* tell fvwm we're running */
111 SendFinishedStartupNotification(fd);
113 Loop(fd);
114 return 0;
121 * Procedure:
122 * Loop - wait for data to process
125 void Loop(int *fd)
127 while(1) {
128 FvwmPacket* packet = ReadFvwmPacket(fd[1]);
129 if ( packet == NULL )
130 exit(0);
131 else
132 process_message( packet->type, packet->body );
139 * Procedure:
140 * Process message - examines packet types, and takes appropriate action
143 void process_message(unsigned long type,unsigned long *body)
145 switch(type)
147 case M_CONFIGURE_WINDOW:
148 if(!find_window(body[0]))
149 add_window(body[0],body);
150 break;
151 case M_WINDOW_NAME:
153 struct list *l;
154 if ((l = find_window(body[0])) != 0) {
155 l->name = (char *)safemalloc(strlen((char *)&body[3])+1);
156 strcpy(l->name,(char *)&body[3]);
159 break;
160 case M_NEW_PAGE:
161 list_new_page(body);
162 break;
163 case M_NEW_DESK:
164 CurDesk = (long)body[0];
165 break;
166 case M_END_WINDOWLIST:
167 do_save();
168 break;
169 default:
170 break;
178 * Procedure:
179 * find_window - find a window in the current window list
182 struct list *find_window(unsigned long id)
184 struct list *l;
186 if(list_root == NULL)
187 return NULL;
189 for(l = list_root; l!= NULL; l= l->next)
191 if(l->id == id)
192 return l;
194 return NULL;
201 * Procedure:
202 * add_window - add a new window in the current window list
205 void add_window(unsigned long new_win, unsigned long *body)
207 struct list *t;
208 struct ConfigWinPacket *cfgpacket = (void *)body;
210 if(new_win == 0)
211 return;
213 t = (struct list *)safemalloc(sizeof(struct list));
214 t->id = new_win;
215 t->next = list_root;
216 t->frame_height = cfgpacket->frame_height;
217 t->frame_width = cfgpacket->frame_width;
218 t->base_width = cfgpacket->hints_base_width;
219 t->base_height = cfgpacket->hints_base_height;
220 t->width_inc = cfgpacket->hints_width_inc;
221 t->height_inc = cfgpacket->hints_height_inc;
222 t->frame_x = cfgpacket->frame_x;
223 t->frame_y = cfgpacket->frame_y;
224 t->title_height = cfgpacket->title_height;
225 t->boundary_width = cfgpacket->border_width;
226 memcpy(&(t->flags), &(cfgpacket->flags), sizeof(t->flags));
227 t->gravity = cfgpacket->hints_win_gravity;
228 t->desk = cfgpacket->desk;
229 t->name = 0;
230 list_root = t;
237 * Procedure:
238 * list_new_page - capture new-page info
241 void list_new_page(unsigned long *body)
243 Vx = (long)body[0];
244 Vy = (long)body[1];
248 * Procedure:
249 * SIGPIPE handler - SIGPIPE means fvwm is dying
252 RETSIGTYPE DeadPipe(int nonsense)
254 exit(0);
255 SIGNAL_RETURN;
261 * Procedure:
262 * writes a command line argument to file "out"
263 * checks for qoutes and stuff
266 void write_string(FILE *out, char *line)
268 int len,space = 0, qoute = 0,i;
270 len = strlen(line);
272 for(i=0;i<len;i++)
274 if(isspace((unsigned char)line[i]))
275 space = 1;
276 if(line[i]=='\"')
277 qoute = 1;
279 if(space == 1)
280 fprintf(out,"\"");
281 if(qoute == 0)
282 fprintf(out,"%s",line);
283 else
285 for(i=0;i<len;i++)
287 if(line[i]=='\"')
288 fprintf(out,"\\\"");
289 else
290 fprintf(out,"%c",line[i]);
293 if(space == 1)
294 fprintf(out,"\"");
295 fprintf(out," ");
299 void do_save_command(FILE *out, struct list *t, int *curdesk,
300 int emit_wait, int *isfirstline)
302 char tname[200],loc[30];
303 char **command_list;
304 int dwidth,dheight,xtermline = 0;
305 int x1,x2,y1,y2,i,command_count;
306 long tVx, tVy;
308 tname[0]=0;
310 x1 = t->frame_x;
311 x2 = ScreenWidth - x1 - t->frame_width - 2;
312 if(x2 < 0)
313 x2 = 0;
314 y1 = t->frame_y;
315 y2 = ScreenHeight - y1 - t->frame_height - 2;
316 if(y2 < 0)
317 y2 = 0;
318 dheight = t->frame_height - t->title_height - 2*t->boundary_width;
319 dwidth = t->frame_width - 2*t->boundary_width;
320 dwidth -= t->base_width ;
321 dheight -= t->base_height ;
322 dwidth /= t->width_inc;
323 dheight /= t->height_inc;
325 if (IS_STICKY_ACROSS_PAGES(t))
327 tVx = 0;
328 tVy = 0;
330 else
332 tVx = Vx;
333 tVy = Vy;
335 sprintf(tname,"%dx%d",dwidth,dheight);
336 if ((t->gravity == EastGravity) ||
337 (t->gravity == NorthEastGravity) ||
338 (t->gravity == SouthEastGravity))
339 sprintf(loc,"-%d",x2);
340 else
341 sprintf(loc,"+%d",x1+(int)tVx);
342 strcat(tname, loc);
344 if((t->gravity == SouthGravity)||
345 (t->gravity == SouthEastGravity)||
346 (t->gravity == SouthWestGravity))
347 sprintf(loc,"-%d",y2);
348 else
349 sprintf(loc,"+%d",y1+(int)tVy);
350 strcat(tname, loc);
352 if ( XGetCommand( dpy, t->id, &command_list, &command_count ) )
354 if (*curdesk != t->desk)
356 fprintf( out, "%s\t\"I\" Desk 0 %ld\n", *isfirstline ? "" : "+",
357 t->desk);
358 fflush ( out );
359 if (*isfirstline) *isfirstline = 0;
360 *curdesk = t->desk;
363 fprintf( out, "%s\t\t\"I\" Exec ", *isfirstline ? "" : "+");
364 if (*isfirstline) *isfirstline = 0;
365 fflush ( out );
366 for (i=0; i < command_count; i++)
368 if ( strncmp( "-geo", command_list[i], 4) == 0)
370 i++;
371 continue;
373 if ( strncmp( "-ic", command_list[i], 3) == 0)
374 continue;
375 if ( strncmp( "-display", command_list[i], 8) == 0)
377 i++;
378 continue;
380 write_string(out,command_list[i]);
381 fflush ( out );
382 if(strstr(command_list[i], "xterm"))
384 fprintf( out, "-geometry %s ", tname );
385 if (IS_ICONIFIED(t))
386 fprintf(out, "-ic ");
387 xtermline = 1;
388 fflush ( out );
391 if ( command_count > 0 )
393 if ( xtermline == 0 )
395 if (IS_ICONIFIED(t))
396 fprintf(out, "-ic ");
397 fprintf( out, "-geometry %s &\n", tname);
399 else
401 fprintf( out, "&\n");
404 if (emit_wait) {
405 if (t->name)
406 fprintf( out, "+\t\t\"I\" Wait %s\n", t->name);
407 else fprintf( out, "+\t\t\"I\" Wait %s\n", command_list[0]);
408 fflush( out );
410 XFreeStringList( command_list );
411 xtermline = 0;
418 * Procedure:
419 * checks to see if we are supposed to take some action now,
420 * finds time for next action to be performed.
423 void do_save(void)
425 struct list *t;
426 char fnbuf[200];
427 FILE *out;
428 int maxdesk = 0;
429 int actdesk = -1;
430 int curdesk;
431 int isfirstline = 1;
433 for (t = list_root; t != NULL; t = t->next)
434 if (t->desk > maxdesk)
435 maxdesk = t->desk;
437 sprintf(fnbuf, "%s/.fvwm2desk", getenv( "HOME" ) );
438 out = fopen( fnbuf, "w" );
440 fprintf( out, "AddToFunc InitFunction");
441 fflush ( out );
444 * Generate all Desks except 'CurDesk'
446 for (curdesk = 0; curdesk <= maxdesk; curdesk++)
448 for (t = list_root; t != NULL; t = t->next)
450 if (t->desk != CurDesk && curdesk == t->desk)
451 do_save_command(out, t, &actdesk, 1, &isfirstline);
455 * Generate 'CurDesk'
457 for (t = list_root; t != NULL; t = t->next)
459 if (t->desk == CurDesk)
460 do_save_command(out, t, &actdesk, 0, &isfirstline);
463 if (actdesk != CurDesk)
464 fprintf( out, "+\t\"I\" Desk 0 %ld\n", CurDesk);
466 fflush( out );
467 fclose( out );
468 exit(0);