summaryrefslogtreecommitdiff
path: root/app/fvwm/modules/FvwmSaveDesk/FvwmSaveDesk.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/fvwm/modules/FvwmSaveDesk/FvwmSaveDesk.c')
-rw-r--r--app/fvwm/modules/FvwmSaveDesk/FvwmSaveDesk.c471
1 files changed, 471 insertions, 0 deletions
diff --git a/app/fvwm/modules/FvwmSaveDesk/FvwmSaveDesk.c b/app/fvwm/modules/FvwmSaveDesk/FvwmSaveDesk.c
new file mode 100644
index 000000000..23781b36f
--- /dev/null
+++ b/app/fvwm/modules/FvwmSaveDesk/FvwmSaveDesk.c
@@ -0,0 +1,471 @@
+/* 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 <pp@solace.mh.se>
+ *
+ * The concept to write an function definition instead of an new.xinitrc
+ * is from Carsten Paeth <calle@calle.in-berlin.de>
+ *
+ * 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.
+ *
+ */
+
+#define TRUE 1
+#define FALSE 0
+
+#include "config.h"
+
+#include <stdio.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xproto.h>
+#include <X11/Xatom.h>
+#include <X11/Intrinsic.h>
+
+#include "../../fvwm/module.h"
+
+#include "FvwmSaveDesk.h"
+
+char *MyName;
+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 *temp, *s;
+ char *display_name = NULL;
+
+ /* Record the program name for error messages */
+ temp = argv[0];
+
+ s=strrchr(argv[0], '/');
+ if (s != NULL)
+ temp = s + 1;
+
+ MyName = safemalloc(strlen(temp)+2);
+ strcpy(MyName,"*");
+ strcat(MyName, temp);
+
+ if((argc != 6)&&(argc != 7))
+ {
+ fprintf(stderr,"%s Version %s should only be executed by fvwm!\n",MyName,
+ VERSION);
+ exit(1);
+ }
+
+ /* Open the X display */
+ if (!(dpy = XOpenDisplay(display_name)))
+ {
+ fprintf(stderr,"%s: can't open display %s", MyName,
+ 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] = atoi(argv[1]);
+ fd[1] = atoi(argv[2]);
+
+ /* Create a list of all windows */
+ /* Request a list of all windows,
+ * wait for ConfigureWindow packets */
+ SendInfo(fd,"Send_WindowList",0);
+
+ Loop(fd);
+ return 0;
+}
+
+
+
+/***********************************************************************
+ *
+ * Procedure:
+ * Loop - wait for data to process
+ *
+ ***********************************************************************/
+void Loop(int *fd)
+{
+ unsigned long header[HEADER_SIZE], *body;
+ int count;
+
+ while(1)
+ {
+ /* read a packet */
+ if((count = ReadFvwmPacket(fd[1],header,&body)) > 0)
+ {
+ /* dispense with the new packet */
+ process_message(header[1],body);
+ free(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;
+
+ if(new_win == 0)
+ return;
+
+ t = (struct list *)safemalloc(sizeof(struct list));
+ t->id = new_win;
+ t->next = list_root;
+ t->frame_height = (int)body[6];
+ t->frame_width = (int)body[5];
+ t->base_width = (int)body[11];
+ t->base_height = (int)body[12];
+ t->width_inc = (int)body[13];
+ t->height_inc = (int)body[14];
+ t->frame_x = (int)body[3];
+ t->frame_y = (int)body[4];;
+ t->title_height = (int)body[9];;
+ t->boundary_width = (int)body[10];
+ t->flags = (unsigned long)body[8];
+ t->gravity = body[21];
+ t->desk = body[7];
+ 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
+ *
+ ***********************************************************************/
+void DeadPipe(int nonsense)
+{
+ exit(0);
+}
+
+
+/***********************************************************************
+ *
+ * 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;i<len;i++)
+ {
+ if(isspace(line[i]))
+ space = 1;
+ if(line[i]=='\"')
+ qoute = 1;
+ }
+ if(space == 1)
+ fprintf(out,"\"");
+ if(qoute == 0)
+ fprintf(out,"%s",line);
+ else
+ {
+ for(i=0;i<len;i++)
+ {
+ if(line[i]=='\"')
+ fprintf(out,"\\\"");
+ else
+ fprintf(out,"%c",line[i]);
+ }
+ }
+ if(space == 1)
+ fprintf(out,"\"");
+ fprintf(out," ");
+
+}
+
+void do_save_command(FILE *out, struct list *t, int *curdesk,
+ int emit_wait, int *isfirstline)
+{
+ char tname[200],loc[30];
+ char **command_list;
+ int dwidth,dheight,xtermline = 0;
+ int x1,x2,y1,y2,i,command_count;
+ long tVx, tVy;
+
+ tname[0]=0;
+
+ x1 = t->frame_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 ( t->flags & STICKY )
+ {
+ 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 ( t->flags & ICONIFIED )
+ fprintf(out, "-ic ");
+ xtermline = 1;
+ fflush ( out );
+ }
+ }
+ if ( command_count > 0 )
+ {
+ if ( xtermline == 0 )
+ {
+ if ( t->flags & ICONIFIED )
+ 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);
+
+}
+