You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

919 lines
31 KiB

This is the Debian patch set for X2X (x2x_1.27-5.1.diff.gz)
Index: Imakefile
--- Imakefile.orig 1997-08-20 18:14:52 +0200
+++ Imakefile 2004-08-28 20:56:14 +0200
@@ -2,7 +2,7 @@
DEPLIBS = $(DEPXTESTLIB) $(DEPEXTENSIONLIB) $(DEPXLIB)
LOCAL_LIBRARIES = $(XTESTLIB) $(EXTENSIONLIB) $(XLIB)
- SRCS = lawyerese.c x2x.c format.c
- OBJS = lawyerese.o x2x.o format.o
+ SRCS = lawyerese.c x2x.c
+ OBJS = lawyerese.o x2x.o
PROTO_DEFINES =
--- format.c.orig 1997-08-20 18:14:52 +0200
+++ format.c 2004-08-28 20:56:14 +0200
@@ -199,7 +199,6 @@
{
int fontheight, fontwidth;
int width, height;
- int len;
int format;
unsigned minchar, maxchar;
unsigned char *buffer, thechar;
--- x2x.1.orig 1997-08-20 18:14:51 +0200
+++ x2x.1 2004-08-28 20:56:14 +0200
@@ -3,7 +3,7 @@
.SH NAME
x2x \- X to X connection
.SH SYNTAX
-\f x2x\fR <[-to <DISPLAY>] | [-from <DISPLAY>]> [options...]
+\fB x2x\fR <[-to <DISPLAY>] | [-from <DISPLAY>]> [options...]
.SH DESCRIPTION
x2x allows the keyboard and mouse on one ("from") X display to be used to
control another ("to") X display. Since x2x uses the XTEST extension,
@@ -17,12 +17,12 @@
a subsequent multiple button click on the "to" display returns control
to the "from" display.
-If the -east or -west options are specified on the command line, x2x
-starts up with a different interface. When the mouse moves to the
-(east or west) side of the default screen on the "from" display, the
-cursor slides over to the "to" display. When the mouse returns to
-to side of the "to" display that it entered, it slides back onto
-the "from" display.
+If the -north, -south, -east or -west options are specified on the
+command line, x2x starts up with a different interface. When the mouse
+moves to the top, bottom, east side or west side of the default screen
+on the "from" display, the cursor slides over to the "to" display.
+When the mouse returns to to side of the "to" display that it entered,
+it slides back onto the "from" display.
Unless the -nosel option is specified, x2x relays X selections from
one display to the other.
@@ -55,6 +55,14 @@
Indicates the ("from") display that remotely controls the "to" display.
Default is equivalent to the default display.
.TP
+.B \-north
+.IP
+Slide off the north side of the "to" display onto the "from" display.
+.TP
+.B \-south
+.IP
+Slide off the south side of the "to" display onto the "from" display.
+.TP
.B \-east
.IP
Slide off the east side of the "to" display onto the "from" display.
@@ -70,7 +78,7 @@
.B \-geometry \fIspecification\fP
.IP
The X geometry specification for the x2x window.
-(Overridden by -east or -west.)
+(Overridden by -north, -south, -east or -west.)
.TP
.B \-wait
.IP
@@ -85,14 +93,21 @@
.TP
.B \-buttonblock
.IP
-If this option is enabled with -east or -west, the cursor will not
-slide back onto the "from" display when one or more mouse buttons
-are pressed.
+If this option is enabled with -north, -south, -east or -west, the
+cursor will not slide back onto the "from" display when one or more
+mouse buttons are pressed.
+.TP
+.B \-buttonmap \fIbutton#\fP \fR"\fP\fIKeySym ...\fP\fR"\fP
+.IP
+Map a mouse button to one or more keyboard events on the "to" display.
+This is useful if you have a mouse with more buttons than the remote X
+server can handle (e.g. a wheel mouse on a PC, merged with a Sun/Sparc
+OpenWindows display).
.TP
.B \-nomouse
.IP
Don't capture the mouse.
-(Overridden by -east or -west.)
+(Overridden by -north, -south, -east or -west.)
.TP
.B \-nopointermap
.IP
@@ -119,11 +134,12 @@
.TP
.B \-resurface
.IP
-Ugly hack to work-around window manager ugliness. The -east and -west
-modes actually put a small window on the side of the "from" display.
-This option causes this window to resurface itself if another window
-ever obscures it. This option can cause really nasty behavior if another
-application tries to do the same thing. Useful for login scripts.
+Ugly hack to work-around window manager ugliness. The -north, -south,
+-east and -west modes actually put a small window on the side of the
+"from" display. This option causes this window to resurface itself if
+another window ever obscures it. This option can cause really nasty
+behavior if another application tries to do the same thing. Useful for
+login scripts.
.TP
.B \-shadow \fIdisplay\fP
.IP
@@ -137,10 +153,17 @@
sticky option prevents autoup for the specified key. Look in
/usr/include/X11/keysymdef.h for a list of valid names of keys
(remove the leading XK_).
+.TP
+.B \-label \fIlabel\fP
+Override the title of the control window (useful when running over ssh).
+.IP
.SH AUTHOR
David Chaiken
.br
(chaiken@pa.dec.com)
+.PP
+Addition of -north and -south options by Charles Briscoe-Smith
+<cpbs@debian.org>.
.SH BUGS
This software is experimental! Heaven help you if your network
connection should go down. Caveat hacker. TANSTAAFL.
--- x2x.c.orig 1997-08-20 18:14:52 +0200
+++ x2x.c 2004-08-28 20:58:23 +0200
@@ -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,37 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+
#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 +103,6 @@
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 +127,8 @@
#define N_BUTTONS 5
+#define MAX_BUTTONMAPEVENTS 20
+
#define GETDPYXTRA(DPY,PDPYINFO)\
(((DPY) == (PDPYINFO)->fromDpy) ?\
&((PDPYINFO)->fromDpyXtra) : &((PDPYINFO)->toDpyXtra))
@@ -161,9 +155,10 @@
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 +175,10 @@
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 +215,7 @@
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 +230,13 @@
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 +251,7 @@
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 +324,18 @@
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 +358,13 @@
#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 +396,16 @@
#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 +444,34 @@
} 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 +508,9 @@
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 +518,8 @@
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 +565,7 @@
toConn = XConnectionNumber(toDpy);
while (True) { /* FOREVER */
- if (fromPending = XPending(fromDpy))
+ if ((fromPending = XPending(fromDpy)))
if (ProcessEvent(fromDpy, &dpyInfo)) /* done! */
break;
@@ -534,7 +589,7 @@
PDPYINFO pDpyInfo;
{
Display *fromDpy, *toDpy;
- Screen *fromScreen, *toScreen;
+ Screen *fromScreen;
long black, white;
int fromHeight, fromWidth, toHeight, toWidth;
Pixmap nullPixmap;
@@ -544,7 +599,7 @@
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 +611,10 @@
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 +630,12 @@
/* 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 +644,76 @@
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 +721,8 @@
/* 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 +791,8 @@
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 +820,25 @@
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 +880,18 @@
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));
-
- formatText(fromDpy, trigger, &(textGC), font,
- toDpyFormatLength, toDpyFormat, NULL, NULL);
+ pDpyInfo->tascent = tascent;
+ pDpyInfo->width = width;
+ pDpyInfo->height = height;
+
+ 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 +1033,36 @@
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 +1070,15 @@
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 +1086,26 @@
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 +1119,12 @@
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 +1140,17 @@
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 +1166,10 @@
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 +1178,48 @@
#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);
-#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;
+ if ((pEv->button <= N_BUTTONS) &&
+ (buttonmap[pEv->button][0] != NoSymbol))
+ {
+ for (pShadow = shadows; pShadow; pShadow = pShadow->pNext)
+ {
+#ifdef DEBUG
+ printf("Button %d is mapped, sending keys: ", pEv->button);
+#endif
+ 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 +1258,21 @@
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);
-#ifdef DEBUG
- 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);
+ 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);
+#endif
+ XFlush(pShadow->dpy);
+ } /* END for */
+ if (doAutoUp)
+ FakeAction(pDpyInfo, FAKE_BUTTON, toButton, False);
+ }
} /* END if */
if (doEdge) return False;
@@ -1145,8 +1295,13 @@
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 */
@@ -1204,12 +1359,10 @@
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 +1429,6 @@
PDPYINFO pDpyInfo;
XPropertyEvent *pEv;
{
- XSelectionRequestEvent *pSelReq;
PDPYXTRA pDpyXtra = GETDPYXTRA(dpy, pDpyInfo);
#ifdef DEBUG
@@ -1535,7 +1687,6 @@
{
unsigned int buttCtr;
unsigned char buttonMap[N_BUTTONS];
- int nButtons;
if (dpy == pDpyInfo->toDpy) { /* only care about toDpy */
/* straightforward mapping */