openbsd-ports/x11/x2x/patches/patch-x2x_c
jasper 620aca6685 - apply a patch from debian brining several fixes and improvments, including
support for -north/-south
- take maintainership

ok todd@ (previous maintainer)
2011-11-22 09:33:09 +00:00

811 lines
28 KiB
Plaintext

$OpenBSD: patch-x2x_c,v 1.1 2011/11/22 09:33:09 jasper Exp $
- Various fixes including -north/-south support.
From Debian's x2x_1.27-8 patch.
--- x2x.c.orig Wed Aug 20 18:14:52 1997
+++ x2x.c Mon Nov 21 14:57:27 2011
@@ -1,7 +1,7 @@
/*
- * x2x: Uses the XTEST extension to forward keystrokes from a window on
- * one display to another display. Useful for desks
- * with multiple keyboards.
+ * x2x: Uses the XTEST extension to forward mouse movements and keystrokes
+ * from a window on one display to another display. Useful for
+ * desks with multiple keyboards.
*
* Copyright (c) 1997
* Digital Equipment Corporation. All rights reserved.
@@ -37,26 +37,42 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+
+/*
+ * Modified on 3 Oct 1998 by Charles Briscoe-Smith:
+ * added options -north and -south
+ */
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/Xresource.h>
#include <X11/Xutil.h>
#include <X11/cursorfont.h>
#include <X11/Xatom.h> /* for selection */
+#include <X11/extensions/XTest.h>
#include <sys/types.h> /* for select */
#include <sys/time.h> /* for select */
-#include "format.h"
/*#define DEBUG*/
+#ifndef MIN
+#define MIN(x,y) (((x) < (y)) ? (x) : (y))
+#endif
+#ifndef MAX
+#define MAX(x,y) (((x) > (y)) ? (x) : (y))
+#endif
+
/**********
* definitions for edge
**********/
#define EDGE_NONE 0 /* don't transfer between edges of screens */
-#define EDGE_EAST 1 /* from display is on the east side of to display */
-#define EDGE_WEST 2 /* from display is on the west side of to display */
+#define EDGE_NORTH 1 /* from display is on the north side of to display */
+#define EDGE_SOUTH 2 /* from display is on the south side of to display */
+#define EDGE_EAST 3 /* from display is on the east side of to display */
+#define EDGE_WEST 4 /* from display is on the west side of to display */
/**********
* functions
@@ -92,25 +108,6 @@ static void RefreshPointerMapping();
static void Usage();
/**********
- * text formatting instructions
- **********/
-#define toDpyFormatLength (sizeof(toDpyFormat) / sizeof(Format))
-static Format toDpyFormat[] = {
- FormatMeasureText,
- FormatSetLeft, 0,
- FormatSetTop, 0,
- FormatAddHalfTextX, 1,
- FormatAddHalfTextY, 3,
- FormatString, (Format)"unknown",
- FormatAddHalfTextX, 1,
- FormatAddHalfTextY, 1
- };
-/* indexes of values to be filled in at runtime */
-#define toDpyLeftIndex 2
-#define toDpyTopIndex 4
-#define toDpyStringIndex 10
-
-/**********
* stuff for selection forwarding
**********/
typedef struct _dpyxtra {
@@ -135,6 +132,8 @@ typedef struct _fakestr {
#define N_BUTTONS 5
+#define MAX_BUTTONMAPEVENTS 20
+
#define GETDPYXTRA(DPY,PDPYINFO)\
(((DPY) == (PDPYINFO)->fromDpy) ?\
&((PDPYINFO)->fromDpyXtra) : &((PDPYINFO)->toDpyXtra))
@@ -161,9 +160,10 @@ typedef struct {
GC textGC;
Atom wmpAtom, wmdwAtom;
Cursor grabCursor;
- XFS *font;
- int twidth, theight;
- int lastFromX;
+ Font fid;
+ int width, height, twidth, theight, tascent;
+ Bool vertical;
+ int lastFromCoord;
int unreasonableDelta;
/* stuff on "to" display */
@@ -180,8 +180,10 @@ typedef struct {
int nScreens;
short **xTables; /* precalculated conversion tables */
short **yTables;
- int fromXConn, fromXDisc; /* location of cursor after conn/disc ops */
- int fromXIncr, fromXDecr; /* location of cursor after incr/decr ops */
+ int fromConnCoord; /* location of cursor after conn/disc ops */
+ int fromDiscCoord;
+ int fromIncrCoord; /* location of cursor after incr/decr ops */
+ int fromDecrCoord;
/* selection forwarding info */
DPYXTRA fromDpyXtra;
@@ -218,6 +220,7 @@ static char *fromDpyName = NULL;
static char *toDpyName = NULL;
static char *defaultFN = "-*-times-bold-r-*-*-*-180-*-*-*-*-*-*";
static char *fontName = "-*-times-bold-r-*-*-*-180-*-*-*-*-*-*";
+static char *label = NULL;
static char *pingStr = "PING"; /* atom for ping request */
static char *geomStr = NULL;
static Bool waitDpy = False;
@@ -232,13 +235,13 @@ static int triggerw = 2;
static Bool doPointerMap = True;
static PSTICKY stickies = NULL;
static Bool doBtnBlock = False;
+static int nButtons = 0;
+static KeySym buttonmap[N_BUTTONS + 1][MAX_BUTTONMAPEVENTS + 1];
/**********
* main
**********/
-main(argc, argv)
-int argc;
-char **argv;
+int main(int argc, char **argv)
{
Display *fromDpy;
PSHADOW pShadow;
@@ -253,7 +256,7 @@ char **argv;
exit(1);
}
- /* no OS independent wat to stop Xlib from complaining via stderr,
+ /* no OS independent way to stop Xlib from complaining via stderr,
but can always pipe stdout/stderr to /dev/null */
/* convert to real name: */
while ((fromDpy = XOpenDisplay(fromDpyName)) == NULL) {
@@ -326,11 +329,18 @@ char **argv;
extern char *lawyerese;
PSTICKY pNewSticky;
KeySym keysym;
+ int button;
+ int eventno;
+ char *keyname, *argptr;
#ifdef DEBUG
printf ("programStr = %s\n", programStr);
#endif
+ /* Clear button map */
+ for (button = 0; button <= N_BUTTONS; button++)
+ buttonmap[button][0] = NoSymbol;
+
for (arg = 1; arg < argc; ++arg) {
if (!strcasecmp(argv[arg], "-from")) {
if (++arg >= argc) Usage();
@@ -353,6 +363,13 @@ char **argv;
#ifdef DEBUG
printf ("fontName = %s\n", fontName);
#endif
+ } else if (!strcasecmp(argv[arg], "-label")) {
+ if (++arg >= argc) Usage();
+ label = argv[arg];
+
+#ifdef DEBUG
+ printf ("label = %s\n", label);
+#endif
} else if (!strcasecmp(argv[arg], "-geometry")) {
if (++arg >= argc) Usage();
geomStr = argv[arg];
@@ -384,6 +401,16 @@ char **argv;
#ifdef DEBUG
printf("will not do pointer mapping\n");
#endif
+ } else if (!strcasecmp(argv[arg], "-north")) {
+ doEdge = EDGE_NORTH;
+#ifdef DEBUG
+ printf("\"from\" is on the north side of \"to\"\n");
+#endif
+ } else if (!strcasecmp(argv[arg], "-south")) {
+ doEdge = EDGE_SOUTH;
+#ifdef DEBUG
+ printf("\"from\" is on the south side of \"to\"\n");
+#endif
} else if (!strcasecmp(argv[arg], "-east")) {
doEdge = EDGE_EAST;
#ifdef DEBUG
@@ -422,6 +449,34 @@ char **argv;
} else {
printf("x2x: warning: can't translate %s\n", argv[arg]);
}
+ } else if (!strcasecmp(argv[arg], "-buttonmap")) {
+ if (++arg >= argc) Usage();
+ button = atoi(argv[arg]);
+
+ if ((button < 1) || (button > N_BUTTONS))
+ printf("x2x: warning: invalid button %d\n", button);
+ else if (++arg >= argc)
+ Usage();
+ else
+ {
+#ifdef DEBUG
+ printf("will map button %d to keysyms '%s'\n", button, argv[arg]);
+#endif
+ argptr = argv[arg];
+ eventno = 0;
+ while ((keyname = strtok(argptr, " \t\n\r")) != NULL)
+ {
+ if ((keysym = XStringToKeysym(keyname)) == NoSymbol)
+ printf("x2x: warning: can't translate %s\n", keyname);
+ else if (eventno + 1 >= MAX_BUTTONMAPEVENTS)
+ printf("x2x: warning: too many keys mapped to button %d\n",
+ button);
+ else
+ buttonmap[button][eventno++] = keysym;
+ argptr = NULL;
+ }
+ buttonmap[button][eventno] = NoSymbol;
+ }
} else if (!strcasecmp(argv[arg], "-resurface")) {
doResurface = True;
#ifdef DEBUG
@@ -458,6 +513,9 @@ static void Usage()
printf(" -big\n");
printf(" -buttonblock\n");
printf(" -nomouse\n");
+ printf(" -nopointermap\n");
+ printf(" -north\n");
+ printf(" -south\n");
printf(" -east\n");
printf(" -west\n");
printf(" -nosel\n");
@@ -465,6 +523,8 @@ static void Usage()
printf(" -resurface\n");
printf(" -shadow <DISPLAY>\n");
printf(" -sticky <sticky key>\n");
+ printf(" -label <LABEL>\n");
+ printf(" -buttonmap <button#> \"<keysym> ...\"\n");
exit(4);
} /* END Usage */
@@ -510,7 +570,7 @@ Display *toDpy;
toConn = XConnectionNumber(toDpy);
while (True) { /* FOREVER */
- if (fromPending = XPending(fromDpy))
+ if ((fromPending = XPending(fromDpy)))
if (ProcessEvent(fromDpy, &dpyInfo)) /* done! */
break;
@@ -534,7 +594,7 @@ static void InitDpyInfo(pDpyInfo)
PDPYINFO pDpyInfo;
{
Display *fromDpy, *toDpy;
- Screen *fromScreen, *toScreen;
+ Screen *fromScreen;
long black, white;
int fromHeight, fromWidth, toHeight, toWidth;
Pixmap nullPixmap;
@@ -544,7 +604,7 @@ PDPYINFO pDpyInfo;
int *heights, *widths;
int counter;
int nScreens, screenNum;
- int twidth, theight; /* text dimensions */
+ int twidth, theight, tascent; /* text dimensions */
int xoff, yoff; /* window offsets */
unsigned int width, height; /* window width, height */
int geomMask; /* mask returned by parse */
@@ -556,9 +616,10 @@ PDPYINFO pDpyInfo;
int eventMask;
GC textGC;
char *windowName;
- XFS *font;
+ Font fid;
PSHADOW pShadow;
int triggerLoc;
+ Bool vertical;
/* cache commonly used variables */
fromDpy = pDpyInfo->fromDpy;
@@ -574,10 +635,12 @@ PDPYINFO pDpyInfo;
/* values also in dpyinfo */
root = pDpyInfo->root = XDefaultRootWindow(fromDpy);
nScreens = pDpyInfo->nScreens = XScreenCount(toDpy);
+ vertical = pDpyInfo->vertical = (doEdge == EDGE_NORTH
+ || doEdge == EDGE_SOUTH);
/* other dpyinfo values */
pDpyInfo->mode = X2X_DISCONNECTED;
- pDpyInfo->unreasonableDelta = fromWidth / 2;
+ pDpyInfo->unreasonableDelta = (vertical ? fromHeight : fromWidth) / 2;
pDpyInfo->pFakeThings = NULL;
/* window init structures */
@@ -586,54 +649,76 @@ PDPYINFO pDpyInfo;
eventMask = KeyPressMask | KeyReleaseMask;
/* cursor locations for moving between screens */
- pDpyInfo->fromXIncr = triggerw;
- pDpyInfo->fromXDecr = fromWidth - triggerw - 1;
+ pDpyInfo->fromIncrCoord = triggerw;
+ pDpyInfo->fromDecrCoord = (vertical ? fromHeight : fromWidth) - triggerw - 1;
if (doEdge) { /* edge triggers x2x */
nullPixmap = XCreatePixmap(fromDpy, root, 1, 1, 1);
eventMask |= EnterWindowMask;
pDpyInfo->grabCursor =
XCreatePixmapCursor(fromDpy, nullPixmap, nullPixmap,
&dummyColor, &dummyColor, 0, 0);
- if (doEdge == EDGE_EAST) {
- /* trigger window location */
+ /* trigger window location */
+ if (doEdge == EDGE_NORTH) {
+ triggerLoc = 0;
+ pDpyInfo->fromConnCoord = fromHeight - triggerw - 1;
+ pDpyInfo->fromDiscCoord = triggerw;
+ } else if (doEdge == EDGE_SOUTH) {
+ triggerLoc = fromHeight - triggerw;
+ pDpyInfo->fromConnCoord = 1;
+ pDpyInfo->fromDiscCoord = triggerLoc - 1;
+ } else if (doEdge == EDGE_EAST) {
triggerLoc = fromWidth - triggerw;
- toHeight = XHeightOfScreen(XScreenOfDisplay(toDpy, 0));
- pDpyInfo->fromXConn = 1;
- pDpyInfo->fromXDisc = fromWidth - triggerw - 1;
- } else {
- /* trigger window location */
+ pDpyInfo->fromConnCoord = 1;
+ pDpyInfo->fromDiscCoord = triggerLoc - 1;
+ } else /* doEdge == EDGE_WEST */ {
triggerLoc = 0;
- toHeight = XHeightOfScreen(XScreenOfDisplay(toDpy, nScreens - 1));
- toWidth = XWidthOfScreen(XScreenOfDisplay(toDpy, nScreens - 1));
- pDpyInfo->fromXConn = fromWidth - triggerw - 1;
- pDpyInfo->fromXDisc = triggerw;
+ pDpyInfo->fromConnCoord = fromWidth - triggerw - 1;
+ pDpyInfo->fromDiscCoord = triggerw;
} /* END if doEdge == ... */
xswa.background_pixel = black;
/* fromWidth - 1 doesn't seem to work for some reason */
+ /* Use triggerw offsets so that if an x2x is running
+ along the left edge and along the north edge, both with
+ -resurface, we don't get a feedback loop of them each
+ fighting to be on top.
+ --09/27/99 Greg J. Badros <gjb@cs.washington.edu> */
+ /* also, make it an InputOnly window so I don't lose
+ screen real estate --09/29/99 gjb */
trigger = pDpyInfo->trigger =
- XCreateWindow(fromDpy, root, triggerLoc, 0, triggerw, fromHeight,
- 0, 0, InputOutput, 0,
- CWBackPixel | CWOverrideRedirect, &xswa);
- font = NULL;
+ XCreateWindow(fromDpy, root,
+ vertical ? triggerw : triggerLoc,
+ vertical ? triggerLoc : triggerw,
+ vertical ? fromWidth - (2*triggerw) : triggerw,
+ vertical ? triggerw : fromHeight - (2*triggerw),
+ 0, 0, InputOnly, 0,
+ CWOverrideRedirect, &xswa);
+ fid = 0;
} else { /* normal window for text: do size grovelling */
pDpyInfo->grabCursor = XCreateFontCursor(fromDpy, XC_exchange);
eventMask |= StructureNotifyMask | ExposureMask;
if (doMouse) eventMask |= ButtonPressMask | ButtonReleaseMask;
+ if (label == NULL)
+ label = toDpyName;
/* determine size of text */
- if (((font = XLoadQueryFont(fromDpy, fontName)) != NULL) ||
- ((font = XLoadQueryFont(fromDpy, defaultFN)) != NULL) ||
- ((font = XLoadQueryFont(fromDpy, "fixed")) != NULL)) {
+ if (((fid = XLoadFont(fromDpy, fontName)) != 0) ||
+ ((fid = XLoadFont(fromDpy, defaultFN)) != 0) ||
+ ((fid = XLoadFont(fromDpy, "fixed")) != 0)) {
/* have a font */
- toDpyFormat[toDpyStringIndex] = (Format)toDpyName;
- formatText(NULL, NULL, NULL, font,
- toDpyFormatLength, toDpyFormat, &twidth, &theight);
+ int ascent, descent, direction;
+ XCharStruct overall;
+ XQueryTextExtents(fromDpy, fid, label, strlen(label),
+ &direction, &ascent, &descent, &overall);
+ twidth = - overall.lbearing + overall.rbearing;
+ theight = ascent + descent;
+ tascent = ascent;
+
textGC = pDpyInfo->textGC = XCreateGC(fromDpy, root, 0, NULL);
XSetState(fromDpy, textGC, black, white, GXcopy, AllPlanes);
- XSetFont(fromDpy, textGC, font->fid);
+ XSetFont(fromDpy, textGC, fid);
} else { /* should not have to execute this clause: */
twidth = theight = 100; /* default window size */
@@ -641,8 +726,8 @@ PDPYINFO pDpyInfo;
/* determine size of window */
xoff = yoff = 0;
- width = twidth;
- height = theight;
+ width = twidth + 4; /* XXX gap around text -- should be configurable */
+ height = theight + 4;
geomMask = XParseGeometry(geomStr, &xoff, &yoff, &width, &height);
switch (gravMask = (geomMask & (XNegative | YNegative))) {
case (XNegative | YNegative): gravity = SouthEastGravity; break;
@@ -711,7 +796,8 @@ PDPYINFO pDpyInfo;
free(windowName);
/* conversion stuff */
- pDpyInfo->toScreen = (doEdge == EDGE_WEST) ? (nScreens - 1) : 0;
+ pDpyInfo->toScreen = (doEdge == EDGE_WEST || doEdge == EDGE_NORTH)
+ ? (nScreens - 1) : 0;
/* construct table lookup for screen coordinate conversion */
pDpyInfo->xTables = (short **)malloc(sizeof(short *) * nScreens);
@@ -739,13 +825,25 @@ PDPYINFO pDpyInfo;
xTable[counter] = (counter * toWidth) / fromWidth;
/* adjustment for boundaries */
- if ((screenNum != 0) || (doEdge == EDGE_EAST))
- xTable[0] = COORD_DECR;
- if (((screenNum + 1) < nScreens) || (doEdge == EDGE_WEST)) {
- xTable[fromWidth - 1] = COORD_INCR;
- /* work-around for bug: on at least one tested screen, cursor
- never moved past fromWidth - 2 */
- xTable[fromWidth - 2] = COORD_INCR;
+ if (vertical) {
+ if ((screenNum != 0) || (doEdge == EDGE_SOUTH))
+ yTable[0] = COORD_DECR;
+ if (((screenNum + 1) < nScreens) || (doEdge == EDGE_NORTH)) {
+ yTable[fromHeight - 1] = COORD_INCR;
+ /* work-around for bug: on at least one tested screen, cursor
+ never moved past fromWidth - 2 (I'll assume this might apply
+ in the vertical case, too. --cpbs) */
+ yTable[fromHeight - 2] = COORD_INCR;
+ }
+ } else {
+ if ((screenNum != 0) || (doEdge == EDGE_EAST))
+ xTable[0] = COORD_DECR;
+ if (((screenNum + 1) < nScreens) || (doEdge == EDGE_WEST)) {
+ xTable[fromWidth - 1] = COORD_INCR;
+ /* work-around for bug: on at least one tested screen, cursor
+ never moved past fromWidth - 2 */
+ xTable[fromWidth - 2] = COORD_INCR;
+ }
}
} /* END for screenNum */
@@ -787,15 +885,18 @@ PDPYINFO pDpyInfo;
pDpyInfo->eventMask = eventMask; /* save for future munging */
if (doSel) XSetSelectionOwner(fromDpy, XA_PRIMARY, trigger, CurrentTime);
XMapRaised(fromDpy, trigger);
- if (pDpyInfo->font = font) { /* paint text */
+ if ((pDpyInfo->fid = fid)) { /* paint text */
/* position text */
pDpyInfo->twidth = twidth;
pDpyInfo->theight = theight;
- toDpyFormat[toDpyLeftIndex] = MAX(0,((width - twidth) / 2));
- toDpyFormat[toDpyTopIndex] = MAX(0,((height - theight) / 2));
+ pDpyInfo->tascent = tascent;
+ pDpyInfo->width = width;
+ pDpyInfo->height = height;
- formatText(fromDpy, trigger, &(textGC), font,
- toDpyFormatLength, toDpyFormat, NULL, NULL);
+ XDrawImageString(fromDpy, trigger, textGC,
+ MAX(0,((width - twidth) / 2)),
+ MAX(0,((height - theight) / 2)) + tascent, label,
+ strlen(label));
} /* END if font */
for (pShadow = shadows; pShadow; pShadow = pShadow->pNext)
@@ -937,33 +1038,36 @@ XMotionEvent *pEv; /* caution: might be pseudo-event!!
int toScreenNum;
PSHADOW pShadow;
- int toX, fromX, delta;
+ int toCoord, fromCoord, delta;
Display *fromDpy;
Bool bAbortedDisconnect;
+ Bool vert;
+ vert = pDpyInfo->vertical;
+
/* find the screen */
toScreenNum = pDpyInfo->toScreen;
- fromX = pEv->x_root;
+ fromCoord = vert ? pEv->y_root : pEv->x_root;
/* check to make sure the cursor is still on the from screen */
if (!(pEv->same_screen)) {
- toX = (pDpyInfo->lastFromX < fromX) ? COORD_DECR : COORD_INCR;
+ toCoord = (pDpyInfo->lastFromCoord < fromCoord) ? COORD_DECR : COORD_INCR;
} else {
- toX = pDpyInfo->xTables[toScreenNum][fromX];
+ toCoord = (vert?pDpyInfo->yTables:pDpyInfo->xTables)[toScreenNum][fromCoord];
/* sanity check motion: necessary for nondeterminism surrounding warps */
- delta = pDpyInfo->lastFromX - fromX;
+ delta = pDpyInfo->lastFromCoord - fromCoord;
if (delta < 0) delta = -delta;
if (delta > pDpyInfo->unreasonableDelta) return False;
}
- if (SPECIAL_COORD(toX) != 0) { /* special coordinate */
+ if (SPECIAL_COORD(toCoord) != 0) { /* special coordinate */
bAbortedDisconnect = False;
- if (toX == COORD_INCR) {
+ if (toCoord == COORD_INCR) {
if (toScreenNum != (pDpyInfo->nScreens - 1)) { /* next screen */
toScreenNum = ++(pDpyInfo->toScreen);
- fromX = pDpyInfo->fromXIncr;
- toX = pDpyInfo->xTables[toScreenNum][fromX];
+ fromCoord = pDpyInfo->fromIncrCoord;
+ toCoord = (vert?pDpyInfo->yTables:pDpyInfo->xTables)[toScreenNum][fromCoord];
} else { /* disconnect! */
if (doBtnBlock &&
(pEv->state & (Button1Mask | Button2Mask | Button3Mask |
@@ -971,15 +1075,15 @@ XMotionEvent *pEv; /* caution: might be pseudo-event!!
bAbortedDisconnect = True;
else {
DoDisconnect(pDpyInfo);
- fromX = pDpyInfo->fromXDisc;
+ fromCoord = pDpyInfo->fromDiscCoord;
}
- toX = pDpyInfo->xTables[toScreenNum][pDpyInfo->fromXConn];
+ toCoord = (vert?pDpyInfo->yTables:pDpyInfo->xTables)[toScreenNum][pDpyInfo->fromConnCoord];
}
} else { /* DECR */
if (toScreenNum != 0) { /* previous screen */
toScreenNum = --(pDpyInfo->toScreen);
- fromX = pDpyInfo->fromXDecr;
- toX = pDpyInfo->xTables[toScreenNum][fromX];
+ fromCoord = pDpyInfo->fromDecrCoord;
+ toCoord = (vert?pDpyInfo->yTables:pDpyInfo->xTables)[toScreenNum][fromCoord];
} else { /* disconnect! */
if (doBtnBlock &&
(pEv->state & (Button1Mask | Button2Mask | Button3Mask |
@@ -987,23 +1091,26 @@ XMotionEvent *pEv; /* caution: might be pseudo-event!!
bAbortedDisconnect = True;
else {
DoDisconnect(pDpyInfo);
- fromX = pDpyInfo->fromXDisc;
+ fromCoord = pDpyInfo->fromDiscCoord;
}
- toX = pDpyInfo->xTables[toScreenNum][pDpyInfo->fromXConn];
+ toCoord = (vert?pDpyInfo->yTables:pDpyInfo->xTables)[toScreenNum][pDpyInfo->fromConnCoord];
}
- } /* END if toX */
+ } /* END if toCoord */
if (!bAbortedDisconnect) {
fromDpy = pDpyInfo->fromDpy;
XWarpPointer(fromDpy, None, pDpyInfo->root, 0, 0, 0, 0,
- fromX, pEv->y_root);
+ vert ? pEv->x_root : fromCoord,
+ vert ? fromCoord : pEv->y_root);
XFlush(fromDpy);
}
} /* END if SPECIAL_COORD */
- pDpyInfo->lastFromX = fromX;
+ pDpyInfo->lastFromCoord = fromCoord;
for (pShadow = shadows; pShadow; pShadow = pShadow->pNext) {
- XTestFakeMotionEvent(pShadow->dpy, toScreenNum, toX,
- pDpyInfo->yTables[toScreenNum][pEv->y_root], 0);
+ XTestFakeMotionEvent(pShadow->dpy, toScreenNum,
+ vert?pDpyInfo->xTables[toScreenNum][pEv->x_root]:toCoord,
+ vert?toCoord:pDpyInfo->yTables[toScreenNum][pEv->y_root],
+ 0);
XFlush(pShadow->dpy);
} /* END for */
@@ -1017,10 +1124,12 @@ PDPYINFO pDpyInfo;
XExposeEvent *pEv;
{
XClearWindow(pDpyInfo->fromDpy, pDpyInfo->trigger);
- if (pDpyInfo->font)
- formatText(pDpyInfo->fromDpy, pDpyInfo->trigger,
- &(pDpyInfo->textGC), pDpyInfo->font,
- toDpyFormatLength, toDpyFormat, NULL, NULL);
+ if (pDpyInfo->fid)
+ XDrawImageString(pDpyInfo->fromDpy, pDpyInfo->trigger, pDpyInfo->textGC,
+ MAX(0,((pDpyInfo->width - pDpyInfo->twidth) / 2)),
+ MAX(0,((pDpyInfo->height - pDpyInfo->theight) / 2)) +
+ pDpyInfo->tascent, label, strlen(label));
+
return False;
} /* END ProcessExpose */
@@ -1036,10 +1145,17 @@ XCrossingEvent *pEv;
if ((pEv->mode == NotifyNormal) &&
(pDpyInfo->mode == X2X_DISCONNECTED) && (dpy == pDpyInfo->fromDpy)) {
DoConnect(pDpyInfo);
- XWarpPointer(fromDpy, None, pDpyInfo->root, 0, 0, 0, 0,
- pDpyInfo->fromXConn, pEv->y_root);
- xmev.x_root = pDpyInfo->lastFromX = pDpyInfo->fromXConn;
- xmev.y_root = pEv->y_root;
+ if (pDpyInfo->vertical) {
+ XWarpPointer(fromDpy, None, pDpyInfo->root, 0, 0, 0, 0,
+ pEv->x_root, pDpyInfo->fromConnCoord);
+ xmev.x_root = pEv->x_root;
+ xmev.y_root = pDpyInfo->lastFromCoord = pDpyInfo->fromConnCoord;
+ } else {
+ XWarpPointer(fromDpy, None, pDpyInfo->root, 0, 0, 0, 0,
+ pDpyInfo->fromConnCoord, pEv->y_root);
+ xmev.x_root = pDpyInfo->lastFromCoord = pDpyInfo->fromConnCoord;
+ xmev.y_root = pEv->y_root;
+ }
xmev.same_screen = True;
ProcessMotionNotify(NULL, pDpyInfo, &xmev);
} /* END if NotifyNormal... */
@@ -1055,7 +1171,10 @@ XButtonEvent *pEv;
int state;
PSHADOW pShadow;
unsigned int toButton;
-
+ KeySym keysym;
+ KeyCode keycode;
+ int eventno;
+
switch (pDpyInfo->mode) {
case X2X_DISCONNECTED:
pDpyInfo->mode = X2X_AWAIT_RELEASE;
@@ -1064,17 +1183,48 @@ XButtonEvent *pEv;
#endif
break;
case X2X_CONNECTED:
- if (pEv->button <= N_BUTTONS) toButton = pDpyInfo->inverseMap[pEv->button];
- for (pShadow = shadows; pShadow; pShadow = pShadow->pNext) {
- XTestFakeButtonEvent(pShadow->dpy, toButton, True, 0);
+ if ((pEv->button <= N_BUTTONS) &&
+ (buttonmap[pEv->button][0] != NoSymbol))
+ {
+ for (pShadow = shadows; pShadow; pShadow = pShadow->pNext)
+ {
#ifdef DEBUG
- printf("from button %d down, to button %d down\n", pEv->button,toButton);
+ printf("Button %d is mapped, sending keys: ", pEv->button);
#endif
- XFlush(pShadow->dpy);
- } /* END for */
- if (doAutoUp)
- FakeAction(pDpyInfo, FAKE_BUTTON, toButton, True);
- if (doEdge) break;
+ for (eventno = 0;
+ (keysym = buttonmap[pEv->button][eventno]) != NoSymbol;
+ eventno++)
+ {
+ if ((keycode = XKeysymToKeycode(pShadow->dpy, keysym))) {
+ XTestFakeKeyEvent(pShadow->dpy, keycode, True, 0);
+ XTestFakeKeyEvent(pShadow->dpy, keycode, False, 0);
+ XFlush(pShadow->dpy);
+#ifdef DEBUG
+ printf(" (0x%04X)", keycode);
+#endif
+ }
+#ifdef DEBUG
+ else
+ printf(" (no code)");
+#endif
+ }
+#ifdef DEBUG
+ printf("\n");
+#endif
+ }
+ } else if (pEv->button <= nButtons) {
+ toButton = pDpyInfo->inverseMap[pEv->button];
+ for (pShadow = shadows; pShadow; pShadow = pShadow->pNext) {
+ XTestFakeButtonEvent(pShadow->dpy, toButton, True, 0);
+#ifdef DEBUG
+ printf("from button %d down, to button %d down\n", pEv->button,toButton);
+#endif
+ XFlush(pShadow->dpy);
+ } /* END for */
+ if (doAutoUp)
+ FakeAction(pDpyInfo, FAKE_BUTTON, toButton, True);
+ }
+ if (doEdge) break;
/* check if more than one button pressed */
state = pEv->state;
@@ -1113,16 +1263,21 @@ XButtonEvent *pEv;
if ((pDpyInfo->mode == X2X_CONNECTED) ||
(pDpyInfo->mode == X2X_CONN_RELEASE)) {
- if (pEv->button <= N_BUTTONS) toButton = pDpyInfo->inverseMap[pEv->button];
- for (pShadow = shadows; pShadow; pShadow = pShadow->pNext) {
- XTestFakeButtonEvent(pShadow->dpy, toButton, False, 0);
+ if ((pEv->button <= nButtons) &&
+ (buttonmap[pEv->button][0] == NoSymbol))
+ // Do not process button release if it was mapped to keys
+ {
+ toButton = pDpyInfo->inverseMap[pEv->button];
+ for (pShadow = shadows; pShadow; pShadow = pShadow->pNext) {
+ XTestFakeButtonEvent(pShadow->dpy, toButton, False, 0);
#ifdef DEBUG
- printf("from button %d up, to button %d up\n", pEv->button, toButton);
+ printf("from button %d up, to button %d up\n", pEv->button, toButton);
#endif
- XFlush(pShadow->dpy);
- } /* END for */
- if (doAutoUp)
- FakeAction(pDpyInfo, FAKE_BUTTON, toButton, False);
+ XFlush(pShadow->dpy);
+ } /* END for */
+ if (doAutoUp)
+ FakeAction(pDpyInfo, FAKE_BUTTON, toButton, False);
+ }
} /* END if */
if (doEdge) return False;
@@ -1145,8 +1300,13 @@ XButtonEvent *pEv;
if (!state) { /* all buttons up: time to (dis)connect */
if (pDpyInfo->mode == X2X_AWAIT_RELEASE) { /* connect */
DoConnect(pDpyInfo);
- xmev.x_root = pDpyInfo->lastFromX = pEv->x_root;
- xmev.y_root = pEv->y_root;
+ if (pDpyInfo->vertical) {
+ xmev.x_root = pEv->x_root;
+ xmev.y_root = pDpyInfo->lastFromCoord = pEv->y_root;
+ } else {
+ xmev.x_root = pDpyInfo->lastFromCoord = pEv->x_root;
+ xmev.y_root = pEv->y_root;
+ }
xmev.same_screen = True;
ProcessMotionNotify(NULL, pDpyInfo, &xmev);
} else { /* disconnect */
@@ -1178,7 +1338,7 @@ XKeyEvent *pEv;
if (pSticky) {
for (pShadow = shadows; pShadow; pShadow = pShadow->pNext) {
- if (keycode = XKeysymToKeycode(pShadow->dpy, keysym)) {
+ if ((keycode = XKeysymToKeycode(pShadow->dpy, keysym))) {
XTestFakeKeyEvent(pShadow->dpy, keycode, True, 0);
XTestFakeKeyEvent(pShadow->dpy, keycode, False, 0);
XFlush(pShadow->dpy);
@@ -1186,7 +1346,7 @@ XKeyEvent *pEv;
} /* END for */
} else {
for (pShadow = shadows; pShadow; pShadow = pShadow->pNext) {
- if (keycode = XKeysymToKeycode(pShadow->dpy, keysym)) {
+ if ((keycode = XKeysymToKeycode(pShadow->dpy, keysym))) {
XTestFakeKeyEvent(pShadow->dpy, keycode, bPress, 0);
XFlush(pShadow->dpy);
} /* END if */
@@ -1204,12 +1364,10 @@ Display *dpy;
PDPYINFO pDpyInfo;
XConfigureEvent *pEv;
{
- if (pDpyInfo->font) {
+ if (pDpyInfo->fid) {
/* reposition text */
- toDpyFormat[toDpyLeftIndex] =
- MAX(0,((pEv->width - pDpyInfo->twidth) / 2));
- toDpyFormat[toDpyTopIndex] =
- MAX(0,((pEv->height - pDpyInfo->theight) / 2));
+ pDpyInfo->width = pEv->width;
+ pDpyInfo->height = pEv->height;
} /* END if font */
return False;
@@ -1276,7 +1434,6 @@ Display *dpy;
PDPYINFO pDpyInfo;
XPropertyEvent *pEv;
{
- XSelectionRequestEvent *pSelReq;
PDPYXTRA pDpyXtra = GETDPYXTRA(dpy, pDpyInfo);
#ifdef DEBUG
@@ -1501,7 +1658,7 @@ PDPYINFO pDpyInfo;
/* send up to all shadows */
for (pShadow = shadows; pShadow; pShadow = pShadow->pNext) {
if (type == FAKE_KEY) { /* key goes up */
- if (keycode = XKeysymToKeycode(pShadow->dpy, pFake->thing)) {
+ if ((keycode = XKeysymToKeycode(pShadow->dpy, pFake->thing))) {
XTestFakeKeyEvent(pShadow->dpy, keycode, False, 0);
#ifdef DEBUG
printf("key 0x%x up\n", pFake->thing);
@@ -1535,7 +1692,6 @@ PDPYINFO pDpyInfo;
{
unsigned int buttCtr;
unsigned char buttonMap[N_BUTTONS];
- int nButtons;
if (dpy == pDpyInfo->toDpy) { /* only care about toDpy */
/* straightforward mapping */