From ad2087f2482e0937570e4f86f3ed8338fffbedd6 Mon Sep 17 00:00:00 2001 From: Dylan Simon Date: Sun, 4 Oct 2009 17:41:54 -0400 Subject: [PATCH] New -distance mapping option Distance mapping makes more efficient use of eye space. Change-Id: Iaf471ee360f1d7f8d0aece905589fb8f39cc4029 Signed-off-by: Dylan Simon Signed-off-by: James Cloos --- Eyes.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- Eyes.h | 3 ++- EyesP.h | 1 + xeyes.c | 3 ++- xeyes.man | 3 +++ 5 files changed, 69 insertions(+), 7 deletions(-) diff --git a/Eyes.c b/Eyes.c index 3fa5b4f..e792445 100644 --- a/Eyes.c +++ b/Eyes.c @@ -79,6 +79,8 @@ static XtResource resources[] = { {XtNrender, XtCBoolean, XtRBoolean, sizeof(Boolean), offset(render), XtRImmediate, (XtPointer) TRUE }, #endif + {XtNdistance, XtCBoolean, XtRBoolean, sizeof(Boolean), + offset(distance), XtRImmediate, (XtPointer) FALSE }, }; #undef offset @@ -100,6 +102,8 @@ static XtResource resources[] = { # define TPOINT_NONE (-1000) /* special value meaning "not yet set" */ # define TPointEqual(a, b) ((a).x == (b).x && (a).y == (b).y) # define XPointEqual(a, b) ((a).x == (b).x && (a).y == (b).y) +# define AngleBetween(A, A0, A1) (A0 <= A1 ? A0 <= A && A <= A1 : \ + A0 <= A || A <= A1) static int delays[] = { 50, 100, 200, 400, 0 }; @@ -299,7 +303,8 @@ eyeLiner(EyesWidget w, static TPoint computePupil ( int num, - TPoint mouse) + TPoint mouse, + const TRectangle *screen) { double cx, cy; double dist; @@ -316,6 +321,42 @@ static TPoint computePupil ( cosa = cos (angle); sina = sin (angle); dist = BALL_DIST; + if (screen) + { + /* use distance mapping */ + double x0, y0, x1, y1; + double a[4]; + x0 = screen->x - cx; + y0 = screen->y - cy; + x1 = x0 + screen->width; + y1 = y0 + screen->height; + a[0] = atan2(y0, x0); + a[1] = atan2(y1, x0); + a[2] = atan2(y1, x1); + a[3] = atan2(y0, x1); + if (AngleBetween(angle, a[0], a[1])) + { + /* left */ + dist *= dx / x0; + } + else if (AngleBetween(angle, a[1], a[2])) + { + /* bottom */ + dist *= dy / y1; + } + else if (AngleBetween(angle, a[2], a[3])) + { + /* right */ + dist *= dx / x1; + } + else if (AngleBetween(angle, a[3], a[0])) + { + /* top */ + dist *= dy / y0; + } + if (dist > BALL_DIST) + dist = BALL_DIST; + } if (dist > hypot ((double) dx, (double) dy)) { cx += dx; cy += dy; @@ -330,11 +371,26 @@ static TPoint computePupil ( } static void computePupils ( + EyesWidget w, TPoint mouse, TPoint pupils[2]) { - pupils[0] = computePupil (0, mouse); - pupils[1] = computePupil (1, mouse); + TRectangle screen, *sp = NULL; + if (w->eyes.distance) { + Window r, cw; + int x, y; + r = RootWindowOfScreen(w->core.screen); + XTranslateCoordinates(XtDisplay(w), XtWindow(w), r, 0, 0, &x, &y, &cw); + screen.x = Tx(-x, -y, &w->eyes.t); + screen.y = Ty(-x, -y, &w->eyes.t); + screen.width = Twidth (w->core.screen->width, w->core.screen->height, + &w->eyes.t); + screen.height = Theight(w->core.screen->width, w->core.screen->height, + &w->eyes.t); + sp = &screen; + } + pupils[0] = computePupil (0, mouse, sp); + pupils[1] = computePupil (1, mouse, sp); } static void @@ -354,7 +410,7 @@ static void repaint_window (EyesWidget w) if (XtIsRealized ((Widget) w)) { eyeLiner (w, TRUE, 0); eyeLiner (w, TRUE, 1); - computePupils (w->eyes.mouse, w->eyes.pupil); + computePupils (w, w->eyes.mouse, w->eyes.pupil); eyeBall (w, TRUE, NULL, 0); eyeBall (w, TRUE, NULL, 1); } @@ -391,7 +447,7 @@ drawEyes(EyesWidget w, TPoint mouse) ++w->eyes.update; return; } - computePupils (mouse, newpupil); + computePupils (w, mouse, newpupil); for (num = 0; num < 2; num ++) { drawEye(w, newpupil[num], num); } diff --git a/Eyes.h b/Eyes.h index d9893a3..424967b 100644 --- a/Eyes.h +++ b/Eyes.h @@ -35,7 +35,8 @@ #define XtNshapeWindow "shapeWindow" #define XtCShapeWindow "ShapeWindow" -#define XtNrender "render" +#define XtNrender "render" +#define XtNdistance "distance" enum EyesPart { PART_CLEAR = -1, diff --git a/EyesP.h b/EyesP.h index 1cffdb4..3a04b13 100644 --- a/EyesP.h +++ b/EyesP.h @@ -34,6 +34,7 @@ typedef struct { Picture picture; Picture fill[PART_SHAPE]; #endif + Boolean distance; } EyesPart; /* Full instance record declaration */ diff --git a/xeyes.c b/xeyes.c index 1bca7ab..276a084 100644 --- a/xeyes.c +++ b/xeyes.c @@ -57,7 +57,7 @@ usage(void) fprintf(stderr, " [-shape | +shape]"); fprintf(stderr, "\n"); fprintf(stderr, -" [-outline {color}] [-center {color}] [-backing {backing-store}]\n"); +" [-outline {color}] [-center {color}] [-backing {backing-store}] [-distance]\n"); #ifdef XRENDER fprintf(stderr, " [-render | +render]\n"); @@ -78,6 +78,7 @@ static XrmOptionDescRec options[] = { {"-render", "*eyes.render", XrmoptionNoArg, "TRUE"}, {"+render", "*eyes.render", XrmoptionNoArg, "FALSE"}, #endif +{"-distance", "*eyes.distance", XrmoptionNoArg, "TRUE"}, }; static Atom wm_delete_window; diff --git a/xeyes.man b/xeyes.man index 4484d3d..1685af2 100644 --- a/xeyes.man +++ b/xeyes.man @@ -52,6 +52,9 @@ This is the default if \fIxeyes\fP has been compiled with Xrender support. .TP 8 .B \+render disables Xrender and draws traditional eyes. +.TP 8 +.B \-distance +uses an alternative mapping, as if the eyes were set back from the screen, thus following the mouse more precisely. .SH "SEE ALSO" X(__miscmansuffix__), X Toolkit documentation .br -- 2.7.4