File x2x-1.30-beta.dif of Package x2x
--- Imakefile
+++ Imakefile 2006-03-17 09:32:17.000000000 +0100
@@ -6,7 +6,7 @@ LOCAL_LIBRARIES = $(XTESTLIB) $(EXTENSIO
SRCS = lawyerese.c x2x.c format.c keymap.c winmsg.c
OBJS = lawyerese.o x2x.o format.o keymap.o winmsg.o x2xwin.res
#else
-LOCAL_LIBRARIES = $(XTESTLIB) $(EXTENSIONLIB) $(XLIB)
+LOCAL_LIBRARIES = $(XTESTLIB) $(EXTENSIONLIB) $(XSSLIB) $(XLIB)
SRCS = lawyerese.c x2x.c format.c
OBJS = lawyerese.o x2x.o format.o
#endif
--- x2x.c
+++ x2x.c 2006-04-21 17:51:15.000000000 +0200
@@ -76,6 +76,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <signal.h>
+#include <errno.h>
#include <X11/Xlib.h>
#include <X11/Xresource.h>
#include <X11/Xutil.h>
@@ -83,6 +85,7 @@
#include <X11/Xatom.h> /* for selection */
#include <X11/Xos.h>
#include <X11/extensions/XTest.h>
+#include <X11/extensions/dpms.h>
#include <X11/keysym.h>
#include "format.h"
@@ -135,7 +138,7 @@ static void FakeThingsUp();
static void FakeAction();
static void RefreshPointerMapping();
static void Usage();
-
+static void *xmalloc();
/**********
@@ -174,7 +177,8 @@ typedef struct _dpyxtra {
typedef struct _fakestr {
struct _fakestr *pNext;
int type;
- unsigned int thing;
+ KeySym thing;
+ KeyCode code;
} FAKE, *PFAKE;
#define FAKE_KEY 0
@@ -208,6 +212,8 @@ typedef struct {
Window root;
Window trigger;
Window big;
+ Window selWinFrom;
+ int selRevFrom;
GC textGC;
Atom wmpAtom, wmdwAtom;
Cursor grabCursor;
@@ -237,10 +243,12 @@ typedef struct {
/* stuff on "to" display */
Display *toDpy;
- Window selWin;
+ Window selWinTo;
+ int selRevTo;
unsigned int inverseMap[N_BUTTONS + 1]; /* inverse of button mapping */
/* state of connection */
+ int signal; /* gort signal? */
int mode; /* connection */
int eventMask; /* trigger */
@@ -264,11 +272,15 @@ typedef struct {
} DPYINFO, *PDPYINFO;
+static DPYINFO dpyInfo;
+
/* shadow displays */
typedef struct _shadow {
struct _shadow *pNext;
char *name;
Display *dpy;
+ long led_mask;
+ Bool flush;
} SHADOW, *PSHADOW;
/* sticky keys */
@@ -372,6 +384,9 @@ char **argv;
PSHADOW pShadow;
#endif /* WIN_2_X */
+#ifdef DEBUG
+ setvbuf(stdout, NULL, _IONBF, 0);
+#endif
XrmInitialize();
ParseCommandLine(argc, argv);
@@ -408,18 +423,23 @@ char **argv;
} /* END if */
sleep(10);
} /* END while fromDpy */
+ (void)XSynchronize(fromDpy, True);
/* toDpy is always the first shadow */
- pShadow = (PSHADOW)malloc(sizeof(SHADOW));
+ pShadow = (PSHADOW)xmalloc(sizeof(SHADOW));
pShadow->name = toDpyName;
/* link into the global list */
pShadow->pNext = shadows;
shadows = pShadow;
/* initialize all of the shadows, including the toDpy */
- for (pShadow = shadows; pShadow; pShadow = pShadow->pNext)
+ for (pShadow = shadows; pShadow; pShadow = pShadow->pNext) {
+ pShadow->led_mask = 0;
+ pShadow->flush = False;
if (!(pShadow->dpy = OpenAndCheckDisplay(pShadow->name)))
exit(3);
+ }
+ (void)XSynchronize(shadows->dpy, True);
/* run the x2x loop */
DoX2X(fromDpy, shadows->dpy);
@@ -594,7 +614,7 @@ char **argv;
} else if (!strcasecmp(argv[arg], "-sticky")) {
if (++arg >= argc) Usage();
if ((keysym = XStringToKeysym(argv[arg])) != NoSymbol) {
- pNewSticky = (PSTICKY)malloc(sizeof(STICKY));
+ pNewSticky = (PSTICKY)xmalloc(sizeof(STICKY));
pNewSticky->pNext = stickies;
pNewSticky->keysym = keysym;
stickies = pNewSticky;
@@ -611,7 +631,7 @@ char **argv;
#endif
} else if (!strcasecmp(argv[arg], "-shadow")) {
if (++arg >= argc) Usage();
- pShadow = (PSHADOW)malloc(sizeof(SHADOW));
+ pShadow = (PSHADOW)xmalloc(sizeof(SHADOW));
pShadow->name = argv[arg];
/* into the global list of shadows */
@@ -684,11 +704,17 @@ Display *dpy;
#define X2X_CONNECTED 2
#define X2X_CONN_RELEASE 3
+static void signal_handler(int sig)
+{
+ if (dpyInfo.mode == X2X_CONNECTED)
+ DoDisconnect(&dpyInfo);
+ dpyInfo.signal = sig;
+}
+
static void DoX2X(fromDpy, toDpy)
Display *fromDpy;
Display *toDpy;
{
- DPYINFO dpyInfo;
int nfds;
fd_set fdset;
Bool fromPending;
@@ -699,7 +725,10 @@ Display *toDpy;
dpyInfo.toDpy = toDpy;
InitDpyInfo(&dpyInfo);
RegisterEventHandlers(&dpyInfo);
-
+
+ signal(SIGINT, signal_handler);
+ signal(SIGTERM, signal_handler);
+
/* set up for select */
#ifdef WIN_2_X
fromConn = (fromDpy == fromWin) ? 0 : XConnectionNumber(fromDpy);
@@ -753,7 +782,7 @@ Display *toDpy;
} else
/* Again, the else qualifies the while below */
#endif /* WIN_2_X */
- while (True) { /* FOREVER */
+ while (dpyInfo.signal == 0) { /* FOREVER */
if ((fromPending = XPending(fromDpy)))
if (ProcessEvent(fromDpy, &dpyInfo)) /* done! */
break;
@@ -792,7 +821,8 @@ PDPYINFO pDpyInfo;
int geomMask; /* mask returned by parse */
int gravMask;
int gravity;
- int xret, yret, wret, hret, bret, dret;
+ int xret, yret;
+ unsigned int wret, hret, bret, dret;
XSetWindowAttributes xswa;
XSizeHints *xsh;
int eventMask;
@@ -829,6 +859,7 @@ PDPYINFO pDpyInfo;
toRoot = XDefaultRootWindow(toDpy);
nScreens = pDpyInfo->nScreens = XScreenCount(toDpy);
#else
+ gravity = NorthWestGravity; /* keep compliler happy */
fromScreen = XDefaultScreenOfDisplay(fromDpy);
black = XBlackPixelOfScreen(fromScreen);
white = XWhitePixelOfScreen(fromScreen);
@@ -1042,7 +1073,7 @@ PDPYINFO pDpyInfo;
xsh->flags = (PPosition|PBaseSize|PWinGravity);
XSetWMNormalHints(fromDpy, trigger, xsh);
- windowName = (char *)malloc(strlen(programStr) + strlen(toDpyName) + 2);
+ windowName = (char *)xmalloc(strlen(programStr) + strlen(toDpyName) + 2);
strcpy(windowName, programStr);
strcat(windowName, " ");
strcat(windowName, toDpyName);
@@ -1085,10 +1116,10 @@ PDPYINFO pDpyInfo;
pDpyInfo->toScreen = (doEdge == EDGE_WEST) ? (nScreens - 1) : 0;
/* construct table lookup for screen coordinate conversion */
- pDpyInfo->xTables = (short **)malloc(sizeof(short *) * nScreens);
- pDpyInfo->yTables = (short **)malloc(sizeof(short *) * nScreens);
- heights = (int *)malloc(sizeof(int *) * nScreens);
- widths = (int *)malloc(sizeof(int *) * nScreens);
+ pDpyInfo->xTables = (short **)xmalloc(sizeof(short *) * nScreens);
+ pDpyInfo->yTables = (short **)xmalloc(sizeof(short *) * nScreens);
+ heights = (int *)xmalloc(sizeof(int *) * nScreens);
+ widths = (int *)xmalloc(sizeof(int *) * nScreens);
for (screenNum = 0; screenNum < nScreens; ++screenNum) {
widths[screenNum] = toWidth =
@@ -1097,9 +1128,9 @@ PDPYINFO pDpyInfo;
XHeightOfScreen(XScreenOfDisplay(toDpy, screenNum));
pDpyInfo->xTables[screenNum] = xTable =
- (short *)malloc(sizeof(short) * fromWidth);
+ (short *)xmalloc(sizeof(short) * fromWidth);
pDpyInfo->yTables[screenNum] = yTable =
- (short *)malloc(sizeof(short) * fromHeight);
+ (short *)xmalloc(sizeof(short) * fromHeight);
/* vertical conversion table */
for (counter = 0; counter < fromHeight; ++counter)
@@ -1198,13 +1229,142 @@ PDPYINFO pDpyInfo;
for (pShadow = shadows; pShadow; pShadow = pShadow->pNext)
XTestGrabControl(pShadow->dpy, True); /* impervious to grabs! */
+ pDpyInfo->selWinTo = None;
+ pDpyInfo->selRevTo = 0;
+ pDpyInfo->selWinFrom = None;
+ pDpyInfo->selRevFrom = 0;
+ pDpyInfo->signal = 0;
+
} /* END InitDpyInfo */
+static void DoWakeUp(Display *dpy)
+{
+ CARD16 state;
+ BOOL onoff;
+ int dummy;
+
+ if (!DPMSQueryExtension(dpy, &dummy, &dummy))
+ return;
+
+ if (!DPMSInfo(dpy, &state, &onoff))
+ return;
+
+ if (!onoff)
+ return;
+
+ switch (state) {
+ case DPMSModeOn:
+ return;
+ default:
+ break;
+ }
+
+#ifdef DEBUG
+ printf("DMPS Wakup\n");
+#endif
+ DPMSForceLevel(dpy, DPMSModeOn);
+}
+
+/*
+ * Be sure that on all displays the same keyboard state
+ * is active, therefore check for CapsLock and NumLock,
+ * compare, and if required change the state on the
+ * shadowed displays.
+ */
+static void KeyboardState(Display *dpy)
+{
+ PSHADOW pShadow;
+ XKeyboardState toState;
+
+ XGetKeyboardControl(dpy, &toState);
+#ifdef DEBUG
+ printf(" LED mask = %lx\n", toState.led_mask);
+#endif
+
+ for (pShadow = shadows; pShadow; pShadow = pShadow->pNext) {
+ KeyCode keycode;
+ XKeyboardState shState;
+
+ XGetKeyboardControl(pShadow->dpy, &shState);
+
+ if (toState.led_mask == shState.led_mask)
+ continue;
+
+ pShadow->led_mask = shState.led_mask;
+
+ if ((toState.led_mask & 1) != (shState.led_mask & 1) &&
+ (keycode = XKeysymToKeycode(pShadow->dpy, XK_Caps_Lock))) {
+ XTestFakeKeyEvent(pShadow->dpy, keycode, True, 0);
+ XTestFakeKeyEvent(pShadow->dpy, keycode, False, 0);
+ pShadow->flush = True;
+ }
+
+ if ((toState.led_mask & 2) != (shState.led_mask & 2) &&
+ (keycode = XKeysymToKeycode(pShadow->dpy, XK_Num_Lock))) {
+ XTestFakeKeyEvent(pShadow->dpy, keycode, True, 0);
+ XTestFakeKeyEvent(pShadow->dpy, keycode, False, 0);
+ pShadow->flush = True;
+ }
+
+ if (pShadow->flush) {
+ XFlush(pShadow->dpy);
+ pShadow->flush = False;
+ }
+ }
+}
+
+static void RestoreKeyboardState(void)
+{
+ PSHADOW pShadow;
+
+ for (pShadow = shadows; pShadow; pShadow = pShadow->pNext) {
+ KeyCode keycode;
+ XKeyboardState shState;
+
+ XGetKeyboardControl(pShadow->dpy, &shState);
+
+#ifdef DEBUG
+ printf(" LED mask = %lx(%lx)\n", shState.led_mask, pShadow->led_mask);
+#endif
+
+ if (pShadow->led_mask == shState.led_mask)
+ continue;
+
+ if ((pShadow->led_mask & 1) != (shState.led_mask & 1) &&
+ (keycode = XKeysymToKeycode(pShadow->dpy, XK_Caps_Lock))) {
+ XTestFakeKeyEvent(pShadow->dpy, keycode, True, 0);
+ XTestFakeKeyEvent(pShadow->dpy, keycode, False, 0);
+ pShadow->flush = True;
+ }
+
+ if ((pShadow->led_mask & 2) != (shState.led_mask & 2) &&
+ (keycode = XKeysymToKeycode(pShadow->dpy, XK_Num_Lock))) {
+ XTestFakeKeyEvent(pShadow->dpy, keycode, True, 0);
+ XTestFakeKeyEvent(pShadow->dpy, keycode, False, 0);
+ pShadow->flush = True;
+ }
+
+ if (pShadow->flush) {
+ XFlush(pShadow->dpy);
+ pShadow->flush = False;
+ }
+ }
+}
+
+static int bad_window_handler(Display *disp, XErrorEvent *err)
+{
+ return 0;
+}
+
static void DoConnect(pDpyInfo)
PDPYINFO pDpyInfo;
{
Display *fromDpy = pDpyInfo->fromDpy;
- Window trigger = pDpyInfo->trigger;
+ Window trigger = pDpyInfo->trigger;
+ PSHADOW pShadow;
+
+ if (pDpyInfo->signal)
+ return;
#ifdef DEBUG
printf("connecting\n");
@@ -1214,6 +1374,32 @@ PDPYINFO pDpyInfo;
#ifdef WIN_2_X
assert (fromDpy != fromWin);
#endif
+
+ XGetInputFocus(fromDpy, &pDpyInfo->selWinFrom, &pDpyInfo->selRevFrom);
+ XSetInputFocus(fromDpy, PointerRoot, 0, CurrentTime);
+ XSync(fromDpy, False);
+
+ XFlush(pDpyInfo->toDpy);
+
+ if (pDpyInfo->selWinTo != None) {
+ Display *toDpy = pDpyInfo->toDpy;
+ Window selWinTo = pDpyInfo->selWinTo;
+ int selRevTo = pDpyInfo->selRevTo;
+ XErrorHandler old_handler = XSetErrorHandler(bad_window_handler);
+
+ XSetInputFocus(toDpy, selWinTo, selRevTo, CurrentTime);
+ XSync (toDpy, False);
+ (void) XSetErrorHandler(old_handler);
+ }
+
+ for (pShadow = shadows; pShadow; pShadow = pShadow->pNext)
+ DoWakeUp(pShadow->dpy);
+
+ if (doAutoUp)
+ KeyboardState(fromDpy);
+
+ XSync(fromDpy, False);
+
if (pDpyInfo->big != None) XMapRaised(fromDpy, pDpyInfo->big);
XGrabPointer(fromDpy, trigger, True,
PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
@@ -1223,13 +1409,16 @@ PDPYINFO pDpyInfo;
GrabModeAsync, GrabModeAsync,
CurrentTime);
XSelectInput(fromDpy, trigger, pDpyInfo->eventMask | PointerMotionMask);
- XFlush(fromDpy);
+
+ XSync(fromDpy, False);
+
} /* END DoConnect */
static void DoDisconnect(pDpyInfo)
PDPYINFO pDpyInfo;
{
Display *fromDpy = pDpyInfo->fromDpy;
+ Display *toDpy = pDpyInfo->toDpy;
PDPYXTRA pDpyXtra;
#ifdef DEBUG
@@ -1239,6 +1428,24 @@ PDPYINFO pDpyInfo;
#ifdef WIN_2_X
assert (fromDpy != fromWin);
#endif
+
+ XGetInputFocus(toDpy, &pDpyInfo->selWinTo, &pDpyInfo->selRevTo);
+ XSetInputFocus(toDpy, PointerRoot, 0, CurrentTime);
+ XSync(toDpy, False);
+
+ XFlush(fromDpy);
+
+ if (pDpyInfo->selWinFrom != None) {
+ Display *fromDpy = pDpyInfo->fromDpy;
+ Window selWinFrom = pDpyInfo->selWinFrom;
+ int selRevFrom = pDpyInfo->selRevFrom;
+ XErrorHandler old_handler = XSetErrorHandler(bad_window_handler);
+
+ XSetInputFocus(fromDpy, selWinFrom, selRevFrom, CurrentTime);
+ XSync (fromDpy, False);
+ (void) XSetErrorHandler(old_handler);
+ }
+
if (pDpyInfo->big != None) XUnmapWindow(fromDpy, pDpyInfo->big);
XUngrabKeyboard(fromDpy, CurrentTime);
XUngrabPointer(fromDpy, CurrentTime);
@@ -1251,11 +1458,14 @@ PDPYINFO pDpyInfo;
}
} /* END if */
- XFlush(fromDpy);
+ XSync(fromDpy, False);
/* force normal state on to display: */
- if (doAutoUp)
+ if (doAutoUp) {
FakeThingsUp(pDpyInfo);
+ RestoreKeyboardState();
+ }
+
} /* END DoDisconnect */
static void RegisterEventHandlers(pDpyInfo)
@@ -1280,8 +1490,6 @@ PDPYINFO pDpyInfo;
XSAVECONTEXT(fromDpy, trigger, KeyRelease, ProcessKeyEvent);
XSAVECONTEXT(fromDpy, trigger, ConfigureNotify, ProcessConfigureNotify);
XSAVECONTEXT(fromDpy, trigger, ClientMessage, ProcessClientMessage);
- XSAVECONTEXT(fromDpy, trigger, ClientMessage, ProcessClientMessage);
- XSAVECONTEXT(fromDpy, trigger, ClientMessage, ProcessClientMessage);
XSAVECONTEXT(fromDpy, None, MappingNotify, ProcessMapping);
@@ -1426,6 +1634,7 @@ XMotionEvent *pEv; /* caution: might be
XTestFakeMotionEvent(pShadow->dpy, toScreenNum, toX,
pDpyInfo->yTables[toScreenNum][pEv->y_root], 0);
XFlush(pShadow->dpy);
+ pShadow->flush = False;
} /* END for */
return False;
@@ -1493,6 +1702,7 @@ XButtonEvent *pEv;
printf("from button %d down, to button %d down\n", pEv->button,toButton);
#endif
XFlush(pShadow->dpy);
+ pShadow->flush = False;
} /* END for */
if (doAutoUp)
FakeAction(pDpyInfo, FAKE_BUTTON, toButton, True);
@@ -1520,6 +1730,8 @@ XButtonEvent *pEv;
pDpyInfo->mode = X2X_CONN_RELEASE;
}
break;
+ default:
+ break;
} /* END switch mode */
return False;
} /* END ProcessButtonPress */
@@ -1544,6 +1756,7 @@ XButtonEvent *pEv;
printf("from button %d up, to button %d up\n", pEv->button, toButton);
#endif
XFlush(pShadow->dpy);
+ pShadow->flush = False;
} /* END for */
if (doAutoUp)
FakeAction(pDpyInfo, FAKE_BUTTON, toButton, False);
@@ -1599,6 +1812,11 @@ XKeyEvent *pEv;
XLookupString(pEv, NULL, 0, &keysym, NULL);
bPress = (pEv->type == KeyPress);
+#ifdef DEBUG
+ printf("key '%s' %s (state=0x%x)\n",
+ XKeysymToString(keysym), (bPress ? "pressed" : "released"), pEv->state);
+#endif
+
/* If CapsLock is on, we need to do some funny business to make sure the */
/* "to" display does the right thing */
if(doCapsLkHack && (pEv->state & 0x2))
@@ -1612,6 +1830,9 @@ XKeyEvent *pEv;
if(((keysym >= XK_A) && (keysym <= XK_Z)) ||
((keysym >= XK_a) && (keysym <= XK_z)))
DoFakeShift = !DoFakeShift;
+#ifdef DEBUG
+ printf("DoFakeShift %d\n", DoFakeShift);
+#endif
}
for (pSticky = stickies; pSticky; pSticky = pSticky->pNext)
@@ -1627,16 +1848,21 @@ XKeyEvent *pEv;
XTestFakeKeyEvent(pShadow->dpy, keycode, False, 0);
if(DoFakeShift) XTestFakeKeyEvent(pShadow->dpy, toShiftCode, False, 0);
XFlush(pShadow->dpy);
+ pShadow->flush = False;
} /* END if */
} /* END for */
} else {
+ Bool invert = (pEv->state & 0x2) && (pEv->state & 0x1);
for (pShadow = shadows; pShadow; pShadow = pShadow->pNext) {
toShiftCode = XKeysymToKeycode(pShadow->dpy, XK_Shift_L);
if ((keycode = XKeysymToKeycode(pShadow->dpy, keysym))) {
- if(DoFakeShift) XTestFakeKeyEvent(pShadow->dpy, toShiftCode, True, 0);
+ if (invert && toShiftCode)
+ XTestFakeKeyEvent(pShadow->dpy, toShiftCode, True, 0);
XTestFakeKeyEvent(pShadow->dpy, keycode, bPress, 0);
- if(DoFakeShift) XTestFakeKeyEvent(pShadow->dpy, toShiftCode, False, 0);
+ if (invert && toShiftCode)
+ XTestFakeKeyEvent(pShadow->dpy, toShiftCode, False, 0);
XFlush(pShadow->dpy);
+ pShadow->flush = False;
} /* END if */
} /* END for */
if (doAutoUp)
@@ -1735,6 +1961,7 @@ XPropertyEvent *pEv;
if (pDpyXtra->sState == SELSTATE_WAIT) {
pDpyXtra->sState = SELSTATE_ON;
XSetSelectionOwner(dpy, XA_PRIMARY, pDpyXtra->propWin, pEv->time);
+ XSync(dpy, False);
} else if (dpy == pDpyInfo->sDpy) {
if (pDpyInfo->sTime == pEv->time) {
/* oops, need to ensure uniqueness */
@@ -1816,15 +2043,16 @@ XSelectionRequestEvent *pSelReq;
XSelectionEvent sendEv;
sendEv.type = SelectionNotify;
+ sendEv.serial = 0;
+ sendEv.send_event= pSelReq->send_event;
sendEv.display = pSelReq->display;
sendEv.requestor = pSelReq->requestor;
sendEv.selection = pSelReq->selection;
sendEv.target = pSelReq->target;
sendEv.property = pSelReq->property;
sendEv.time = pSelReq->time;
- XSendEvent(pSelReq->display, pSelReq->requestor, False, 0,
- (XEvent *)&sendEv);
-
+
+ XSendEvent(pSelReq->display, pSelReq->requestor, False, 0, (XEvent *)&sendEv);
} /* END SendSelectionNotify */
static Bool ProcessSelectionClear(dpy, pDpyInfo, pEv)
@@ -1903,24 +2131,33 @@ XMappingEvent *pEv;
static void FakeAction(pDpyInfo, type, thing, bDown)
PDPYINFO pDpyInfo;
-unsigned int thing;
+int type;
+KeySym thing;
Bool bDown;
{
+ Display *fromDpy = pDpyInfo->fromDpy;
+ KeyCode code = 0;
PFAKE *ppFake;
PFAKE pFake;
+ if (type == FAKE_KEY)
+ code = XKeysymToKeycode(fromDpy, thing);
+ else
+ code = thing;
+
/* find the associated button, or the last record, whichever comes first */
for (ppFake = &(pDpyInfo->pFakeThings);
(*ppFake &&
- (((*ppFake)->type != type) || ((*ppFake)->thing != thing)));
+ (((*ppFake)->type != type) || ((*ppFake)->code != code)));
ppFake = &((*ppFake)->pNext));
if (bDown) { /* key down */
if (*ppFake == NULL) { /* need a new record */
- pFake = (PFAKE)malloc(sizeof(FAKE));
+ pFake = (PFAKE)xmalloc(sizeof(FAKE));
pFake->pNext = NULL; /* always at the end of the list */
pFake->type = type;
pFake->thing = thing;
+ pFake->code = code;
*ppFake = pFake;
} /* END if */
} else { /* key up */
@@ -1950,22 +2187,20 @@ PDPYINFO pDpyInfo;
if (type == FAKE_KEY) { /* key goes up */
if ((keycode = XKeysymToKeycode(pShadow->dpy, pFake->thing))) {
XTestFakeKeyEvent(pShadow->dpy, keycode, False, 0);
+ pShadow->flush = True;
#ifdef DEBUG
- printf("key 0x%x up\n", pFake->thing);
+ printf("key '%s' up (fake)\n", XKeysymToString(pFake->thing));
#endif
} /* END if */
} else { /* button goes up */
XTestFakeButtonEvent(pShadow->dpy, pFake->thing, False, 0);
+ pShadow->flush = True;
#ifdef DEBUG
- printf("button %d up\n", pFake->thing);
+ printf("button %d up (fake)\n", (unsigned int)pFake->thing);
#endif
} /* END if/else */
} /* END for */
- /* flush everything at once */
- for (pShadow = shadows; pShadow; pShadow = pShadow->pNext)
- XFlush(pShadow->dpy);
-
/* get next and free current */
pNext = pFake->pNext;
free(pFake);
@@ -1974,6 +2209,13 @@ PDPYINFO pDpyInfo;
pDpyInfo->pFakeThings = NULL;
} /* END if */
+ /* flush everything at once */
+ for (pShadow = shadows; pShadow; pShadow = pShadow->pNext)
+ if (pShadow->flush) {
+ XFlush(pShadow->dpy);
+ pShadow->flush = False;
+ }
+
} /* END FakeThingsUp */
static void RefreshPointerMapping(dpy, pDpyInfo)
@@ -2060,7 +2302,7 @@ int MoveWindowToScreen(PDPYINFO pDpyInfo
printf("Using SendInput to synthesize a mouse click\n");
#endif
- pInputs = (LPINPUT) malloc (2*sizeof(INPUT));
+ pInputs = (LPINPUT) xmalloc (2*sizeof(INPUT));
pInputs[0].type = INPUT_MOUSE;
pInputs[0].mi.dx = 0;
@@ -2129,7 +2371,7 @@ int x,y;
{
#ifdef DEBUG
- printf("disconnecting\n");
+ printf("disconnecting (Win2x)\n");
#endif
pDpyInfo->mode = X2X_DISCONNECTED;
@@ -2430,7 +2672,7 @@ WinProcessMessage (HWND hwnd, UINT iMsg,
/* If the length is bad just ignore */
if (len > 0) {
if (pDpyInfo->winSelText != NULL) free(pDpyInfo->winSelText);
- pDpyInfo->winSelText = malloc(len + 10);
+ pDpyInfo->winSelText = xmalloc(len + 10);
if (pDpyInfo->winSelText != NULL)
strcpy(pDpyInfo->winSelText, lptstr);
#ifdef DEBUG
@@ -2467,6 +2709,7 @@ WinProcessMessage (HWND hwnd, UINT iMsg,
#endif
XSetSelectionOwner(pDpyInfo->toDpy, XA_PRIMARY,
pDpyInfo->toDpyXtra.propWin, CurrentTime);
+ XFlush(pDpyInfo->toDpy);
pDpyInfo->owntoXsel = 1;
}
}
@@ -2510,6 +2753,7 @@ WinProcessMessage (HWND hwnd, UINT iMsg,
for (pShadow = shadows; pShadow; pShadow = pShadow->pNext) {
XActivateScreenSaver(pShadow->dpy);
XFlush(pShadow->dpy);
+ pShadow->flush = False;
} /* END for shadow */
}
/* Fall through */
@@ -2643,6 +2887,7 @@ void WinPointerEvent(PDPYINFO pDpyInfo,
XTestFakeMotionEvent(pShadow->dpy, toScreenNum, toX,
pDpyInfo->yTables[toScreenNum][y], 0);
XFlush(pShadow->dpy);
+ pShadow->flush = False;
} /* END for */
return;
@@ -2666,6 +2911,7 @@ void WinPointerEvent(PDPYINFO pDpyInfo,
button, down ? "down":"up", toButton, down ? "down":"up");
#endif
XFlush(pShadow->dpy);
+ pShadow->flush = False;
} /* END for */
if (doAutoUp)
FakeAction(pDpyInfo, FAKE_BUTTON, toButton, down);
@@ -2693,6 +2939,7 @@ void SendButtonClick(pDpyInfo, button)
button, toButton);
#endif
XFlush(pShadow->dpy);
+ pShadow->flush = False;
} /* END for */
#ifdef DEBUG
else
@@ -2963,6 +3210,7 @@ void SendKeyEvent(PDPYINFO pDpyInfo, Key
XTestFakeKeyEvent(pShadow->dpy, keycode, down, 0);
XFlush(pShadow->dpy);
+ pShadow->flush = False;
} /* END if */
} /* END for */
if (doAutoUp)
@@ -3100,3 +3348,14 @@ XSelectionEvent *pEv;
} /* END ProcessSelectionNotify */
#endif /* WIN_2_X only routines */
+
+static void *xmalloc(size)
+size_t size;
+{
+ void * ptr = malloc(size);
+ if (!ptr) {
+ fprintf(stderr, "%s - error: %s\n", programStr, strerror(errno));
+ exit(1);
+ }
+ return memset(ptr, 0, size);
+}