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
Build instructions
SolarisLinux (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);
}
Comments:

I am not a sun employee, but I tried to compile your code in a linux box (Mandrake) to make gnome useful. I found the library and include file paths (/usr/X11R6/include and /usr/X11R6/lib). But I am not able to compile it, lots of errors. I did remove -lxmu and the code following the comment motif thingy . gcc -O -I/usr/X11R6/include -L/usr/X11R6/lib/ -lX11 -o movemouse movemouse.c (gcc did not recognize the -R option and I couldn't find what the -R option meant). I don't know what the -O option is either. I can send you the error output if you want (I don't have your email id, mine is given in this comment).

Posted by Amjidanutpan Ramanujam on January 27, 2005 at 11:34 PM GMT #

Post a Comment:
Comments are closed for this entry.
About

petesh

Search

Archives
« April 2014
MonTueWedThuFriSatSun
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    
       
Today