272 lines
5.9 KiB
C
272 lines
5.9 KiB
C
/* This module, and the entire NoClutter program, and the concept for
|
|
* interfacing this module to the Window Manager, are all original work
|
|
* by Robert Nation and Nobutaka Suzuki <nobuta-s@is.aist-nara.ac.jp>
|
|
*
|
|
* Copyright 1994, Robert Nation and Nobutaka Suzuki.
|
|
* 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>
|
|
|
|
#if HAVE_SYS_SELECT_H
|
|
#include <sys/select.h>
|
|
#endif
|
|
|
|
#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 <X11/cursorfont.h>
|
|
|
|
#include "../../fvwm/module.h"
|
|
#include "FvwmScroll.h"
|
|
|
|
char *MyName;
|
|
int fd_width;
|
|
int fd[2];
|
|
|
|
Display *dpy; /* which display are we talking to */
|
|
Window Root;
|
|
int screen;
|
|
int x_fd;
|
|
int d_depth;
|
|
int ScreenWidth, ScreenHeight;
|
|
|
|
char *BackColor = "black";
|
|
|
|
Window app_win;
|
|
|
|
#define MW_EVENTS (ExposureMask | ButtonReleaseMask | KeyReleaseMask)
|
|
|
|
|
|
/***********************************************************************
|
|
*
|
|
* Procedure:
|
|
* main - start of module
|
|
*
|
|
***********************************************************************/
|
|
int main(int argc, char **argv)
|
|
{
|
|
char *temp, *s;
|
|
char *display_name = NULL;
|
|
int Clength;
|
|
char *tline;
|
|
|
|
/* Save the program name for error messages and config parsing */
|
|
temp = argv[0];
|
|
s=strrchr(argv[0], '/');
|
|
if (s != NULL)
|
|
temp = s + 1;
|
|
|
|
MyName = safemalloc(strlen(temp)+2);
|
|
strcpy(MyName,"*");
|
|
strcat(MyName, temp);
|
|
Clength = strlen(MyName);
|
|
|
|
if(argc < 6)
|
|
{
|
|
fprintf(stderr,"%s Version %s should only be executed by fvwm!\n",MyName,
|
|
VERSION);
|
|
exit(1);
|
|
}
|
|
|
|
if(argc >= 7)
|
|
{
|
|
extern int Reduction_H;
|
|
Reduction_H = atoi(argv[6]);
|
|
}
|
|
|
|
if(argc >= 8)
|
|
{
|
|
extern int Reduction_V;
|
|
Reduction_V = atoi(argv[7]);
|
|
}
|
|
|
|
/* Dead pipe == dead fvwm */
|
|
signal (SIGPIPE, DeadPipe);
|
|
|
|
fd[0] = atoi(argv[1]);
|
|
fd[1] = atoi(argv[2]);
|
|
|
|
/* An application window may have already been selected - look for it */
|
|
sscanf(argv[4],"%x",(unsigned int *)&app_win);
|
|
|
|
/* Open the Display */
|
|
if (!(dpy = XOpenDisplay(display_name)))
|
|
{
|
|
fprintf(stderr,"%s: can't open display %s", MyName,
|
|
XDisplayName(display_name));
|
|
exit (1);
|
|
}
|
|
x_fd = XConnectionNumber(dpy);
|
|
screen= DefaultScreen(dpy);
|
|
Root = RootWindow(dpy, screen);
|
|
d_depth = DefaultDepth(dpy, screen);
|
|
|
|
ScreenHeight = DisplayHeight(dpy,screen);
|
|
ScreenWidth = DisplayWidth(dpy,screen);
|
|
|
|
/* scan config file for set-up parameters */
|
|
/* Colors and fonts */
|
|
GetConfigLine(fd,&tline);
|
|
|
|
while(tline != (char *)0)
|
|
{
|
|
if(strlen(tline)>1)
|
|
{
|
|
if(strncasecmp(tline,CatString3(MyName, "Back",""),
|
|
Clength+4)==0)
|
|
{
|
|
CopyString(&BackColor,&tline[Clength+4]);
|
|
}
|
|
}
|
|
GetConfigLine(fd,&tline);
|
|
}
|
|
|
|
/* sever our connection with fvwm */
|
|
close(fd[0]);
|
|
close(fd[1]);
|
|
if(app_win == 0)
|
|
GetTargetWindow(&app_win);
|
|
|
|
if(app_win == 0)
|
|
return 0;
|
|
|
|
fd_width = GetFdWidth();
|
|
|
|
GrabWindow(app_win);
|
|
Loop(app_win);
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
*
|
|
* Detected a broken pipe - time to exit
|
|
*
|
|
**********************************************************************/
|
|
void DeadPipe(int nonsense)
|
|
{
|
|
extern Atom wm_del_win;
|
|
|
|
XReparentWindow(dpy,app_win,Root,0,0);
|
|
send_clientmessage (dpy, app_win, wm_del_win, CurrentTime);
|
|
XSync(dpy,0);
|
|
exit(0);
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
*
|
|
* If no application window was indicated on the command line, prompt
|
|
* the user to select one
|
|
*
|
|
*********************************************************************/
|
|
void GetTargetWindow(Window *app_win)
|
|
{
|
|
XEvent eventp;
|
|
int val = -10,trials;
|
|
Window target_win;
|
|
|
|
trials = 0;
|
|
while((trials <100)&&(val != GrabSuccess))
|
|
{
|
|
val=XGrabPointer(dpy, Root, True,
|
|
ButtonReleaseMask,
|
|
GrabModeAsync, GrabModeAsync, Root,
|
|
XCreateFontCursor(dpy,XC_crosshair),
|
|
CurrentTime);
|
|
if(val != GrabSuccess)
|
|
{
|
|
usleep(1000);
|
|
}
|
|
trials++;
|
|
}
|
|
if(val != GrabSuccess)
|
|
{
|
|
fprintf(stderr,"%s: Couldn't grab the cursor!\n",MyName);
|
|
exit(1);
|
|
}
|
|
XMaskEvent(dpy, ButtonReleaseMask,&eventp);
|
|
XUngrabPointer(dpy,CurrentTime);
|
|
XSync(dpy,0);
|
|
*app_win = eventp.xany.window;
|
|
if(eventp.xbutton.subwindow != None)
|
|
*app_win = eventp.xbutton.subwindow;
|
|
|
|
target_win = ClientWindow(*app_win);
|
|
if(target_win != None)
|
|
*app_win = target_win;
|
|
}
|
|
|
|
|
|
void nocolor(char *a, char *b)
|
|
{
|
|
fprintf(stderr,"FvwmInitBanner: can't %s %s\n", a,b);
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
*
|
|
* Find the actual application
|
|
*
|
|
***************************************************************************/
|
|
Window ClientWindow(Window input)
|
|
{
|
|
Atom _XA_WM_STATE;
|
|
unsigned int nchildren;
|
|
Window root, parent, *children,target;
|
|
unsigned long nitems, bytesafter;
|
|
unsigned char *prop;
|
|
Atom atype;
|
|
int aformat;
|
|
int i;
|
|
|
|
_XA_WM_STATE = XInternAtom (dpy, "WM_STATE", False);
|
|
|
|
if (XGetWindowProperty (dpy,input, _XA_WM_STATE , 0L,
|
|
3L , False, _XA_WM_STATE,&atype,
|
|
&aformat, &nitems, &bytesafter,
|
|
&prop) == Success)
|
|
{
|
|
if(prop != NULL)
|
|
{
|
|
XFree(prop);
|
|
return input;
|
|
}
|
|
}
|
|
|
|
if(!XQueryTree(dpy, input, &root, &parent, &children, &nchildren))
|
|
return None;
|
|
|
|
for (i = 0; i < nchildren; i++)
|
|
{
|
|
target = ClientWindow(children[i]);
|
|
if(target != None)
|
|
{
|
|
XFree((char *)children);
|
|
return target;
|
|
}
|
|
}
|
|
XFree((char *)children);
|
|
return None;
|
|
}
|