/* -*-c-*- */
/* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "config.h"
#ifdef HAVE_SYS_BSDTYPES_H
#include <sys/bsdtypes.h> /* Saul */
#endif
#include <stdio.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/wait.h>
#include "libs/ftime.h"
#include <sys/stat.h>
#include <unistd.h>
#include <ctype.h>
#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <X11/Xutil.h>
#include <X11/Xproto.h>
#include <X11/Xatom.h>
#include <X11/Intrinsic.h>
#include "libs/fvwmlib.h"
#include "libs/FShape.h"
#include "libs/Module.h"
#include "libs/Colorset.h"
#include "libs/PictureBase.h"
#include "libs/fvwmsignal.h"
#include "libs/FScreen.h"
#include "libs/FRenderInit.h"
#include "libs/ColorUtils.h"
#include "libs/Graphics.h"
#include "libs/Parse.h"
#include "libs/Strings.h"
#include "libs/System.h"
#include "fvwmDragWell.h"
#include "dragSource.h"
#define hostnameStrLen 64
extern DragSource dsg;
extern void xdndInit(Display *, Window);
extern void dragSourceInit(DragSource *,Display *,Window,Window);
void XStartup(char *appName);
void veryLongLoop(void);
char *shuffleDown(char **,short *,int,int);
int shrinkList(char **,short *,int,int);
int dilateList(char **,short *,int,int);
void changeWindowName(Window, char *);
void readHistory(void);
void writeHistory(void);
int dummy(DragWellButton *);
void createRootMenu(void);
void flushHistory(void);
void getReliefColors(void);
void createBackground(void);
void createWindow(void);
void parseOptions(void);
void parseFvwmMessage(char *msg);
int myXNextEvent(XEvent *event, char *fvwmMessage);
Atom xdndSrcDoDrag(DragSource *ds, Window srcWin, Atom action,
Atom * typelist);
void dragSrcInit(DragSource *ds,Display *dpy,Window root,Window client);
static RETSIGTYPE TerminateHandler(int);
int fd[2]; /*used for reading .fvwm2rc options*/
/*fd[0] module2fvwm*/
/*fd[1] fvwm2module*/
XGlobals xg; /*X related globals*/
DragWellMenuGlobals mg; /*menu related globals */
DragWellButton dragBut; /*not really used as a button but rather a drag well*/
char dropData[MAX_PATH_LEN]; /*data used for the drop*/
Bool Swallowed = False;
/* Don't know what this does yet...*/
void deadPipe(int nonsense)
{
/*writeHistory();*/
exit(0);
}
#ifdef DRAW_KILLBUTTON
/* drawX - draws an "x" on a button
* Dimension (w-8,h-8), roughly centered
* Arguments:
* but - the button to draw upon
*/
int drawX(DragWellButton *but)
{
/*upper left to bottom right*/
XDrawLine(xg.dpy, but->win, xg.antiReliefGC, but->wx+4, but->wy+4,
but->wx+but->w-4,but->wy+but->h-4);
/*bottom left to upper right*/
XDrawLine(xg.dpy, but->win, xg.antiReliefGC, but->wx+4, but->wy+but->h-5,
but->wx+but->w-5,but->wy+4);
}
#endif
int main(int argc, char **argv)
{
Window app_win;
fd[MODULE_TO_FVWM] = atoi (argv[1]); /*used to get info from .fvwm2rc*/
fd[FVWM_TO_MODULE] = atoi (argv[2]);
sscanf (argv[4], "%x", (unsigned int *)&app_win);
/*dsg.mfsErr = fopen("/tmp/mfsErr","w");*/
XStartup(argv[0]); /*initializes variables*/
veryLongLoop(); /*event loop*/
return 0;
}
/* initDragWellButton - initializes a DragWellButton
* Doesn't return anything useful
* Arguments:
* but - the button to be initialized
* win - the window the button is drawn on
* x,y - the upper left corner of the button, in (Window win) coords.
* drawFunc - a function pointer for drawing something on the button
*/
void initDragWellButton(DragWellButton *but,Window win, int x, int y, int w,
int h, int (*drawFunc)(DragWellButton *))
{
but->win = win;
but->wx = x;
but->wy = y;
but->w = w;
but->h = h;
but->state = DRAGWELL_BUTTON_NOT_PUSHED;
but->drawButFace = drawFunc;
}
/* drawDragWellButton - draws a DragWellButton
* Doesn't return anything meaningful
* Arguments:
* but - the button to be drawn
*/
void drawDragWellButton(DragWellButton *but)
{
(*(but->drawButFace))(but); /*draws face of button*/
if (but->state==DRAGWELL_BUTTON_NOT_PUSHED)
RelieveRectangle(xg.dpy, but->win, but->wx, but->wy, but->w - 1, but->h - 1,
xg.hiliteGC, xg.shadowGC, 2);
else
RelieveRectangle(xg.dpy, but->win, but->wx, but->wy, but->w - 1, but->h - 1,
xg.shadowGC, xg.hiliteGC, 2);
}
/* mouseInButton - returns true if the pointer is in a DragWellButton
* returns 1 if in button and 0 otherwise.
* Arguments:
* but - the button to be drawn
* x,y - the pointer coords in (DragWellButton->win) coords
*/
int mouseInButton(DragWellButton *but, int x, int y)
{
if ((but->wx <=x)&&(x<=(but->wx+but->w)))
if ((but->wy <=y)&&(y<=(but->wy+but->h)))
return 1;
return 0;
}
/*dragwellAnimate - does an animation in the dragwell
* Does not return anything useful */
void dragwellAnimate(void)
{
int i;
int sleepTime;
/*only one animation type for now*/
switch (xg.animationType) {
case DEFAULT_ANIMATION:
/*animate*/
if (dragBut.state == DRAGWELL_BUTTON_PUSHED)
XClearArea(xg.dpy,xg.win,xg.dbx+2,xg.dby+2,xg.dbw-2,xg.dbh-2,False);
else
XFillRectangle(
xg.dpy,xg.win,xg.buttonGC,xg.dbx+2,xg.dby+2,xg.dbw-2,xg.dbh-2);
/*This way, the animation time is constant regardless of size of
* box(assuming drawing is instantaneous...*/
sleepTime = TOTAL_ANIMATION_TIME/(xg.dbh-3);
for (i=xg.dby+xg.dbh-2;i>xg.dby;i--) {
if (dragBut.state == DRAGWELL_BUTTON_PUSHED)
XFillRectangle(
xg.dpy,xg.win,xg.buttonGC,xg.dbx+2,i,xg.dbw-3,xg.dby+xg.dbh-1-i);
else
XClearArea(xg.dpy,xg.win,xg.dbx+2,i,xg.dbw-3,xg.dby+xg.dbh-1-i,False);
XFlush(xg.dpy);
usleep(sleepTime);
}
drawDragWellButton(&dragBut);
break;
}
}
/* Main event loop*/
void veryLongLoop(void)
{
int x,y;
XEvent xev;
char fvwmMessage[512];
int eventType;
initDragWellButton(&dragBut,xg.win,xg.dbx,xg.dby,xg.dbw,xg.dbh,dummy);
dragBut.state = DRAGWELL_BUTTON_NOT_PUSHED;
drawDragWellButton(&dragBut);
while (!isTerminated)
{
/*get next event*/
if ((eventType=myXNextEvent (&xev,fvwmMessage))==FOUND_XEVENT)
{
/* we have a X event*/
switch(xev.type) {
case ButtonPress:
x = xev.xbutton.x;
y = xev.xbutton.y;
if (mg.dragState == DRAGWELLMENU_HAVE_DRAG_ITEM) {
if (mouseInButton(&dragBut,x,y)) {
if (mg.dragDataType==DRAG_DATA_TYPE_PATH)
mg.typelist[0] = mg.textUriAtom;
else
mg.typelist[0] = XInternAtom(xg.dpy,mg.dragTypeStr,False);
xdndSrcDoDrag(&dsg,xg.win,mg.action,mg.typelist);
}
}
break;
case ClientMessage:
/*close window option */
if ((xev.xclient.format==32) &&
(xev.xclient.data.l[0]==xg.wmAtomDelWin))
deadPipe(1);
break;
case Expose:
drawDragWellButton(&dragBut); /*draws the drag icon*/
break;
case ConfigureNotify:
if (xg.colorset >= 0 && Colorset[xg.colorset].pixmap == ParentRelative)
XClearArea(xg.dpy, xg.win, 0,0,0,0, True);
break;
}
} else if (eventType==FOUND_FVWM_MESSAGE) { /* we have an fvwm message */
/* two cases, one where item is a file, other where we have a subdir */
parseFvwmMessage(fvwmMessage);
dragwellAnimate();
} else {
/* no window*/
/* deadPipe(0);*/
}
}
}
/* parseFvwmMessage - decodes a SendToModule command.
* Arguments:
* msg - the fvwm message
* sets dragBut.state */
static char *dragopts[] = {
"DragType",
"DragData"
};
void parseFvwmMessage(char *msg)
{
char *dragtype = NULL, *dragData = NULL;
char *optString, *option, *args;
char hostname[hostnameStrLen];
/* parse line into comma separated pieces, set dragtype and dragdata */
while (msg && *msg) {
msg = GetQuotedString(msg, &optString, ",", NULL, NULL, NULL);
if (!optString)
break;
args = GetNextToken(optString, &option);
if (!option) {
free(optString);
break;
}
switch(GetTokenIndex(option, dragopts, 0, NULL))
{
case 0:
CopyString(&dragtype, args);
break;
case 1:
CopyString(&dragData, args);
break;
}
if (option) {
free(option);
option = NULL;
}
free(optString);
optString = NULL;
}
if (dragtype != NULL) {
strcpy(mg.dragTypeStr,dragtype);
mg.dragDataType = DRAG_DATA_TYPE_NONPATH;
} else {
mg.dragDataType = DRAG_DATA_TYPE_PATH;
strcpy(mg.dragTypeStr,"text/uri-list");
}
if (dragData == NULL || *dragData == 0) {
mg.dragState = DRAGWELLMENU_NO_DRAG_ITEM;
dragBut.state = DRAGWELL_BUTTON_NOT_PUSHED;
} else {
mg.dragState = DRAGWELLMENU_HAVE_DRAG_ITEM;
strcpy(mg.dragData, dragData);
dragBut.state = DRAGWELL_BUTTON_PUSHED;
}
/*setup a drag*/
if (mg.dragState == DRAGWELLMENU_HAVE_DRAG_ITEM) {
if (mg.dragDataType == DRAG_DATA_TYPE_PATH) {
strcpy(dropData, "file://");
gethostname(hostname, hostnameStrLen);
strcat(dropData, hostname);
strcat(dropData, mg.dragData);
} else {
strcpy(dropData, mg.dragData);
}
}
}
/*
* TerminateHandler - signal handler to make FvwmIconBox exit cleanly
*/
static RETSIGTYPE
TerminateHandler(int sig)
{
/*
* This function might not return - it could "long-jump"
* right out, so we need to do everything we need to do
* BEFORE we call it ...
*/
fvwmSetTerminate(sig);
SIGNAL_RETURN;
}
/* XStartup - sets up the X and menu state. Return value is meaningless.
* Arguments:
* appName - the name of the application.
*/
void XStartup(char *appName)
{
char *appNameStart;
/*setup exit stuff*/
#ifdef HAVE_SIGACTION
struct sigaction sigact;
#ifdef SA_INTERRUPT
sigact.sa_flags = SA_INTERRUPT;
#else
sigact.sa_flags = 0;
#endif
sigemptyset(&sigact.sa_mask);
sigaddset(&sigact.sa_mask, SIGPIPE);
sigaddset(&sigact.sa_mask, SIGTERM);
sigaddset(&sigact.sa_mask, SIGINT);
sigact.sa_handler = TerminateHandler;
sigaction(SIGPIPE, &sigact, NULL);
sigaction(SIGTERM, &sigact, NULL);
sigaction(SIGINT, &sigact, NULL);
#else
/*
* No sigaction, so fall back onto standard and unreliable signals
*/
#ifdef USE_BSD_SIGNALS
fvwmSetSignalMask( sigmask(SIGPIPE) | sigmask(SIGTERM) | sigmask(SIGINT) );
#endif
signal(SIGPIPE, TerminateHandler);
signal(SIGTERM, TerminateHandler);
signal(SIGINT, TerminateHandler);
#ifdef HAVE_SIGINTERRUPT
siginterrupt(SIGPIPE, 1);
siginterrupt(SIGTERM, 1);
siginterrupt(SIGINT, 1);
#endif
#endif
memset(&xg, 0, sizeof(xg));
if (!(xg.dpy = XOpenDisplay (NULL))) {
fprintf (stderr, "%s: can't open display %s",xg.appName,
XDisplayName (NULL));
exit (1);
}
/*xg.log = fopen("/home/straub/Work/C++/Xdnd/fvwm-snap-19990906/modules/FvwmDragWell/qfs.log","w");*/
/*Name the starting window name to the invocation name*/
appNameStart = strrchr(appName,'/')+1; /*remove the path from the name*/
if (appNameStart == NULL) {
appNameStart = appName;
}
xg.appName = (char *) malloc(sizeof(char) * (strlen(appNameStart)+1));
strcpy(xg.appName,appNameStart); /*save the name of the application*/
flib_init_graphics(xg.dpy);
/*get X stuff*/
xg.xfd = XConnectionNumber(xg.dpy);
xg.fdWidth = GetFdWidth();
xg.screen = DefaultScreen(xg.dpy);
xg.root = RootWindow(xg.dpy,xg.screen);
xg.dpyDepth = DefaultDepth(xg.dpy, xg.screen);
xg.dpyHeight = DisplayHeight(xg.dpy,xg.screen);
xg.dpyWidth = DisplayWidth(xg.dpy,xg.screen);
xg.dbx = 9;
xg.dby = 9;
xg.dbw = 30;
xg.dbh = 30;
xg.w = 48;
xg.h = 48;
/*Setup defaults*/
mg.exportAsURL = True;
mg.fontname = NULL;
xg.foreColorStr = NULL;
xg.backColorStr = NULL;
xg.shadowColorStr = NULL;
xg.hiliteColorStr = NULL;
xg.colorset = -1; /*no colorset*/
parseOptions(); /*overide defaults from .fvwm2rc*/
if (xg.foreColorStr==NULL)
CopyString(&xg.foreColorStr,"grey60");
if (xg.backColorStr==NULL)
CopyString(&xg.backColorStr,"black");
if (xg.shadowColorStr==NULL)
CopyString(&xg.shadowColorStr,"grey20");
if (xg.hiliteColorStr==NULL)
CopyString(&xg.hiliteColorStr,"grey90");
getReliefColors();
createWindow();
createBackground();
mg.dragState = DRAGWELLMENU_NO_DRAG_ITEM;
/*more initialization menu stuff, using font info*/
/*mg.fontHeight = mg.font->max_bounds.ascent + mg.font->max_bounds.descent;*/
xdndInit(xg.dpy, xg.root);
dragSrcInit(&dsg,xg.dpy,xg.root,xg.win);
mg.action = dsg.atomSel->xdndActionMove;
mg.textUriAtom = XInternAtom(xg.dpy,"text/uri-list",False);
mg.typelist = (Atom *) malloc(4*sizeof(Atom));
mg.typelist[1] = None;
mg.typelist[2] = None;
mg.typelist[3] = 0;
xg.animationType = DEFAULT_ANIMATION;
/* tell fvwm we're running */
SendFinishedStartupNotification(fd);
}
/*getReliefColors - sets up the colors for the dragwell
*Arguments:*/
void getReliefColors(void) {
if(xg.dpyDepth < 2) {
/*for mono display, not well implemented...*/
xg.fore = GetColor("white");
xg.back = GetColor("black");
xg.hilite = xg.fore;
xg.shadow = xg.back;
} else if (xg.colorset >=0) { /*using a colorset*/
xg.hilite = Colorset[xg.colorset].hilite;
xg.shadow = Colorset[xg.colorset].shadow;
xg.fore = Colorset[xg.colorset].fg;
xg.back = Colorset[xg.colorset].bg;
} else { /*no colorset*/
xg.fore = GetColor(xg.foreColorStr);
xg.back = GetColor(xg.backColorStr);
xg.shadow = GetColor(xg.shadowColorStr);
xg.hilite = GetColor(xg.hiliteColorStr);
}
}
/* createBackground - sets the background of the dragwell window
* Arguments:*/
void createBackground(void) {
unsigned long gcm;
XGCValues gcv;
/*Graphic context stuff*/
gcm = GCForeground|GCBackground|GCSubwindowMode;
gcv.subwindow_mode = IncludeInferiors;
gcv.foreground = xg.hilite;
gcv.background = xg.back;
xg.hiliteGC = fvwmlib_XCreateGC(xg.dpy, xg.win, gcm, &gcv);
gcv.foreground = xg.shadow;
gcv.background = xg.back;
xg.shadowGC = fvwmlib_XCreateGC(xg.dpy, xg.win, gcm, &gcv);
gcv.foreground = xg.fore;
gcv.background = xg.back;
xg.buttonGC = fvwmlib_XCreateGC(xg.dpy, xg.win, gcm, &gcv);
if (xg.colorset >=0) /*colorset*/
SetWindowBackground(xg.dpy, xg.win, xg.w, xg.h, &Colorset[xg.colorset],
Pdepth, xg.buttonGC, False);
else /*just use background pixel*/
XSetWindowBackground(xg.dpy, xg.win, xg.back);
}
/* parseOptions - loads in options from the .fvwm2rc file.
* Arguments: */
void parseOptions(void)
{
char *token,*next,*tline=NULL,*tline2,*resource;
char *arg1,*arg2;
/* loop that parses through the .fvwm2rc line by line.*/
for (GetConfigLine(fd,&tline); tline != NULL; GetConfigLine(fd,&tline)) {
tline2 = GetModuleResource(tline, &resource, xg.appName);
if (!resource) {/*not a xg.appName resource(*FvwmDragWell) resource*/
token = PeekToken(tline, &next);
if (StrEquals(token, "Colorset")) {
LoadColorset(next);
}
else if (StrEquals(token, XINERAMA_CONFIG_STRING)) {
FScreenConfigureModule(next);
}
continue;
}
tline2 = GetNextToken(tline2, &arg1);
if (!arg1)
{
arg1 = (char *)safemalloc(1);
arg1[0] = 0;
}
tline2 = GetNextToken(tline2, &arg2);
if (!arg2)
{
arg2 = (char *)safemalloc(1);
arg2[0] = 0;
}
if (StrEquals(resource, "ExportAsURL")) {
if (StrEquals(arg1,"True"))
mg.exportAsURL = True;
else
mg.exportAsURL = False;
} else if (StrEquals(resource, "Font")) {
CopyString(&mg.fontname,arg1);
} else if (StrEquals(resource, "Fore")) {
CopyString(&xg.foreColorStr,arg1);
} else if (StrEquals(resource, "Back")) {
CopyString(&xg.backColorStr,arg1);
} else if (StrEquals(resource, "Shadow")) {
CopyString(&xg.shadowColorStr,arg1);
} else if (StrEquals(resource, "Hilite")) {
CopyString(&xg.hiliteColorStr,arg1);
} else if (StrEquals(resource, "Colorset")) {
sscanf(arg1, "%d", &xg.colorset);
AllocColorset(xg.colorset);
} else if (StrEquals(resource, "Geometry")) {
int g_x,g_y,flags;
unsigned width,height;
xg.w = 48;
xg.h = 48;
xg.x = 0;
xg.y = 0;
xg.xneg = 0;
xg.yneg = 0;
xg.usposition = 0;
flags = FScreenParseGeometry(arg1,&g_x,&g_y,&width,&height);
if (flags & WidthValue) {
xg.w = width;
}
if (flags & HeightValue) {
xg.h= height;
}
if (flags & XValue) {
xg.x = g_x;
xg.usposition = 1;
}
if (flags & YValue) {
xg.y = g_y;
xg.usposition = 1;
}
if (flags & XNegative) {
xg.xneg = 1;
}
if (flags & YNegative) {
xg.yneg = 1;
}
} else if (StrEquals(resource, "DragWellGeometry")) {
int g_x,g_y,flags;
unsigned width,height;
xg.dbw = 30;
xg.dbh = 30;
xg.dbx = 9;
xg.dby = 9;
flags = FScreenParseGeometry(arg1,&g_x,&g_y,&width,&height);
if (flags & WidthValue) {
xg.dbw = width;
}
if (flags & HeightValue) {
xg.dbh= height;
}
if (flags & XValue) {
xg.dbx = g_x;
}
if (flags & YValue) {
xg.dby = g_y;
}
}
free(resource);
free(arg1);
free(arg2);
}
#ifdef USE_UNUSED
if (!mg.nw) {
/*Allocate font here because we need size information to create the main menu*/
if (mg.fontname==NULL) {
mg.fontname =
(char *) malloc(sizeof(char)*(strlen("-adobe-helvetica-bold-r-*-*-10-*-*-*-*-*-*-*")+1));
strcpy(mg.fontname,"-adobe-helvetica-bold-r-*-*-12-*-*-*-*-*-*-*");
}
mg.font = XLoadQueryFont(xg.dpy,mg.fontname);
if (mg.font == NULL) {
fprintf(stderr,"FvwmDragWell:No font located. Exiting\n");
exit(1);
}
}
#endif
}
/* changeWindowName - change the window name displayed in the title bar.
* Arguments:
* win - the window
* str - the new name of the window
*/
void changeWindowName(Window win, char *str)
{
XTextProperty name;
if (XStringListToTextProperty(&str,1,&name) == 0)
{
fprintf(stderr,"%s: cannot allocate window name",str);
return;
}
XSetWMName(xg.dpy,win,&name);
XSetWMIconName(xg.dpy,win,&name);
XFree(name.value);
}
/*change_colorset - changes the background of wharf
*Arguments:
* colorset - the new colorset */
static void change_colorset(int colorset)
{
if (colorset == xg.colorset && colorset >= 0)
{
/* update GCs */
XFreeGC(xg.dpy, xg.buttonGC);
XFreeGC(xg.dpy, xg.shadowGC);
XFreeGC(xg.dpy, xg.hiliteGC);
/* update background pixmap */
getReliefColors();
createBackground();
XClearWindow(xg.dpy,xg.win);
drawDragWellButton(&dragBut); /*draws the drag icon*/
}
XSync(xg.dpy, 0);
return;
}
/*
*
* myXNextEvent - waits for the next event, which is either an XEvent,
* or an fvwm event.
* Arguements:
* event - the XEvent that is possibly found.
* fvwmMessage - the FvwmMessage that is possibly found.
* Returns FOUND_XEVENT if a XEvent was found.
* Returns FOUND_FVWM_MESSAGE if a fvwm M_STRING packet was found.
* Returns FOUND_NON_FVWM_MESSAGE for any other fvwm packet type.
* Note that for fvwm packet type M_CONFIG(colorset), it updates the
* colorset
* Borrowed from FvwmPager
*/
int myXNextEvent(XEvent *event, char *fvwmMessage)
{
fd_set in_fdset;
static int miss_counter = 0;
char *msg, *tline, *token;
unsigned long *lptr;
int colorset;
if(FPending(xg.dpy)) /*look for an X event first*/
{
FNextEvent(xg.dpy,event); /*got an X event*/
return FOUND_XEVENT;
}
FD_ZERO(&in_fdset);
FD_SET(xg.xfd,&in_fdset); /*look for x events*/
FD_SET(fd[1],&in_fdset); /*look for fvwm events*/
if (select(xg.fdWidth,SELECT_FD_SET_CAST &in_fdset, 0, 0, NULL) > 0) /*wait */
{
if(FD_ISSET(xg.xfd, &in_fdset))
{
if(FPending(xg.dpy))
{
FNextEvent(xg.dpy,event); /*get an X event*/
miss_counter = 0;
return FOUND_XEVENT;
}
miss_counter++;
#ifdef WORRY_ABOUT_MISSED_XEVENTS
if(miss_counter > 100)
{
deadPipe(0);
}
#endif
}
if(FD_ISSET(fd[1], &in_fdset))
{
FvwmPacket* packet = ReadFvwmPacket(fd[1]);
/*packet format defined in libs/Module.h*/
if ( packet == NULL )
{
exit(0);
}
else
{
if (packet->type==M_CONFIG_INFO)
{
tline = (char*)&(packet->body[3]);
token = PeekToken(tline, &tline);
if (StrEquals(token, "Colorset"))
{
/*colorset packet*/
colorset = LoadColorset(tline);
change_colorset(colorset);
}
else if (StrEquals(token, XINERAMA_CONFIG_STRING))
{
FScreenConfigureModule(tline);
}
return FOUND_FVWM_NON_MESSAGE;
}
else if (packet->type==M_STRING)
{
if (packet->size>3)
{
/* Note that "SendToModule" calls
* SendStrToModule(fvwm/module_interface.c)
* which seems to insert three pieces of data at the start of
* the body */
/* The quoting seems to be wrong in SendToModule */
/* Sending "SendToModule "FvwmDragWell" dragitem "stuff"
* yields [" dragitem "stuff"]*/
lptr = packet->body;
msg = (char *) &(lptr[3]);
strcpy(fvwmMessage,msg);
return FOUND_FVWM_MESSAGE;
}
else
{
return FOUND_FVWM_NON_MESSAGE;
}
}
else if (packet->type == MX_PROPERTY_CHANGE)
{
if (packet->body[0] == MX_PROPERTY_CHANGE_BACKGROUND &&
xg.colorset >= 0 &&
Colorset[xg.colorset].pixmap == ParentRelative &&
((!Swallowed && packet->body[2] == 0) ||
(Swallowed && packet->body[2] == xg.win)))
{
XClearArea(xg.dpy, xg.win, 0,0,0,0, True);
}
else if (packet->body[0] == MX_PROPERTY_CHANGE_SWALLOW &&
packet->body[2] == xg.win)
{
Swallowed = packet->body[1];
}
return FOUND_FVWM_NON_MESSAGE;
}
else
{
return FOUND_FVWM_NON_MESSAGE;
}
}
}
}
return FOUND_FVWM_NON_MESSAGE;
}
/* dummy - used to draw the face of the dragwell button
* Arguments:
* but - the dragwell button
* Does not return anything useful.*/
int dummy(DragWellButton *but)
{
if (but->state==DRAGWELL_BUTTON_PUSHED)
XFillRectangle(xg.dpy,xg.win,xg.buttonGC,xg.dbx+2,xg.dby+2,xg.dbw-4,
xg.dbh-4);
return 0;
}
/*createWindow - creates the drag window.
* Arguments:*/
void createWindow(void)
{
unsigned long valuemask;
XSetWindowAttributes attributes;
xg.sizehints.min_width = 1;
xg.sizehints.min_height = 1;
xg.sizehints.width_inc = 1;
xg.sizehints.height_inc = 1;
xg.sizehints.base_width = xg.w;
xg.sizehints.base_height = xg.h;
xg.sizehints.win_gravity = NorthWestGravity;
xg.sizehints.flags = (PMinSize | PResizeInc | PBaseSize | PWinGravity);
if (xg.xneg)
{
xg.sizehints.win_gravity = NorthEastGravity;
xg.x = xg.dpyWidth + xg.x - xg.w;
}
if (xg.yneg)
{
xg.y = xg.dpyHeight + xg.y - xg.h;
if(xg.sizehints.win_gravity == NorthEastGravity)
xg.sizehints.win_gravity = SouthEastGravity;
else
xg.sizehints.win_gravity = SouthWestGravity;
}
if (xg.usposition)
{
xg.sizehints.flags |= USPosition;
/* hack to prevent mapping on wrong screen with StartsOnScreen */
FScreenMangleScreenIntoUSPosHints(FSCREEN_XYPOS, &xg.sizehints);
}
valuemask = (CWBackPixmap | CWBorderPixel| CWColormap);
attributes.background_pixel = xg.back;
attributes.border_pixel = xg.fore;
attributes.background_pixmap = None;
attributes.colormap = Pcmap;
attributes.event_mask = (StructureNotifyMask);
xg.win = XCreateWindow (xg.dpy, xg.root, xg.x, xg.y, xg.w,
xg.h, 0, Pdepth, InputOutput, Pvisual,
valuemask, &attributes);
/*_XA_WM_PROTOCOLS = XInternAtom (dpy, "WM_PROTOCOLS", False);*/
xg.wmAtomDelWin = XInternAtom(xg.dpy,"WM_DELETE_WINDOW",False);
XSetWMProtocols(xg.dpy,xg.win,&xg.wmAtomDelWin,1);
XSetWMNormalHints(xg.dpy,xg.win,&xg.sizehints);
changeWindowName(xg.win, xg.appName);
XSelectInput(xg.dpy, xg.win, MW_EVENTS);
XMapWindow(xg.dpy,xg.win);
}
syntax highlighted by Code2HTML, v. 0.9.1