Thursday January 27, 2005
playing around with mice and windows
Updated: 2005/02/03 - it didn't build so well on Linux.
This is a bit of code for Solaris which allows you to:
- Move your mouse around the screen
- Resize the window under the mouse
- Move the window under the mouse
| Solaris | Linux (mandrake 10 tested) |
|---|---|
| cc -v -I/usr/openwin/include -L/usr/openwin/lib -R/usr/openwin/lib -o movemouse movemouse.c -lX11 -lXmu | gcc -DLINUX -W -I/usr/X11R6/include -L/usr/X11R6/lib -o movemouse movemouse.c -lX11 -lXmu |
The meaning of the -R/usr/openwin/lib for solaris is to set the run-time linker lookup to try the /usr/openwin/lib path for libraries, as part of the symbol resolution step. Otherwise it relies on either the LD_LIBRARY_PATH (It is evil), or the crle path (man crle - it is neat).
For Linux you normally have the /etc/ld.so.conf file, which typically has /usr/X11R6/lib in there (and if you've got qt, probably has /usr/lib/qt3/lib as well). If you want to find out more abou tthis then look at the info/man page for ldconfig.
I have this code for window managers that don't have mouse/window movement shaping hotkeys of their own (e.g. fvwm). It makes the gnome window
managers almost useful. It should be portable to other X based OS's.
It comes with the usual preamble - use it at your own risk, if it eats your cat then it's not mine (or Sun's) fault.
#include <alloca.h>
#include <libgen.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#if defined(LINUX)
#include <string.h>
#include <stdint.h>
#endif
#include <sys/types.h>
#include <unistd.h>
#include <X11/X.h>
#include <X11/Xlib.h>
static char *appname;
struct systeminfo {
int rootx;
int rooty;
int width;
int height;
int winx;
int winy;
Display *display;
Window rootwin;
Window undermouse;
XWindowAttributes childattr;
};
static char *actionhelp();
static void
usage(int exitcode)
{
(void) printf("usage: %s {<action> [+-]<valx>[%%] [+-]<valy>[%%] }+ \n",
appname);
(void) printf("\tif you use +- it is taken as a delta, otherwise it is"
" absolute\n");
(void) printf("Where action is one of %s\n", actionhelp());
(void) printf("\tFor example %s mm 0 0 would move the mouse to the "
"\n\ttop left of the screen\n", appname);
exit(exitcode);
}
static int
XError(Display *disp, XErrorEvent *code)
{
char buffer[2000];
XGetErrorText(disp, code->error_code, buffer, 1999);
(void) printf("Error: %s\n", buffer);
return (0);
}
static int isdelta(const char *value) {
return ((*value == '-') || (*value == '+'));
}
static int isperc(const char *value) {
return ((strrchr(value, '%') - value) == (strlen(value) - 1));
}
static int transform(const char *val, int start, int maxMetric) {
int av = atoi(val);
/*(void) printf("%s %d %d %d\n", val, av, start, maxMetric);*/
if (isdelta(val) && isperc(val))
return (start + (int)(maxMetric * av / 100));
if (isdelta(val))
return (start + av);
if (isperc(val))
return ((int)(maxMetric * av / 100));
return (av);
}
static void getxy(struct systeminfo *info, const char *xarg,
const char *yarg, int *xval, int *yval, uintptr_t offx,
uintptr_t offy) {
/*LINTED*/
*xval = transform(xarg, *((int *)((char *)info + offx)),
isperc(xarg) && isdelta(xarg) ? info->width :
WidthOfScreen(DefaultScreenOfDisplay(info->display)));
/*LINTED*/
*yval = transform(yarg, *((int *)((char *)info + offy)),
isperc(yarg) && isdelta(yarg) ? info->height :
HeightOfScreen(DefaultScreenOfDisplay(info->display)));
/* (void) printf("%d %d\n", *xval, *yval); */
}
static void MoveMouse(struct systeminfo *info, int xarg, int yarg) {
XWarpPointer(info->display, None, info->rootwin, 0, 0, 0, 0,
xarg, yarg);
}
static void ResizeWindow(struct systeminfo *info, int xarg, int yarg) {
XResizeWindow(info->display, info->undermouse, xarg, yarg);
}
static void MoveWindow(struct systeminfo *info, int xarg, int yarg) {
XMoveWindow(info->display, info->undermouse, xarg, yarg);
}
#define funtostring(FV) #FV, FV
static struct activity {
char *action;
char *helpstring;
void (*function)(struct systeminfo *, int, int);
uintptr_t offsetx;
uintptr_t offsety;
} activitylist[] = {
{ "mm", funtostring(MoveMouse),
offsetof(struct systeminfo, rootx),
offsetof(struct systeminfo, rooty) },
{ "rw", funtostring(ResizeWindow),
offsetof(struct systeminfo, width),
offsetof(struct systeminfo, height) },
{ "mw", funtostring(MoveWindow),
offsetof(struct systeminfo, winx),
offsetof(struct systeminfo, winy) },
{ NULL, NULL, NULL }
};
static char *actionhelp(void) {
static char *buffer = NULL;
char *stribo;
struct activity *ack = activitylist;
stribo = alloca(1024);
if (buffer != NULL)
return (buffer);
buffer = calloc(1, getpagesize());
while (ack->action != NULL) {
(void) sprintf(stribo, "%s(%s) ", ack->action, ack->helpstring);
(void) strcat(buffer, stribo);
ack++;
}
return (buffer);
}
extern Window XmuClientWindow(Display *, Window);
static void InitializeWinfoid(struct systeminfo *winfoid) {
unsigned int mask;
winfoid->rootwin = XDefaultRootWindow(winfoid->display);
XQueryPointer(winfoid->display, winfoid->rootwin,
&winfoid->rootwin, &winfoid->undermouse,
&winfoid->rootx, &winfoid->rooty,
&winfoid->winx, &winfoid->winy, &mask);
XGetWindowAttributes(winfoid->display, winfoid->undermouse,
&winfoid->childattr);
winfoid->winx = winfoid->childattr.x;
winfoid->winy = winfoid->childattr.y;
winfoid->undermouse = XmuClientWindow(winfoid->display,
winfoid->undermouse);
XGetWindowAttributes(winfoid->display, winfoid->undermouse,
&winfoid->childattr);
winfoid->width = winfoid->childattr.width;
winfoid->height = winfoid->childattr.height;
}
int
main(int argc, char **argv)
{
struct systeminfo winfoid;
int atarg;
int thisx, thisy;
char *disp;
appname = basename(strdup(argv[0]));
XSetErrorHandler(XError);
if ((argc < 3) || ((argc - 1) % 3)) usage(1);
disp = XDisplayName(NULL);
if (disp == NULL) disp = ":0.0";
winfoid.display = XOpenDisplay(disp);
if (winfoid.display == NULL) {
(void) fprintf(stderr, "Can't open display %s\n", disp);
exit(2);
}
InitializeWinfoid(&winfoid);
/* handle arguments */
for (atarg = 1; atarg < argc; atarg += 3) {
struct activity *atac = activitylist;
while (atac->action != NULL) {
if (strncmp(atac->action, argv[atarg], 2) == 0)
break;
atac++;
}
if (atac->action != NULL) {
getxy(&winfoid, argv[atarg+1], argv[atarg+2],
&thisx, &thisy, atac->offsetx, atac->offsety);
atac->function(&winfoid, thisx, thisy);
}
}
XCloseDisplay(winfoid.display);
return (0);
}
January 27, 2005 05:03 PM GMT
Permalink
Posted by Amjidanutpan Ramanujam on January 28, 2005 at 07:34 AM GMT #
Comments are closed for this entry.