e16/src/scursor.c

363 lines
9.5 KiB
C

/*
* Copyright (C) 1999 Carsten Haitzler, Geoff Harrison and various contributors
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in
* all copies of the Software, its documentation and marketing & publicity
* materials, and acknowledgment shall be given in the documentation, materials
* and software packages that this Software was used.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "E.h"
#ifdef HAVE_LIBXTST
#include <X11/extensions/XTest.h>
#endif
static int update_time = 10;
static int hot_x = 0, hot_y = 0;
static int sc_x = 0, sc_y = 0;
static char wait_mode = 0;
static Display *sc_disp = NULL;
static Window sc_window = 0;
static Atom sc_atom = 0;
static ImlibData *imd = NULL;
Window
SC_GetDestWin(void)
{
return 0;
}
void
SC_PassEvent(XEvent * ev)
{
ev = NULL;
}
void
SC_Main(void)
{
XEvent ev;
struct timeval tv;
int wait_count = 1;
for (;;)
{
if (XCheckWindowEvent(sc_disp, sc_window,
PropertyChangeMask |
PointerMotionMask |
ButtonPressMask |
ButtonReleaseMask
,&ev))
{
switch (ev.type)
{
case KeyPress:
printf("EV: KeyPress:\n");
break;
case KeyRelease:
printf("EV: KeyRelease:\n");
break;
case ButtonPress:
printf("EV: ButtonPress:\n");
break;
case ButtonRelease:
printf("EV: ButtonRelease:\n");
break;
case MotionNotify:
printf("EV: MotionNotify:\n");
break;
case PropertyNotify:
{
static Atom a_wait = 0;
static Atom a_hotspot = 0;
int format_ret;
unsigned long bytes_after, num_ret;
Atom aa;
CARD32 *retval;
if (!a_wait)
a_wait = XInternAtom(sc_disp, "ENL_SC_WAIT", False);
if (!a_hotspot)
a_hotspot = XInternAtom(sc_disp, "ENL_SC_HOTSPOT", False);
if (ev.xproperty.atom == a_wait)
{
retval = NULL;
XGetWindowProperty(sc_disp, sc_window,
ev.xproperty.atom,
0, 0x7fffffff, False,
XA_CARDINAL, &aa, &format_ret,
&num_ret, &bytes_after,
(unsigned char **)(&retval));
if (retval)
{
wait_mode = (char)(*retval);
XFree(retval);
}
}
else if (ev.xproperty.atom == a_hotspot)
{
retval = NULL;
XGetWindowProperty(sc_disp, sc_window,
ev.xproperty.atom,
0, 0x7fffffff, False,
XA_CARDINAL, &aa, &format_ret,
&num_ret, &bytes_after,
(unsigned char **)(&retval));
if (retval)
{
hot_x = retval[0];
hot_y = retval[1];
XFree(retval);
}
}
}
default:
printf("EV: ???\n");
break;
}
}
if (wait_mode)
{
char s[1024], *f;
ImlibImage *im;
Pixmap pmap, mask;
Esnprintf(s, sizeof(s), "pix/wait%i.png", wait_count);
wait_count++;
if (wait_count > 12)
wait_count = 1;
f = FindFile(s);
im = NULL;
if (f)
im = Imlib_load_image(imd, f);
if (f)
Efree(f);
if (im)
{
Imlib_render(imd, im, im->rgb_width, im->rgb_height);
pmap = Imlib_move_image(imd, im);
mask = Imlib_move_mask(imd, im);
EShapeCombineMask(sc_disp, sc_window, ShapeBounding, 0, 0,
mask, ShapeSet);
ESetWindowBackgroundPixmap(sc_disp, sc_window, pmap);
Imlib_free_pixmap(imd, pmap);
XClearWindow(sc_disp, sc_window);
EResizeWindow(sc_disp, sc_window, im->rgb_width, im->rgb_height);
Imlib_destroy_image(imd, im);
}
}
{
Window dw;
int dd, x, y;
unsigned int mm;
XQueryPointer(sc_disp, root.win, &dw, &dw, &dd, &dd, &x, &y, &mm);
EMoveWindow(sc_disp, sc_window, x - hot_x, y - hot_y);
EMapRaised(sc_disp, sc_window);
sc_x = x;
sc_y = y;
}
tv.tv_sec = 0;
tv.tv_usec = 1000000 / update_time;
select(0, NULL, NULL, NULL, &tv);
}
}
/* routine to set up the software cursor */
void
SC_Init(void)
{
Atom aa;
CARD32 val;
int format_ret;
unsigned long bytes_after, num_ret;
XSetWindowAttributes attr;
Window *retval = NULL;
Pixmap pmap, mask;
Cursor cs;
XColor cl;
GC gc;
XGCValues gcv;
sc_atom = XInternAtom(disp, "ENLIGHTENMENT_SOFT_CURSOR", False);
XSync(disp, False);
if (fork())
{
UngrabX();
for (;;)
{
retval = NULL;
XGetWindowProperty(disp, root.win, sc_atom, 0, 0x7fffffff, True,
XA_CARDINAL, &aa, &format_ret, &num_ret,
&bytes_after, (unsigned char **)(&retval));
if (retval)
break;
}
sc_window = *retval;
fflush(stdout);
XFree(retval);
return;
}
XSetErrorHandler((XErrorHandler) NULL);
XSetIOErrorHandler((XIOErrorHandler) NULL);
signal(SIGHUP, SIG_DFL);
signal(SIGINT, SIG_DFL);
signal(SIGQUIT, SIG_DFL);
signal(SIGILL, SIG_DFL);
signal(SIGABRT, SIG_DFL);
signal(SIGFPE, SIG_IGN);
signal(SIGSEGV, SIG_IGN);
signal(SIGPIPE, SIG_DFL);
signal(SIGALRM, SIG_DFL);
signal(SIGTERM, SIG_DFL);
signal(SIGUSR1, SIG_DFL);
signal(SIGUSR2, SIG_DFL);
signal(SIGCHLD, SIG_DFL);
signal(SIGTSTP, SIG_DFL);
signal(SIGBUS, SIG_IGN);
sc_disp = XOpenDisplay(DisplayString(disp));
XGrabServer(sc_disp);
#ifdef HAVE_LIBXTST
{
int test_event_base, test_error_base, test_v1, test_v2;
if (XTestQueryExtension(sc_disp, &test_event_base, &test_error_base, &
test_v1, &test_v2))
XTestGrabControl(sc_disp, True);
}
#endif
printf("sc going\n");
imd = Imlib_init(sc_disp);
attr.backing_store = NotUseful;
attr.override_redirect = True;
attr.colormap = root.cmap;
attr.border_pixel = 0;
attr.background_pixel = 0;
attr.save_under = True;
sc_window = XCreateWindow(sc_disp, root.win, 0, 0, 32, 32, 0, root.depth,
InputOutput, root.vis, CWOverrideRedirect |
CWSaveUnder | CWBackingStore | CWColormap |
CWBackPixel | CWBorderPixel, &attr);
XSelectInput(sc_disp, sc_window,
PropertyChangeMask |
PointerMotionMask |
ButtonPressMask |
ButtonReleaseMask
);
sc_atom = XInternAtom(disp, "ENLIGHTENMENT_SOFT_CURSOR", False);
val = sc_window;
XChangeProperty(sc_disp, root.win, sc_atom, XA_CARDINAL, 32,
PropModeReplace, (unsigned char *)&val, 1);
pmap = ECreatePixmap(sc_disp, sc_window, 16, 16, 1);
mask = ECreatePixmap(sc_disp, sc_window, 16, 16, 1);
gc = XCreateGC(sc_disp, pmap, 0, &gcv);
XSetForeground(sc_disp, gc, 0);
XFillRectangle(sc_disp, pmap, gc, 0, 0, 16, 16);
XFillRectangle(sc_disp, mask, gc, 0, 0, 16, 16);
XFreeGC(sc_disp, gc);
cs = XCreatePixmapCursor(sc_disp, pmap, mask, &cl, &cl, 0, 0);
XDefineCursor(sc_disp, sc_window, cs);
EMapRaised(sc_disp, sc_window);
XGrabPointer(sc_disp, sc_window, True,
ButtonPressMask | ButtonReleaseMask |
PointerMotionMask | ButtonMotionMask
,GrabModeAsync, GrabModeAsync, None, cs,
CurrentTime);
XUngrabServer(sc_disp);
SC_Main();
exit(0);
}
/* routines for E main to call to communicate to software cursor */
void
SC_SetWait(void)
{
static Atom a = 0;
CARD32 val;
if (!a)
a = XInternAtom(disp, "ENL_SC_WAIT", False);
val = 1;
XChangeProperty(disp, sc_window, a, XA_CARDINAL, 32,
PropModeReplace, (unsigned char *)&val, 1);
}
void
SC_Normal(void)
{
static Atom a = 0;
CARD32 val;
if (!a)
a = XInternAtom(disp, "ENL_SC_WAIT", False);
val = 0;
XChangeProperty(disp, sc_window, a, XA_CARDINAL, 32,
PropModeReplace, (unsigned char *)&val, 1);
}
void
SC_SetHotspot(int x, int y)
{
static Atom a = 0;
CARD32 val[2];
if (!a)
a = XInternAtom(disp, "ENL_SC_HOTSPOT", False);
val[0] = x;
val[1] = y;
XChangeProperty(disp, sc_window, a, XA_CARDINAL, 32,
PropModeReplace, (unsigned char *)&val, 2);
}
void
SC_SetImage(char *file)
{
ImlibImage *im;
Pixmap pmap, mask;
im = ELoadImage(file);
if (im)
{
Imlib_render(id, im, im->rgb_width, im->rgb_height);
pmap = Imlib_move_image(id, im);
mask = Imlib_move_mask(id, im);
if (pmap)
{
ESetWindowBackgroundPixmap(disp, sc_window, pmap);
EShapeCombineMask(disp, sc_window, ShapeBounding,
0, 0, mask, ShapeSet);
}
Imlib_free_pixmap(id, pmap);
Imlib_destroy_image(id, im);
}
}
void
SC_Kill(void)
{
if (sc_window)
{
XKillClient(disp, sc_window);
XSync(disp, False);
sc_window = 0;
}
}