xenocara/app/fvwm/modules/FvwmBanner/FvwmBanner.c

378 lines
8.8 KiB
C

/***************************************************************************
* FvwmBanner
*
* Show Fvwm Banner
*
***************************************************************************/
#include "config.h"
#ifdef HAVE_SYS_BSDTYPES_H
#include <sys/bsdtypes.h> /* Saul */
#endif
#include <stdio.h>
#include <signal.h>
#include <fcntl.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/time.h>
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#include <unistd.h>
#include <ctype.h>
#include <stdlib.h>
#include <X11/StringDefs.h>
#include <X11/Intrinsic.h>
#include <X11/Shell.h>
#include <X11/extensions/shape.h>
#include <X11/xpm.h>
#include "../../libs/fvwmlib.h"
#include "../../icons/fvwm2_big.xpm"
#if 0
#include "../../icons/k2.xpm"
#endif /* 0 */
typedef struct _XpmIcon {
Pixmap pixmap;
Pixmap mask;
XpmAttributes attributes;
} XpmIcon;
/**************************************************************************
* A few function prototypes
**************************************************************************/
void RedrawWindow(void);
void GetXPMData(char **);
void GetXPMFile(char *,char *);
void change_window_name(char *str);
int flush_expose (Window w);
static void parseOptions (int fd[2]);
XpmIcon view;
Window win;
char *pixmapPath = NULL;
char *pixmapName = NULL;
char *myName = NULL;
int timeout = 3000000; /* default time of 3 seconds */
Display *dpy; /* which display are we talking to */
Window Root;
int screen;
int x_fd;
int d_depth;
int ScreenWidth, ScreenHeight;
XSizeHints mysizehints;
Pixel back_pix, fore_pix;
GC NormalGC,FGC;
static Atom wm_del_win;
Colormap colormap;
#define MW_EVENTS (ExposureMask | ButtonReleaseMask)
/****************************************************************************
*
* Creates an icon window as needed
*
****************************************************************************/
int main(int argc, char **argv)
{
char *display_name = NULL, *string = NULL;
int retval = 0;
XEvent Event;
fd_set in_fdset;
int fd_width ;
struct timeval value;
int fd[2];
fd_width = GetFdWidth();
/* Save our program name - for error messages */
string = strrchr (argv[0], '/');
if (string != (char *) 0) string++;
myName = safemalloc (strlen (string) + 1);
strcpy (myName, string);
if(argc>=3)
{
/* sever our connection with fvwm, if we have one. */
fd[0] = atoi(argv[1]);
fd[1] = atoi(argv[2]);
#if 0
if(fd[0]>0)close(fd[0]);
if(fd[1]>0)close(fd[1]);
#endif /* 0 */
}
else
{
fprintf (stderr,
"%s version %s should only be executed by fvwm!\n",
myName,
VERSION);
exit(1);
}
if (argc > 6) {
pixmapName = safemalloc (strlen (argv[6]) + 1);
strcpy (pixmapName, argv[6]);
}
/* Open the display */
if (!(dpy = XOpenDisplay(display_name)))
{
fprintf(stderr,"FvwmBanner: can't open display %s",
XDisplayName(display_name));
exit (1);
}
screen= DefaultScreen(dpy);
Root = RootWindow(dpy, screen);
colormap = XDefaultColormap(dpy,screen);
d_depth = DefaultDepth(dpy, screen);
x_fd = XConnectionNumber(dpy);
ScreenHeight = DisplayHeight(dpy,screen);
ScreenWidth = DisplayWidth(dpy,screen);
parseOptions(fd);
/* Get the xpm banner */
if (pixmapName)
GetXPMFile(pixmapName,pixmapPath);
else
#if 0
if(d_depth > 4)
GetXPMData(k2_xpm);
else
#endif /* 0 */
GetXPMData(fvwm2_big_xpm);
/* Create a window to hold the banner */
mysizehints.flags=
USSize|USPosition|PWinGravity|PResizeInc|PBaseSize|PMinSize|PMaxSize;
/* subtract one for the right/bottom border */
mysizehints.width = view.attributes.width;
mysizehints.height=view.attributes.height;
mysizehints.width_inc = 1;
mysizehints.height_inc = 1;
mysizehints.base_height = mysizehints.height;
mysizehints.base_width = mysizehints.width;
mysizehints.min_height = mysizehints.height;
mysizehints.min_width = mysizehints.width;
mysizehints.max_height = mysizehints.height;
mysizehints.max_width = mysizehints.width;
mysizehints.win_gravity = NorthWestGravity;
mysizehints.x = (ScreenWidth - view.attributes.width)/2;
mysizehints.y = (ScreenHeight - view.attributes.height)/2;
win = XCreateSimpleWindow(dpy,Root,mysizehints.x,mysizehints.y,
mysizehints.width,mysizehints.height,
0,fore_pix ,None);
/* Set assorted info for the window */
XSetTransientForHint(dpy,win,Root);
wm_del_win = XInternAtom(dpy,"WM_DELETE_WINDOW",False);
XSetWMProtocols(dpy,win,&wm_del_win,1);
XSetWMNormalHints(dpy,win,&mysizehints);
change_window_name("FvwmBanner");
XSetWindowBackgroundPixmap(dpy,win,view.pixmap);
#ifdef SHAPE
if(view.mask != None)
XShapeCombineMask(dpy, win, ShapeBounding,0,0,view.mask, ShapeSet);
#endif
XMapWindow(dpy,win);
XSync(dpy,0);
#if 0
usleep(timeout);
#else
XSelectInput(dpy,win,ButtonReleaseMask);
/* Display the window */
value.tv_usec = timeout % 1000000;
value.tv_sec = timeout / 1000000;
while(1)
{
FD_ZERO(&in_fdset);
FD_SET(x_fd,&in_fdset);
if(!XPending(dpy))
retval=select(fd_width,SELECT_TYPE_ARG234 &in_fdset, 0, 0, &value);
if (retval==0)
{
XDestroyWindow(dpy,win);
XSync(dpy,0);
exit(0);
}
if(FD_ISSET(x_fd, &in_fdset))
{
/* read a packet */
XNextEvent(dpy,&Event);
switch(Event.type)
{
case ButtonRelease:
XDestroyWindow(dpy,win);
XSync(dpy,0);
exit(0);
case ClientMessage:
if (Event.xclient.format==32 && Event.xclient.data.l[0]==wm_del_win)
{
XDestroyWindow(dpy,win);
XSync(dpy,0);
exit(0);
}
default:
break;
}
}
}
#endif /* 0 */
return 0;
}
/****************************************************************************
*
* Looks for a color XPM icon file
*
****************************************************************************/
void GetXPMData(char **data)
{
view.attributes.valuemask = XpmReturnPixels| XpmCloseness | XpmExtensions;
view.attributes.closeness = 40000 /* Allow for "similar" colors */;
if(XpmCreatePixmapFromData(dpy, Root, data,
&view.pixmap, &view.mask,
&view.attributes)!=XpmSuccess)
{
fprintf(stderr,"FvwmBanner: ERROR couldn't convert data to pixmap\n");
exit(1);
}
}
void GetXPMFile(char *file, char *path)
{
char *full_file = NULL;
view.attributes.valuemask = XpmReturnPixels| XpmCloseness | XpmExtensions;
view.attributes.closeness = 40000 /* Allow for "similar" colors */;
if (file)
full_file = findIconFile(file,path,R_OK);
if (full_file)
{
if(XpmReadFileToPixmap(dpy,
Root,
full_file,
&view.pixmap,
&view.mask,
&view.attributes) == XpmSuccess)
{
return;
}
fprintf(stderr,"FvwmBanner: ERROR reading pixmap file\n");
}
else
fprintf(stderr,"FvwmBanner: ERROR finding pixmap file in PixmapPath\n");
GetXPMData(fvwm2_big_xpm);
}
void nocolor(char *a, char *b)
{
fprintf(stderr,"FvwmBanner: can't %s %s\n", a,b);
}
static void parseOptions (int fd[2])
{
char *tline= NULL;
int clength;
clength = strlen (myName);
while (GetConfigLine (fd, &tline),tline != NULL)
{
if (strlen (tline) > 1)
{
if (strncasecmp (tline,
CatString3 ("*", myName, "Pixmap"),
clength + 7) ==0)
{
if (pixmapName == (char *) 0)
{
CopyString (&pixmapName, &tline[clength+7]);
if (pixmapName[0] == 0)
{
free (pixmapName);
pixmapName = (char *) 0;
}
}
continue;
}
if (strncasecmp (tline,
CatString3 ("*", myName, "Timeout"),
clength + 8) ==0)
{
timeout = atoi(&tline[clength+8]) * 1000000;
continue;
}
if (strncasecmp(tline, "PixmapPath",10)==0)
{
CopyString (&pixmapPath, &tline[10]);
if (pixmapPath[0] == 0)
{
free (pixmapPath);
pixmapPath = (char *) 0;
}
continue;
}
}
}
return;
}
/**************************************************************************
* Change the window name displayed in the title bar.
**************************************************************************/
void change_window_name(char *str)
{
XTextProperty name;
if (XStringListToTextProperty(&str,1,&name) == 0)
{
fprintf(stderr,"FvwmBanner: cannot allocate window name");
return;
}
XSetWMName(dpy,win,&name);
XSetWMIconName(dpy,win,&name);
XFree(name.value);
}
/***********************************************************************
*
* Procedure:
* SIGPIPE handler - SIGPIPE means fvwm is dying
*
***********************************************************************/
/*ARGSUSED*/
void DeadPipe (int nonsense)
{
exit (0);
}