xenocara/app/fvwm/modules/FvwmSaveDesk/FvwmSaveDesk.c

472 lines
11 KiB
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 <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);
}