pax_global_header00006660000000000000000000000064120715427660014524gustar00rootroot0000000000000052 comment=49c3131bff4a93c52c692c5a352c556ace5ec537 x2x-1.30/000077500000000000000000000000001207154276600121705ustar00rootroot00000000000000x2x-1.30/.gitignore000066400000000000000000000003271207154276600141620ustar00rootroot00000000000000*.o .deps/ /INSTALL /aclocal.m4 /autom4te.cache/ /config.guess /config.h /config.h.in /config.log /config.status /config.sub /configure /depcomp /install-sh /lawyerese.c /missing /stamp-h1 /x2x Makefile Makefile.in x2x-1.30/AUTHORS000066400000000000000000000004741207154276600132450ustar00rootroot00000000000000* David Chaiken Original version author * Charles Briscoe-Smith -north, -south options. Various patches. * Mark Hayter Cygwin version, -fromwin to allow using Windows as source display. * Snow Windows version patches * Mikhail Gusarov Maintainer x2x-1.30/COPYING000066400000000000000000000031251207154276600132240ustar00rootroot00000000000000Copyright (c) 1997 Digital Equipment Corporation. All rights reserved. By downloading, installing, using, modifying or distributing this software, you agree to the following: 1. CONDITIONS. Subject to the following conditions, you may download, install, use, modify and distribute this software in source and binary forms: a) Any source code, binary code and associated documentation (including the online manual) used, modified or distributed must reproduce and retain the above copyright notice, this list of conditions and the following disclaimer. b) No right is granted to use any trade name, trademark or logo of Digital Equipment Corporation. Neither the ''Digital Equipment Corporation'' name nor any trademark or logo of Digital Equipment Corporation may be used to endorse or promote products derived from this software without the prior written permission of Digital Equipment Corporation. 2. DISCLAIMER. THIS SOFTWARE IS PROVIDED BY DIGITAL ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL DIGITAL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. x2x-1.30/COPYING.win32000066400000000000000000000025401207154276600141650ustar00rootroot00000000000000Cygwin version with -fromwin to allow source to be a Windows machine that is not running a X server. Adapted by Mark Hayter 2003 using win2vnc ClientConnect.cpp code. The win2vnc code was itself adapted from vncviewer for windows win2vnc, adapted from vncviewer by Fredrik Hubinette 2001. Original vncviewer copyright follows: Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. This file is part of the VNC system. The VNC system is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by he Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. If the source code for the VNC system is not available from the place whence you received this file, check http://www.uk.research.att.com/vnc or contact the authors on vnc@uk.research.att.com for information on obtaining it. Original x2x copyright follows: x2x-1.30/ChangeLog000066400000000000000000000001511207154276600137370ustar00rootroot000000000000002008-03-18 - autotools-based build instead of Imake-based - lawyerese.c is now generated from COPYING.* x2x-1.30/ChangeLog.old000066400000000000000000000065531207154276600145300ustar00rootroot00000000000000RCS 1.1 -nAlpha1 : First release for Puneet and David to play with Files: Imakefile format.c format.h keymap.c keymap.h lawyerese.c x2x.1 x2x.c 22 Sept 03 released Alpha2 -------------------------- - Modify Imakefile to recognize cygwin or not - Adapt to load null cursor - Add Windows resources (for cursor, but alos has version info) - Initializae some variables (unused in -fromwin) to keep compiler happy - Add casts in printfs to remover warnings - Don't grab clipboard from X if its what we added to Windows - Force redraw when big window goes away (may not be strictly needed) - Intersept windows screenblank and forward to X if connected - Intersept ERASEBKGND and prevent Windows drawing black in big window - Don't register for property notify (on -to) in fromWin case - Bump version to 1.30 per Chaiken Add files: resource.h nocursor.cur (copy from win2vnc) x2xwin.rc (resource description) 02 Oct 03 released Alpha3 - After MAX_UNREASONABLES "unreasonable" coordinates they become reasonable (helps recovery from errors that would otherwise loose the mouse) - Add 1 second tick to cause X events to be polled, sets max bound when doing a paste to the X side [bug from pkumar] - Check number of buttons on -to side and don't send mousewheel events if buttons 4/5 are not ok. [bug from chaiken] - Check for not becomming foreground, and try to recover, become aggresive if events are turning up on the wrong window [Bug from Thomas] - Fix cursor warp (west) so it goes one left of return coordinate [Bug from Thomas] - Extra message printing if -DDEBUGCHATTY [mdh] - Version of -capslockhack code in Windows KeyEvent processing [Bug from Thomas and mdh] - Add magic key sequences for -fromwin: RightAlt-Home to force cursor back to Windows RightAlt-End to exit x2x - Known issue: Both left and right shift keys on Windows cause left shift on X. - make -fromwin imply -capslockhack, and add -nocapslockhack option - Fix to allow -east work before -fromwin on command line [Bug from Thomas] - Add comment in usage with Thomas' tip on making a shortcut to launch x2x - Fix Imakefile LOCAL_LIBRARIES to only include windows libs on cygwin - Add comments on -D to Imakefile Changed files: Imakefile keymap.c x2x.c x2xwin.rc (bump version) Added files: winmsg.c - This is a quick hack to turn Windows message numbers into a string so I can print them. Only when -DDEBUGCHATTY 27 Oct 2003 Beta 1 ------------------ - Added code from Thomas Chadwick to save Windows focus when going to X and restore on the way back (good for click-to-focus) - Added code from Thomas Chadwick to send a fake mouse click to Windows when x2x is havig problems getting the focus (good for click-to-focus) - Support the -buttonblock flag in the -fromwin code - Add description of -fromwin to the manpage - Make man file x2x.man so that the makefile will build x2x.1.html and the install will install x2x.1 - Add to BUGS section of the man page that Ctrl-Alt-Del on the Windows side will leave the Ctrl and Alt keys stuck down on the X server and that pressing and releasing Ctrl and Alt should fix this. - Default to no -DDEBUG - Bump version to Beta - Add -clipcheck option and relax clipboard copy checking to windows if it is not given (allows other than plain XA_STRING copies, eg emacs keeps giving me a COMPOUND_TEXT type) Changed files: x2x.c x2x.man x2xwin.rc Imakefile x2x-1.30/INSTALL000066400000000000000000000001751207154276600132240ustar00rootroot00000000000000Just build/install x2x as any other autotools-based program. Configuration options: --with-win32 - enables win32 support x2x-1.30/Makefile.am000066400000000000000000000020071207154276600142230ustar00rootroot00000000000000# # Copyright (c) 2008 Mikhail Gusarov # # BSD-3 # AM_CFLAGS = $(X11_CFLAGS) -Wall AM_LDFLAGS = $(X11_LIBS) bin_PROGRAMS = x2x x2x_SOURCES = x2x.c nodist_x2x_SOURCES = lawyerese.c dist_man1_MANS = x2x.1 # -- win32 support -- if WIN32 AM_CFLAGS += -DWIN_2_X AM_LDFLAGS += -luser32 -lgdi32 # Ugly hack x2x_SOURCES += keymap.c winmsg.c x2xwin.rc .o:.rc windres $^ -o $@ x2xwin.o: resource.h nocursor.cur endif # -- creating lawyerese.c -- if WIN32 COPYING_FILES = COPYING.win32 else COPYING_FILES = endif COPYING_FILES += COPYING lawyerese.c: $(COPYING_FILES) echo 'char *lawyerese =' > $@.tmp && \ sed -e 's|.*|"\0\\n"|g' $^ >> $@.tmp && \ echo ";" >> $@.tmp && \ mv $@.tmp $@ || rm -f $@.tmp CLEANFILES = lawyerese.c # -- Various -- dist_doc_DATA = AUTHORS ChangeLog ChangeLog.old COPYING COPYING.win32 \ README docs/HostBasedAuthentication.txt \ docs/MIT-MAGIC-COOKIE-1.txt docs/SshTunneling.txt \ docs/X2xUsage.txt EXTRA_DIST = keymap.h nocursor.cur resource.h x2x-1.30/README000066400000000000000000000020031207154276600130430ustar00rootroot00000000000000x2x === Overview -------- x2x allows the keyboard, mouse on one X display to be used to control another X display. It also shares X clipboards between the displays. When built/run on Cygwin it may be run on Windows desktop to control X display. License ------- x2x is under MIT/BSD license. Windows support includes code under GPL2 or later. Call for help ------------- x2x has a long history. It was born in the times when life was hard, window managers were simple and displays were rectangle. Several implicit assumptions survived during the x2x lifetime, and now need reconsideration. As x2x is simple (however, it has accumulated inner knowledge of X11 implementations), we are looking for brave person who can read and understand whole x2x and will write new x2x, adapted to the modern life of dynamically attached and detached displays, complex data transferring through the X selections and Xinerama. Authors ------- x2x was initially developed in DEC by David Chaiken. Current maintainer is Mikhail Gusarov. x2x-1.30/bootstrap.sh000077500000000000000000000000331207154276600145400ustar00rootroot00000000000000#!/bin/sh autoreconf -isv x2x-1.30/configure.ac000066400000000000000000000020021207154276600144500ustar00rootroot00000000000000dnl dnl Copyright (c) 2008 Mikhail Gusarov dnl dnl BSD-3 dnl AC_PREREQ([2.69]) AC_INIT([x2x],[1.30-rc1],[http://x2x.dottedmag.net/newticket],[x2x],[http://x2x.dottedmag.net]) AM_INIT_AUTOMAKE([foreign dist-bzip2]) AC_CONFIG_SRCDIR([x2x.c]) # config.h is unused but generating it avoids compiler invocation clutter. AC_CONFIG_HEADERS([config.h]) AC_PROG_CC AC_PROG_INSTALL ## This PKG_CHECK_MODULES can be replaced by the following three ## AC_CHECK_LIBs and the non-Cygwin setting of AM_LDFLAGS and ## AM_CFLAGS in Makefile.am removed. PKG_CHECK_MODULES(X11, xext xtst x11) # AC_CHECK_LIB([X11], [XOpenDisplay]) # AC_CHECK_LIB([Xext], [XextFindDisplay]) # AC_CHECK_LIB([Xtst], [XTestFakeKeyEvent]) AC_ARG_ENABLE([win32], AS_HELP_STRING( [--enable-win32], [enable Win32 support (-fromwin option). Disabled by default])) AC_SUBST(X11_CFLAGS) AC_SUBST(X11_LIBS) AC_SUBST(enable_win32) AM_CONDITIONAL(WIN32, [test x$enable_win32 = xyes]) AC_CONFIG_FILES([Makefile]) AC_OUTPUT x2x-1.30/docs/000077500000000000000000000000001207154276600131205ustar00rootroot00000000000000x2x-1.30/docs/HostBasedAuthentication.txt000066400000000000000000000024721207154276600204420ustar00rootroot00000000000000X server may be configured to allow """any""" connection from specified host. `xhost` is the utility allowing to control what hosts are allowed to connect. Basic synopsis is ||`xhost -`||enables host authentication protocol: only authenticated hosts may connect.|| ||`xhost +`||disables any security protocols: any host may connect|| ||`xhost +host`||adds specified host to the allowed hosts list|| ||`xhost -host`||removes host from the allowed hosts list|| `host` may contain `inet:hostname` to allow clients from `hostname` to connect, `local` to allow connection from local clients and other, less used now, forms. For the full information about xhost read `xhost(1x)` manual page and `Xsecurity(7x)` manual pages. It is highly insecure to use host-based authentication protocols in the non-controlled networks, so you should probably consider using other authentication protocol, such as [wiki:MIT-MAGIC-COOKIE-1], or even SshTunneling. But in some cases, such as virtual machines inside one hardware machine, host-based authentication is ok. Example configuration using host-based authentication is the following: `host1` runs `x2x` and wants to control display on `host2`. On the host2: {{{ host2% echo $DISPLAY :0.0 host2% xhost +inet:host1 (or just 'xhost +host1') host2% }}} On the host1: {{{ host1% x2x -to host2:0 }}} x2x-1.30/docs/MIT-MAGIC-COOKIE-1.txt000066400000000000000000000031171207154276600162370ustar00rootroot00000000000000[wiki:MIT-MAGIC-COOKIE-1] is much more secure authentication protocol than HostBasedAuthentication: it uses private tokens to authenicate clients trying to access X server: token is bound to the X server and vaild only during one session. Authentication tokens are generated at server startup and stored at `.Xauthority` file in user home directory. Any X application trying to access the display reads authentication token corresponding to the display from this file (or from the file variable XAUTHORITY points to if this variable exists) and passes this token to the server. `xauth` program is designed to manipulate authentication tokens. Two most interesting for us commands of xauth are ||`xauth nextract`||extracts the authentication token from `.Xauthority` file.|| ||`xauth nmerge`||adds the authentication token, extracted by `nextract`, to the `.Xauthority` file|| ('n' here means 'numeric format' as opposed to the 'binary': numeric format contains only printable symbols). You also can list installed to the `.Xauthority` authentication tokens by using `xauth nlist`. Example configuration is the same as in HostBasedAuthentication: `host1` runs `x2x` and wants to control display on `host2`. On the host2: {{{ host2% echo $DISPLAY :0.0 host2% xauth nextract - :0.0 host2% }}} On the host1: {{{ host1% xauth nmerge - host1% x2x -to host2:0 }}} This authentication method is a bit more complicated than host-based, but much more secure, and you should prefer it unless you know exactly what are you doing. x2x-1.30/docs/SshTunneling.txt000066400000000000000000000031421207154276600163020ustar00rootroot00000000000000You can use SSH to easily make `x2x` link two displays together. SSH provides the options to tunnel the X traffic from the host you are connecting to the host you are connected from. SSH propagates authentication token from the local host to the remote host, and creates tunnel. For example, if you have access token to the `$DISPLAY` on the local host, it will propagate authentication token to the remote host, and forward local X connection to the display like `localhost:10` on the remote host. SSH server and client have number of options to control the behavior of the forwarding. The most frequently used options are listed in the table below: ssh server options (`/etc/ssh/sshd_config`) ||`X11Forwarding`||Specifies whether forwarding is allowed. May be 'yes' or 'no'.|| ||`X11DisplayOffset`||Specifies first display number to be used. By default it is '10', which means tunnel will be established from the `localhost:10` display. || ||`X11UseLocalhost`||Specifies whether listening socket will be bound to the localhost only or to the all available network interfaces.|| ssh client options (`~/.ssh/config`, `/etc/ssh/ssh_config`) ||`ForwardX11` (command-line switches -X and -x)||Specifies whether to forward X connection to the remote host. Option -X enables forwarding, -x disables it.|| Full list of options is contained in man pages ssh(1), ssh_config(5) and sshd_config(5). Example configuration. host1 runs x2x and wants to control display on host2. On the host1: {{{ host1% echo $DISPLAY :0.0 host1% }}} On the host2: {{{ host2% ssh host1 Password: host1% echo $DISPLAY localhost:10 host1% x2x -from :0 }}} x2x-1.30/docs/X2xUsage.txt000066400000000000000000000016501207154276600153310ustar00rootroot00000000000000x2x links two X displays together so you can use single mouse and keyboard to control them. Your keyboard and mouse works as usual on the display they attached to, until you switch display (by clicking x2x window, or moving mouse to the edge of screen, depending of the options passed to x2x), and then all your input goes to the second display. X selection data also propagates as expected. ''Right now there are glitches with transferring non-ASCII X selection data: GTK and QT applications expose strange behavior, while Tk and Xaw applications work properly (see the ticket #7).'' Surely, accessing remote displays is a subject of authentication. x2x uses regular X11 authorization methods, so this should not be so much trouble, but we are providing quick howto for the uninitiated :) X11 use HostBasedAuthentication and [wiki:MIT-MAGIC-COOKIE-1] protocols. Also SshTunneling may be used for the access to the remote displays. x2x-1.30/keymap.c000066400000000000000000000167251207154276600136350ustar00rootroot00000000000000// This file comes from the vncviewer source // Converted to C from C++ and used in -fromwin version of x2x // 2003 By Mark Hayter // Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. // // This file is part of the VNC system. // // The VNC system is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, // USA. // // If the source code for the VNC system is not available from the place // whence you received this file, check http://www.uk.research.att.com/vnc or contact // the authors on vnc@uk.research.att.com for information on obtaining it. // Thanks to Martin C. Mueller for assistance with the // international keyboard mapping stuff. // KeyMap.cpp #ifdef WIN_2_X #include #include #define XK_MISCELLANY #define XK_LATIN1 #define XK_XKB_KEYS #include "keymap.h" // Define the keymap structure typedef struct vncKeymapping_struct { unsigned int wincode; KeySym Xcode; } vncKeymapping; static const vncKeymapping keymap[] = { {VK_BACK, XK_BackSpace}, {VK_TAB, XK_Tab}, {VK_CLEAR, XK_Clear}, {VK_RETURN, XK_Return}, {VK_LSHIFT, XK_Shift_L}, {VK_RSHIFT, XK_Shift_L}, /* XXX mdh - never gen SHIFT_R */ {VK_SHIFT, XK_Shift_L}, {VK_LCONTROL, XK_Control_L}, {VK_RCONTROL, XK_Control_R}, {VK_CONTROL, XK_Control_L}, {VK_LMENU, XK_Alt_L}, {VK_RMENU, XK_Alt_R}, {VK_MENU, XK_Alt_L}, {VK_PAUSE, XK_Pause}, {VK_CAPITAL, XK_Caps_Lock}, {VK_ESCAPE, XK_Escape}, {VK_SPACE, XK_space}, {VK_PRIOR, XK_Page_Up}, {VK_NEXT, XK_Page_Down}, {VK_END, XK_End}, {VK_HOME, XK_Home}, {VK_LEFT, XK_Left}, {VK_UP, XK_Up}, {VK_RIGHT, XK_Right}, {VK_DOWN, XK_Down}, {VK_SELECT, XK_Select}, {VK_EXECUTE, XK_Execute}, {VK_SNAPSHOT, XK_Print}, {VK_INSERT, XK_Insert}, {VK_DELETE, XK_Delete}, {VK_HELP, XK_Help}, {VK_NUMPAD0, XK_KP_0}, {VK_NUMPAD1, XK_KP_1}, {VK_NUMPAD2, XK_KP_2}, {VK_NUMPAD3, XK_KP_3}, {VK_NUMPAD4, XK_KP_4}, {VK_NUMPAD5, XK_KP_5}, {VK_NUMPAD6, XK_KP_6}, {VK_NUMPAD7, XK_KP_7}, {VK_NUMPAD8, XK_KP_8}, {VK_NUMPAD9, XK_KP_9}, {VK_MULTIPLY, XK_KP_Multiply}, {VK_ADD, XK_KP_Add}, {VK_SEPARATOR, XK_KP_Separator}, // often comma {VK_SUBTRACT, XK_KP_Subtract}, {VK_DECIMAL, XK_KP_Decimal}, {VK_DIVIDE, XK_KP_Divide}, {VK_F1, XK_F1}, {VK_F2, XK_F2}, {VK_F3, XK_F3}, {VK_F4, XK_F4}, {VK_F5, XK_F5}, {VK_F6, XK_F6}, {VK_F7, XK_F7}, {VK_F8, XK_F8}, {VK_F9, XK_F9}, {VK_F10, XK_F10}, {VK_F11, XK_F11}, {VK_F12, XK_F12}, {VK_F13, XK_F13}, {VK_F14, XK_F14}, {VK_F15, XK_F15}, {VK_F16, XK_F16}, {VK_F17, XK_F17}, {VK_F18, XK_F18}, {VK_F19, XK_F19}, {VK_F20, XK_F20}, {VK_F21, XK_F21}, {VK_F22, XK_F22}, {VK_F23, XK_F23}, {VK_F24, XK_F24}, {VK_NUMLOCK, XK_Num_Lock}, {VK_SCROLL, XK_Scroll_Lock} }; static unsigned char buf[4]; static unsigned char keystate[256]; KeyActionSpec PCtoX(UINT virtkey, DWORD keyData) { int numkeys = 0; int mapsize, i; int extended; int ret; KeyActionSpec kas; kas.releaseModifiers = 0; extended = ((keyData & 0x1000000) != 0); #ifdef DEBUG printf(" keyData %04x ", (unsigned int) keyData); #endif if (extended) { #ifdef DEBUG printf(" (extended) "); #endif switch (virtkey) { case VK_MENU : virtkey = VK_RMENU; break; case VK_CONTROL: virtkey = VK_RCONTROL; break; } } // We try looking it up in our table mapsize = sizeof(keymap) / sizeof(vncKeymapping); // Look up the desired code in the table for (i = 0; i < mapsize; i++) { if (keymap[i].wincode == virtkey) { kas.keycodes[numkeys++] = keymap[i].Xcode; break; } } if (numkeys != 0) { #ifdef DEBUG UINT key = kas.keycodes[numkeys-1]; printf("keymap gives %u (%x) ", key, key); #endif } else { // not found in table #ifdef DEBUG printf("not in special keymap, "); #endif // we try a simple conversion to Ascii, using the current keyboard mapping GetKeyboardState(keystate); ret = ToAscii(virtkey, 0, keystate, (WORD *) buf, 0); // If Left Ctrl & Alt both pressed and ToAscii gives a valid keysym // This is for AltGr on international keyboards (= LCtrl-Alt). // e.g. Ctrl-Alt-Q gives @ on German keyboards if ( ((keystate[VK_MENU] & 0x80) != 0) && ((keystate[VK_CONTROL] & 0x80) != 0) ) { // If the key means anything in this keyboard layout if ( (ret >= 1) && ( ( (*buf >= 32) && (*buf <= 126) ) || ( (*buf >= 160) && (*buf <= 255) ) ) ) { // Send the modifiers up, then the keystroke, then mods down // We don't release the right control; this allows German users // to use it for doing Ctl-@ etc. (though not under Win95 -- // see below) if (GetKeyState(VK_LCONTROL) & 0x8000) kas.releaseModifiers |= KEYMAP_LCONTROL; if (GetKeyState(VK_LMENU) & 0x8000) kas.releaseModifiers |= KEYMAP_LALT; if (GetKeyState(VK_RMENU) & 0x8000) kas.releaseModifiers |= KEYMAP_RALT; // This is for windows 95, and possibly other systems. // The above GetKeyState calls don't work in 95 - they always return 0. // But if we're here at all we know that control and alt are pressed, so let's // raise all Control and Alt keys if we haven't registered any yet. if (kas.releaseModifiers == 0) kas.releaseModifiers = KEYMAP_LCONTROL | KEYMAP_LALT | KEYMAP_RALT; #ifdef DEBUG printf("Ctrl-Alt pressed ToAscii(without modifiers)returns %d bytes: ", ret); #endif for (i = 0; i < ret; i++) { kas.keycodes[numkeys++] = *(buf+i); #ifdef DEBUG printf("%02x (%c) ", *(buf+i) , *(buf+i)); #endif } #ifdef DEBUG printf("\n"); #endif } } // If not a ctrl-alt key if (numkeys == 0) { // There are no keysyms corresponding to control characters // Eg Ctrl F. The server already knows whether the control // key is pressed. So we are interested in the key that would be // there if the Ctrl were not pressed. keystate[VK_CONTROL] = keystate[VK_LCONTROL] = keystate[VK_RCONTROL] = 0; ret = ToAscii(virtkey, 0, keystate, (WORD *) buf, 0); if (ret < 0) { switch (*buf) { case '`' : kas.keycodes[numkeys++] = XK_dead_grave; break; case '\'' : kas.keycodes[numkeys++] = XK_dead_acute; break; case '~' : kas.keycodes[numkeys++] = XK_dead_tilde; break; case '^': kas.keycodes[numkeys++] = XK_dead_circumflex; break; } } // if this works, and it's a regular printable character, just send that if (ret >= 1) { #ifdef DEBUG printf("ToAscii (without ctrl) returns %d byte(s): ", ret); #endif for (i = 0; i < ret; i++) { kas.keycodes[numkeys++] = *(buf+i); #ifdef DEBUG printf("%02x (%c) ", *(buf+i) , *(buf+i)); #endif } } } } kas.keycodes[numkeys] = VoidKeyCode; return kas; } #endif x2x-1.30/keymap.h000066400000000000000000000037121207154276600136320ustar00rootroot00000000000000 // This file comes from the vncviewer source // Converted to C from C++ and used in -fromwin version of x2x // 2003 By Mark Hayter // Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. // // This file is part of the VNC system. // // The VNC system is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, // USA. // // If the source code for the VNC system is not available from the place // whence you received this file, check http://www.uk.research.att.com/vnc or contact // the authors on vnc@uk.research.att.com for information on obtaining it. // KeyMap.h // mapping of windows virtual key codes to X keysyms. #include #include // A single key press on the client may result in more than one // going to the server. #define MaxKeysPerKey 4 #define VoidKeyCode XK_VoidSymbol // keycodes contains the keysyms terminated by an VoidKeyCode. // The releaseModifiers is a set of ORed flags indicating whether // particular modifier-up messages should be sent before the keys // and modifier-down after. #define KEYMAP_LCONTROL 0x0001 #define KEYMAP_RCONTROL 0x0002 #define KEYMAP_LALT 0x0004 #define KEYMAP_RALT 0x0008 typedef struct { KeySym keycodes[MaxKeysPerKey]; int releaseModifiers; } KeyActionSpec; KeyActionSpec PCtoX(unsigned int virtkey, DWORD keyData); x2x-1.30/nocursor.cur000066400000000000000000000005061207154276600145560ustar00rootroot00000000000000 0( @ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿx2x-1.30/resource.h000066400000000000000000000001101207154276600141600ustar00rootroot00000000000000// Communication between the .rc file and code #define IDC_NOCURSOR 100 x2x-1.30/winmsg.c000066400000000000000000000132151207154276600136420ustar00rootroot00000000000000/* Code to print windows messages */ /* mdh 9/30/03 */ #ifdef DEBUGCHATTY /* This table generated from cygwin /usr/include/w32api/winuser.h * with : * grep WM_ /usr/include/w32api/winuser.h | * sed 's/#define \([^ ]*\) \(.*\)/{\2,\"\1\"},/' > foo * then edited! */ #define WM_USER 1024 struct wmsginfo { int num; char *msg }; struct wmsginfo msginfo[] = { {6,"WM_ACTIVATE"}, {28,"WM_ACTIVATEAPP"}, /* FIXME/CHECK: Are WM_AFX{FIRST,LAST} valid for WINVER < 0x400? */ {864,"WM_AFXFIRST"}, {895,"WM_AFXLAST"}, {780,"WM_ASKCBFORMATNAME"}, {75,"WM_CANCELJOURNAL"}, {31,"WM_CANCELMODE"}, {533,"WM_CAPTURECHANGED"}, {781,"WM_CHANGECBCHAIN"}, {258,"WM_CHAR"}, {47,"WM_CHARTOITEM"}, {34,"WM_CHILDACTIVATE"}, {771,"WM_CLEAR"}, {16,"WM_CLOSE"}, {273,"WM_COMMAND"}, {68 /* obsolete */,"WM_COMMNOTIFY"}, {65,"WM_COMPACTING"}, {57,"WM_COMPAREITEM"}, {123,"WM_CONTEXTMENU"}, {769,"WM_COPY"}, {74,"WM_COPYDATA"}, {1,"WM_CREATE"}, {309,"WM_CTLCOLORBTN"}, {310,"WM_CTLCOLORDLG"}, {307,"WM_CTLCOLOREDIT"}, {308,"WM_CTLCOLORLISTBOX"}, {306,"WM_CTLCOLORMSGBOX"}, {311,"WM_CTLCOLORSCROLLBAR"}, {312,"WM_CTLCOLORSTATIC"}, {768,"WM_CUT"}, {259,"WM_DEADCHAR"}, {45,"WM_DELETEITEM"}, {2,"WM_DESTROY"}, {775,"WM_DESTROYCLIPBOARD"}, {537,"WM_DEVICECHANGE"}, {27,"WM_DEVMODECHANGE"}, {126,"WM_DISPLAYCHANGE"}, {776,"WM_DRAWCLIPBOARD"}, {43,"WM_DRAWITEM"}, {563,"WM_DROPFILES"}, {10,"WM_ENABLE"}, {22,"WM_ENDSESSION"}, {289,"WM_ENTERIDLE"}, {529,"WM_ENTERMENULOOP"}, {561,"WM_ENTERSIZEMOVE"}, {20,"WM_ERASEBKGND"}, {530,"WM_EXITMENULOOP"}, {562,"WM_EXITSIZEMOVE"}, {29,"WM_FONTCHANGE"}, {135,"WM_GETDLGCODE"}, {49,"WM_GETFONT"}, {51,"WM_GETHOTKEY"}, {127,"WM_GETICON"}, {36,"WM_GETMINMAXINFO"}, {13,"WM_GETTEXT"}, {14,"WM_GETTEXTLENGTH"}, /* FIXME/CHECK: Are WM_HANDHEL{FIRST,LAST} valid for WINVER < 0x400? */ {856,"WM_HANDHELDFIRST"}, {863,"WM_HANDHELDLAST"}, {83,"WM_HELP"}, {786,"WM_HOTKEY"}, {276,"WM_HSCROLL"}, {782,"WM_HSCROLLCLIPBOARD"}, {39,"WM_ICONERASEBKGND"}, {272,"WM_INITDIALOG"}, {278,"WM_INITMENU"}, {279,"WM_INITMENUPOPUP"}, {81,"WM_INPUTLANGCHANGE"}, {80,"WM_INPUTLANGCHANGEREQUEST"}, {256,"WM_KEYDOWN"}, {257,"WM_KEYUP"}, {8,"WM_KILLFOCUS"}, {546,"WM_MDIACTIVATE"}, {551,"WM_MDICASCADE"}, {544,"WM_MDICREATE"}, {545,"WM_MDIDESTROY"}, {553,"WM_MDIGETACTIVE"}, {552,"WM_MDIICONARRANGE"}, {549,"WM_MDIMAXIMIZE"}, {548,"WM_MDINEXT"}, {564,"WM_MDIREFRESHMENU"}, {547,"WM_MDIRESTORE"}, {560,"WM_MDISETMENU"}, {550,"WM_MDITILE"}, {44,"WM_MEASUREITEM"}, {290,"WM_MENURBUTTONUP"}, {288,"WM_MENUCHAR"}, {287,"WM_MENUSELECT"}, {531,"WM_NEXTMENU"}, {3,"WM_MOVE"}, {534,"WM_MOVING"}, {134,"WM_NCACTIVATE"}, {131,"WM_NCCALCSIZE"}, {129,"WM_NCCREATE"}, {130,"WM_NCDESTROY"}, {132,"WM_NCHITTEST"}, {163,"WM_NCLBUTTONDBLCLK"}, {161,"WM_NCLBUTTONDOWN"}, {162,"WM_NCLBUTTONUP"}, {169,"WM_NCMBUTTONDBLCLK"}, {167,"WM_NCMBUTTONDOWN"}, {168,"WM_NCMBUTTONUP"}, {160,"WM_NCMOUSEMOVE"}, {133,"WM_NCPAINT"}, {166,"WM_NCRBUTTONDBLCLK"}, {164,"WM_NCRBUTTONDOWN"}, {165,"WM_NCRBUTTONUP"}, {40,"WM_NEXTDLGCTL"}, {531,"WM_NEXTMENU"}, {78,"WM_NOTIFY"}, {85,"WM_NOTIFYFORMAT"}, {0,"WM_NULL"}, {15,"WM_PAINT"}, {777,"WM_PAINTCLIPBOARD"}, {38,"WM_PAINTICON"}, {785,"WM_PALETTECHANGED"}, {784,"WM_PALETTEISCHANGING"}, {528,"WM_PARENTNOTIFY"}, {770,"WM_PASTE"}, {896,"WM_PENWINFIRST"}, {911,"WM_PENWINLAST"}, {72,"WM_POWER"}, {536,"WM_POWERBROADCAST"}, {791,"WM_PRINT"}, {792,"WM_PRINTCLIENT"}, {55,"WM_QUERYDRAGICON"}, {17,"WM_QUERYENDSESSION"}, {783,"WM_QUERYNEWPALETTE"}, {19,"WM_QUERYOPEN"}, {35,"WM_QUEUESYNC"}, {18,"WM_QUIT"}, {774,"WM_RENDERALLFORMATS"}, {773,"WM_RENDERFORMAT"}, {32,"WM_SETCURSOR"}, {7,"WM_SETFOCUS"}, {48,"WM_SETFONT"}, {50,"WM_SETHOTKEY"}, {128,"WM_SETICON"}, {11,"WM_SETREDRAW"}, {12,"WM_SETTEXT"}, {26,"WM_SETTINGCHANGE"}, {24,"WM_SHOWWINDOW"}, {5,"WM_SIZE"}, {779,"WM_SIZECLIPBOARD"}, {532,"WM_SIZING"}, {42,"WM_SPOOLERSTATUS"}, {125,"WM_STYLECHANGED"}, {124,"WM_STYLECHANGING"}, {262,"WM_SYSCHAR"}, {21,"WM_SYSCOLORCHANGE"}, {274,"WM_SYSCOMMAND"}, {263,"WM_SYSDEADCHAR"}, {260,"WM_SYSKEYDOWN"}, {261,"WM_SYSKEYUP"}, {82,"WM_TCARD"}, {30,"WM_TIMECHANGE"}, {275,"WM_TIMER"}, {772,"WM_UNDO"}, {1024,"WM_USER"}, {84,"WM_USERCHANGED"}, {46,"WM_VKEYTOITEM"}, {277,"WM_VSCROLL"}, {778,"WM_VSCROLLCLIPBOARD"}, {71,"WM_WINDOWPOSCHANGED"}, {70,"WM_WINDOWPOSCHANGING"}, {26,"WM_WININICHANGE"}, {256,"WM_KEYFIRST"}, {264,"WM_KEYLAST"}, { 136,"WM_SYNCPAINT"}, {33,"WM_MOUSEACTIVATE"}, {512,"WM_MOUSEMOVE"}, {513,"WM_LBUTTONDOWN"}, {514,"WM_LBUTTONUP"}, {515,"WM_LBUTTONDBLCLK"}, {516,"WM_RBUTTONDOWN"}, {517,"WM_RBUTTONUP"}, {518,"WM_RBUTTONDBLCLK"}, {519,"WM_MBUTTONDOWN"}, {520,"WM_MBUTTONUP"}, {521,"WM_MBUTTONDBLCLK"}, {522,"WM_MOUSEWHEEL"}, {512,"WM_MOUSEFIRST"}, {522,"WM_MOUSELAST"}, {0x2A1, "WM_MOUSEHOVER"}, {0x2A3, "WM_MOUSELEAVE"}, {WM_USER,"DM_GETDEFID"}, {(WM_USER+1),"DM_SETDEFID"}, {(WM_USER+2),"DM_REPOSITION"}, {(WM_USER+100),"PSM_PAGEINFO"}, {(WM_USER+101),"PSM_SHEETINFO"}, {0xc,"HELP_WM_HELP"}, {32768,"WM_APP"} }; #define MAX_TEXT 2048 static char *msgstr[MAX_TEXT]; static char *unknown = "(unknown)"; static int need_init = 1; char *msgtotext(int msg) { int i; if (need_init) { printf("Init messages\n"); for (i=0; i < MAX_TEXT; i++) msgstr[i] = unknown; for (i=0; msginfo[i].num < 32767; i++) { if (msginfo[i].num >= MAX_TEXT) printf("Warning: ignore %d, %s\n", msginfo[i].num, msginfo[i].msg); else { if (msgstr[msginfo[i].num] != unknown) printf("Warning: duplicate %d %s and %s\n", msginfo[i].num, msgstr[msginfo[i].num], msginfo[i].msg); else msgstr[msginfo[i].num] = msginfo[i].msg; } } need_init = 0; } if (msg >= MAX_TEXT) return unknown; else return msgstr[msg]; } #else /* not DEBUGCHATTY */ char *msgtotext(int msg) { return "(msgtotext)"; } #endif /* DEBUGCHATTY */ x2x-1.30/x2x.1000066400000000000000000000275411207154276600130040ustar00rootroot00000000000000.nh .TH x2x 1 .SH NAME x2x \- X to X connection .SH SYNTAX \fB x2x\fR <[\-to ] | [\-fromwin | \-from ]> [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, the "to" X display must support XTEST. If x2x is built under Cygwin (on Windows XP or Windows 2000) then the \-fromwin option may be specified to allow the "from" display to be the Windows desktop. (The Cygwin build also supports use of an X display for the "from" screen). Use of \-fromwin sets the default behaviour as if the \-big \-west \-capslockhack options had also been given. In the default interface, x2x puts a window on the "from" display. This window is labeled with the name of the "to" display. Keystrokes typed into this window go to the window on the "to" display that has the input focus. Clicking on the x2x window causes the mouse on the "from" display to control the cursor on the "to" display. Performing a subsequent multiple button click on the "to" display returns control to the "from" display. If the \-fromwin, \-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. (If \-fromwin is specified then the X selection is relayed to and from the Windows clipboard as text strings). Here are a few hints for eXcursion users (based on Intel version 2.1.309). First, use the \-big option. Second, in the control panel, under mouse, check the box that enables "Automatically Capture Text on Button Up." X selections will then automatically move into the Windows clipboard. As is the case with all X applications running on 2.1.309 (including x2x), you will need to do an extra mouse click after performing the X selection for this operation to work. x2x is known to work poorly with eXcursion running on Windows 95, probably due to the Windows 95 task scheduler. x2x does work well with eXcursion running on Windows NT. The hints for eXcursion are also valid for Exceed, with the exception that X selections work better, as long as you are using x2x version 1.25 or later. .SH OPTIONS Either the \-to option or the \-from option (or both) must be specified. .TP .B \-to \fIdisplay\fP .IP Indicates the ("to") display that is remotely controlled by the "from" display. Default is equivalent to the default display. .TP .B \-from \fIdisplay\fP .IP Indicates the ("from") display that remotely controls the "to" display. Default is equivalent to the default display. .TP .B \-fromwin .IP Available when x2x is built in the Cygwin environment. This option indicates the ("from") display should be the Windows desktop. In this case the "to" display must be specified with the \-to option. Setting this option forces \-big and sets the default to \-west \-capslockhack The \-fromwin option works best when Windows is configured for focus-follows-mouse also known as X Mouse. This can be set using TweakUI for Windows XP (on the Mouse/X-Mouse panel) or the XMouse2000 program for Windows 2000. If Windows is set for its default behaviour x2x will attempt to get the keyboard and mouse focus but may not succeed. (The Windows XP TweakUI has a General/Focus option that can be unchecked to allow applications to steal the focus.) If it fails the first try, x2x tries quite hard to get the focus! If the "to" display supports mouse buttons 4 and 5 then mouse wheel events on the Windows side are translated to clicks of buttons 4 and 5 on the X display. This matches with XFree86 servers using Option "ZAxisMapping" "4 5". A link may be created on the Windows desktop to conveniently launch x2x. Assuming cygwin is installed to C:\\cygwin and x2x.exe is in /usr/X11R6/bin then the link properties should be set to: Target: .br C:\\cygwin\\usr\\X11R6\\bin\\run.exe\ /usr/X11R6/bin/x2x\ \-fromwin\ \-to\ somewhere:0.0\ \-east Start In: C:\\cygwin\\usr\\X11R6\\bin The "Start In" option is important to allow DLLs to be loaded and C:\\cygwin\\bin must be on the Windows PATH to allow other DLLs to be loaded. (If either of these are incorrect, launching the application tends to silently fail.) There are two magic key combinations activated by \-fromwin: RightAlt-Home: Forces the focus back to Windows without needing the mouse to be moved. Useful when some popup window on the Windows side grabs the mouse! RightAlt-End: Exit x2x .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. .TP .B \-west .IP Slide off the west side of the "to" display onto the "from" display. .TP .B \-font \fIfontname\fP .IP The font used in the x2x window. (Overridden by \-east or \-west.) .TP .B \-geometry \fIspecification\fP .IP The X geometry specification for the x2x window. (Overridden by \-north, \-south, \-east or \-west.) .TP .B \-wait .IP Tells x2x to poll the "to" and "from" displays at startup until they are ready. Useful for login scripts. .TP .B \-big .IP Workaround for a bug in the cursor grab implementations of at least one X server. Put a big window over the "from" display in order to force the X server to track the cursor. (This option is forced by the \-fromwin option). .TP .B \-buttonblock .IP 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 \-north, \-south, \-east or \-west.) .TP .B \-nopointermap .IP Since x2x uses XTEST, which sends input at a lower level than the pointer button mapping, x2x needs to understand the "to" display's button mapping and do appropriate conversion. Use this option to turn off the pointer button conversion. .TP .B \-nosel .IP Don't relay the X selection between displays. .TP .B \-noautoup .IP Normally, the autoup feature in x2x automatically lifts up all keys and mouse buttons when it removes the cursor from the "from" display. .B Note: the autoup feature changes the state of lock functions like .B Caps Lock. The state of the lock function may not correspond to .B the state of the keyboard LEDs! To disable this feature, use the \-noautoup command line option. .TP .B \-resurface .IP 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 \-capslockhack .IP Ugly hack to work-around the situation in which the "to" Xserver doesn't seem to honor the state of the CapsLock on the "from" Xserver. This is the default when the \-fromwin option is given (although the hack used is slightly less ugly). .TP .B \-nocapslockhack .IP Disable the \-capslockhack behaviour. Used to change the default behaviour after the \-fromwin option is specified. .TP .B \-clipcheck .IP Check that clipboard entries are regular strings (XA_STRING) before forwarding to Windows. Enabling this is safer but may prevent copying with certain setups (eg from emacs under KDE/XFree). .TP .B \-shadow \fIdisplay\fP .IP Also sends mouse movements and keystrokes to this display. Useful for demos. Amaze your friends: specify multiple shadows. .TP .B \-sticky \fIsticky-key\fP .IP This option is primarily for "lock" keys like Caps_Lock. If a lock key only seems to work on every other press, try this option. The 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 \-singlesticky .IP Some X servers generate both a key down and a key up when a lock key is toggled. Some X servers generate a key down when a lock key is activated and a key up only when it is deactivated. This option will allow an X server with the former behavior to control one with the latter behavior. Use this if Caps_Lock lock is behaving like shift. .TP .B \-label \fIlabel\fP .IP Override the label of the control window (useful when running over ssh). The label is the text displayed within the control window. .TP .B \-title \fItitle\fP .IP Override the title of the control window (useful when running over ssh). .IP .TP .B \-copyright .IP Prints the full copyright for the x2x code. .SH AUTHOR David Chaiken .br (chaiken@pa.dec.com) .br Mark Hayter (\-fromwin code, thanks to the WinVNC sources) .br Addition of \-north and \-south options by Charles Briscoe-Smith . .br Current maintaner is Mikhail Gusarov .SH BUGS This software is experimental! Heaven help you if your network connection should go down. Caveat hacker. TANSTAAFL. Nevertheless, bugtracker is at http://x2x.dottedmag.net/trac/do/newticket When using the \-fromwin option if the Ctrl-Alt-Del keysequence is used while the mouse is forwarded to the X display then the Ctrl and Alt key press events are reported to x2x and forwarded but no other key events are generated. Thus if the Ctrl-Alt-Del sequence is used to manually lock the Windows display when the display is unlocked the mouse will still be forwarded to the X screen and the X server will believe Ctrl and Alt are still pressed. Pressing and releasing Ctrl and Alt should restore correct operation, as should returning the mouse to the Windows display (or using the RightAlt-Home magic key sequence). .SH LAWYERESE Copyright (c) 1997 Digital Equipment Corporation. All rights reserved. By downloading, installing, using, modifying or distributing this software, you agree to the following: 1. CONDITIONS. Subject to the following conditions, you may download, install, use, modify and distribute this software in source and binary forms: a) Any source code, binary code and associated documentation (including the online manual) used, modified or distributed must reproduce and retain the above copyright notice, this list of conditions and the following disclaimer. b) No right is granted to use any trade name, trademark or logo of Digital Equipment Corporation. Neither the "Digital Equipment Corporation" name nor any trademark or logo of Digital Equipment Corporation may be used to endorse or promote products derived from this software without the prior written permission of Digital Equipment Corporation. 2. DISCLAIMER. THIS SOFTWARE IS PROVIDED BY DIGITAL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL DIGITAL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Windows 95 and Windows NT are trademarks of Microsoft Corporation. .br Exceed is a trademark of Hummingbird Communications Ltd. x2x-1.30/x2x.c000066400000000000000000003303171207154276600130640ustar00rootroot00000000000000/* * 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. * * By downloading, installing, using, modifying or distributing this * software, you agree to the following: * * 1. CONDITIONS. Subject to the following conditions, you may download, * install, use, modify and distribute this software in source and binary * forms: * * a) Any source code, binary code and associated documentation * (including the online manual) used, modified or distributed must * reproduce and retain the above copyright notice, this list of * conditions and the following disclaimer. * * b) No right is granted to use any trade name, trademark or logo of * Digital Equipment Corporation. Neither the "Digital Equipment * Corporation" name nor any trademark or logo of Digital Equipment * Corporation may be used to endorse or promote products derived from * this software without the prior written permission of Digital * Equipment Corporation. * * 2. DISCLAIMER. THIS SOFTWARE IS PROVIDED BY DIGITAL "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL DIGITAL BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * 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 */ /* Cygwin version with -fromwin to allow source to be a Windows * machine that is not running a X server. * Adapted by Mark Hayter 2003 using win2vnc ClientConnect.cpp code * * Original win2vnc copyright follows: */ // win2vnc, adapted from vncviewer by Fredrik Hubinette 2001 // // Original copyright follows: // // Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. // // This file is part of the VNC system. // // The VNC system is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, // USA. // // If the source code for the VNC system is not available from the place // whence you received this file, check http://www.uk.research.att.com/vnc or contact // the authors on vnc@uk.research.att.com for information on obtaining it. #include #include #include #include #include #include #include #include #include #include #include /* for selection */ #include #include #include #include #include #ifdef WIN_2_X #define _WIN32_WINNT 0x0500 #include #include #include #include "keymap.h" #include "resource.h" #define X2X_MSG_HOTKEY (WM_USER + 1) #define DPMSModeOn 0 extern Status DPMSForceLevel(Display *, unsigned short); /* We always support this: */ #define DPMSQueryExtension(DPY, EVBASE, ERBASE) TRUE #else #include #endif /*#define DEBUG*/ #ifndef MIN #define MIN(x,y) (((x) < (y)) ? (x) : (y)) #endif #ifndef MAX #define MAX(x,y) (((x) > (y)) ? (x) : (y)) #endif #define UTF8_STRING "UTF8_STRING" /********** * definitions for edge **********/ #define EDGE_NONE 0 /* don't transfer between edges of screens */ #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 **********/ static void ParseCommandLine(); static Display *OpenAndCheckDisplay(); static Bool CheckTestExtension(); #ifndef WIN_2_X static int ErrorHandler(); #endif static void DoDPMSForceLevel(); static void DoX2X(); static void InitDpyInfo(); static void DoConnect(); static void DoDisconnect(); static void RegisterEventHandlers(); static Bool ProcessEvent(); static Bool ProcessMotionNotify(); static Bool ProcessExpose(); static void DrawWindowText(); static Bool ProcessEnterNotify(); static Bool ProcessButtonPress(); static Bool ProcessButtonRelease(); static Bool ProcessKeyEvent(); static Bool ProcessConfigureNotify(); static Bool ProcessClientMessage(); static Bool ProcessSelectionRequest(); static void SendPing(); static Bool ProcessPropertyNotify(); static Bool ProcessSelectionNotify(); static void SendSelectionNotify(); static Bool ProcessSelectionClear(); static Bool ProcessVisibility(); static Bool ProcessMapping(); static void FakeThingsUp(); static void FakeAction(); static void RefreshPointerMapping(); static void Usage(); static void *xmalloc(); /********** * stuff for selection forwarding **********/ typedef struct _dpyxtra { Display *otherDpy; int sState; Atom pingAtom; Bool pingInProg; Window propWin; } DPYXTRA, *PDPYXTRA; /********** * structures for recording state of buttons and keys **********/ typedef struct _fakestr { struct _fakestr *pNext; int type; KeySym thing; KeyCode code; } FAKE, *PFAKE; #define FAKE_KEY 0 #define FAKE_BUTTON 1 #define N_BUTTONS 20 #define MAX_BUTTONMAPEVENTS 20 #define GETDPYXTRA(DPY,PDPYINFO)\ (((DPY) == (PDPYINFO)->fromDpy) ?\ &((PDPYINFO)->fromDpyXtra) : &((PDPYINFO)->toDpyXtra)) /* values for sState */ #define SELSTATE_ON 0 #define SELSTATE_OFF 1 #define SELSTATE_WAIT 2 /* special values for translated coordinates */ #define COORD_INCR -1 #define COORD_DECR -2 #define SPECIAL_COORD(COORD) (((COORD) < 0) ? (COORD) : 0) /* max unreasonable coordinates before accepting it */ #define MAX_UNREASONABLES 10 /********** * display information **********/ typedef struct { /* stuff on "from" display */ Display *fromDpy; Atom fromDpyUtf8String; Window root; Window trigger; Window big; Window selWinFrom; int selRevFrom; GC textGC; Atom wmpAtom, wmdwAtom; Cursor grabCursor; Font fid; int width, height, twidth, theight, tascent; Bool vertical; int lastFromCoord; int unreasonableDelta; #ifdef WIN_2_X int unreasonableCount; /* From display info for Windows */ HWND bigwindow; HWND edgewindow; int onedge; int fromWidth, fromHeight; int wdelta; int lastFromY; HWND hwndNextViewer; // int initialClipboardSeen; char *winSelText; int owntoXsel; int expectSelNotify; int expectOwnClip; int winSSave; int nXbuttons; RECT monitorRect; RECT screenRect; int screenHeight; int screenWidth; int lastFromX; #endif /* WIN_2_X */ /* stuff on "to" display */ Display *toDpy; Atom toDpyUtf8String; Atom toDpyTargets; 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 */ /* coordinate conversion stuff */ int toScreen; int nScreens; short **xTables; /* precalculated conversion tables */ short **yTables; 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; DPYXTRA toDpyXtra; Display *sDpy; XSelectionRequestEvent sEv; Time sTime; /* for recording state of buttons and keys */ PFAKE pFakeThings; } DPYINFO, *PDPYINFO; static DPYINFO dpyInfo; /* shadow displays */ typedef struct _shadow { struct _shadow *pNext; char *name; Display *dpy; long led_mask; Bool flush; int DPMSstatus; /* -1: not queried, 0: not supported, 1: supported */ } SHADOW, *PSHADOW; /* sticky keys */ typedef struct _sticky { struct _sticky *pNext; KeySym keysym; } STICKY, *PSTICKY; typedef int (*HANDLER)(); /* event handler function */ /* These prototypes need the typedefs */ #ifdef WIN_2_X static void MoveWindowToEdge(PDPYINFO); static int MoveWindowToScreen(PDPYINFO); static void DoWinConnect(PDPYINFO, int, int); static void DoWinDisconnect(PDPYINFO, int, int); static void SendButtonClick(PDPYINFO, int); LRESULT CALLBACK WinProcessMessage (HWND, UINT, WPARAM, LPARAM); void WinPointerEvent(PDPYINFO, int, int, DWORD, UINT); void WinKeyEvent(PDPYINFO, int, DWORD); void SendKeyEvent(PDPYINFO, KeySym, int, int, int); static Bool ProcessSelectionRequestW(); static Bool ProcessSelectionNotifyW(); static Bool ProcessSelectionClearW(); #ifdef DEBUGCHATTY char *msgtotext(int); #endif #endif /* WIN_2_X */ /********** * top-level variables **********/ static char *programStr = "x2x"; 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 *title = NULL; static char *pingStr = "PING"; /* atom for ping request */ static char *geomStr = NULL; static Bool waitDpy = False; static Bool doBig = False; static Bool doMouse = True; static int doEdge = EDGE_NONE; static Bool doSel = True; static Bool doAutoUp = True; static Bool doResurface = False; static PSHADOW shadows = NULL; static int triggerw = 2; static Bool doPointerMap = True; static PSTICKY stickies = NULL; static Bool doBtnBlock = False; static Bool doCapsLkHack = False; static Bool doClipCheck = False; static Bool doDpmsMouse = False; static int logicalOffset= 0; static int nButtons = 0; static KeySym buttonmap[N_BUTTONS + 1][MAX_BUTTONMAPEVENTS + 1]; #ifdef WIN_2_X /* These are used to allow pointer comparisons */ static char *fromWinName = "x2xFromWin"; static int dummy; static Display *fromWin = (Display *)&dummy; static HWND hWndSave; static HINSTANCE m_instance; #endif #ifdef DEBUG #define debug printf #else void debug(const char* fmt, ...) { } #endif #ifdef WIN_2_X #define MAX_WIN_ARGS 40 int STDCALL WinMain (HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmd, int nShow) { Display *fromDpy; PSHADOW pShadow; int argc; char *argv[MAX_WIN_ARGS]; char *ap; if (lpCmd[0] == ' ') { lpCmd++; } argv[0] = programStr; argc = 1; ap = lpCmd; /* XXX mdh - Should probably deal with quotes properly too */ while (*ap && (argc < MAX_WIN_ARGS)) { argv[argc++] = ap; while (*ap && (*ap != ' ')) ap++; if (*ap == ' ') *ap++ = 0; } m_instance = hInst; #else /* Not WIN_2_X */ /********** * main **********/ int main(argc, argv) int argc; char **argv; { Display *fromDpy; PSHADOW pShadow; #endif /* WIN_2_X */ #ifdef DEBUG setvbuf(stdout, NULL, _IONBF, 0); #endif XrmInitialize(); ParseCommandLine(argc, argv); #ifdef WIN_2_X if (fromDpyName != fromWinName) fromDpyName = XDisplayName(fromDpyName); #else fromDpyName = XDisplayName(fromDpyName); #endif toDpyName = XDisplayName(toDpyName); if (!strcasecmp(toDpyName, fromDpyName)) { fprintf(stderr, "%s: display names are both %s\n", programStr, toDpyName); exit(1); } /* no OS independent way to stop Xlib from complaining via stderr, but can always pipe stdout/stderr to /dev/null */ /* convert to real name: */ #ifdef WIN_2_X if (fromDpyName == fromWinName) { /* From is Windows, don't need to open */ fromDpy = fromWin; } else /* This ugly hanging else... */ #endif /* WIN_2_X */ /* ... qualifies this while in WIN_2_X case with an X source */ while ((fromDpy = XOpenDisplay(fromDpyName)) == NULL) { if (!waitDpy) { fprintf(stderr, "%s - error: can not open display %s\n", programStr, fromDpyName); exit(2); } /* END if */ sleep(10); } /* END while fromDpy */ (void)XSynchronize(fromDpy, True); /* toDpy is always the first shadow */ pShadow = (PSHADOW)xmalloc(sizeof(SHADOW)); pShadow->DPMSstatus = -1; 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) { pShadow->led_mask = 0; pShadow->flush = False; if (!(pShadow->dpy = OpenAndCheckDisplay(pShadow->name))) exit(3); } (void)XSynchronize(shadows->dpy, True); #ifndef WIN_2_X /* set error handler, so that program does not abort on non-critcal errors */ XSetErrorHandler(ErrorHandler); #endif /* run the x2x loop */ DoX2X(fromDpy, shadows->dpy); /* shut down gracefully */ #ifdef WIN_2_X /* Only close if it is a real X from display */ if (fromDpy != fromWin) XCloseDisplay(fromDpy); #else XCloseDisplay(fromDpy); #endif for (pShadow = shadows; pShadow; pShadow = pShadow->pNext) XCloseDisplay(pShadow->dpy); exit(0); } /* END main */ static Display *OpenAndCheckDisplay(name) char *name; { Display *openDpy; /* convert to real name: */ name = XDisplayName(name); while ((openDpy = XOpenDisplay(name)) == NULL) { if (!waitDpy) { fprintf(stderr, "%s - error: can not open display %s\n", programStr, name); return NULL; } /* END if */ sleep(10); } /* END while openDpy */ if (!CheckTestExtension(openDpy)) { fprintf(stderr, "%s - error: display %s does not support the test extension\n", programStr, name); return NULL; } return (openDpy); } /* END OpenAndCheckDisplay */ /********** * use standard X functions to parse the command line **********/ static void ParseCommandLine(argc, argv) int argc; char **argv; { int arg; PSHADOW pShadow; extern char *lawyerese; PSTICKY pNewSticky; KeySym keysym; int button; int eventno; char *keyname, *argptr; debug("programStr = %s\n", programStr); /* Clear button map */ for (button = 0; button <= N_BUTTONS; button++) buttonmap[button][0] = NoSymbol; for (arg = 1; arg < argc; ++arg) { #ifdef WIN_2_X if (!strcasecmp(argv[arg], "-fromWin")) { fromDpyName = fromWinName; /* XXX mdh - For now only support edge windows getting big */ /* Note: -east will override correctly (even if earlier on the line) */ doBig = True; if (doEdge == EDGE_NONE) doEdge = EDGE_WEST; doCapsLkHack = True; debug("fromDpyName = %s\n", fromDpyName); } else /* Note this else will qualify the if below... */ #endif /* WIN_2_X */ if (!strcasecmp(argv[arg], "-from")) { if (++arg >= argc) Usage(); fromDpyName = argv[arg]; debug("fromDpyName = %s\n", fromDpyName); } else if (!strcasecmp(argv[arg], "-to")) { if (++arg >= argc) Usage(); toDpyName = argv[arg]; debug("toDpyName = %s\n", toDpyName); } else if (!strcasecmp(argv[arg], "-font")) { if (++arg >= argc) Usage(); fontName = argv[arg]; debug("fontName = %s\n", fontName); } else if (!strcasecmp(argv[arg], "-label")) { if (++arg >= argc) Usage(); label = argv[arg]; debug("label = %s\n", label); } else if (!strcasecmp(argv[arg], "-title")) { if (++arg > argc) Usage(); title = argv[arg]; debug("title = %s\n", title); } else if (!strcasecmp(argv[arg], "-geometry")) { if (++arg >= argc) Usage(); geomStr = argv[arg]; debug("geometry = %s\n", geomStr); } else if (!strcasecmp(argv[arg], "-wait")) { waitDpy = True; debug("will wait for displays\n"); } else if (!strcasecmp(argv[arg], "-big")) { doBig = True; debug("will create big window on from display\n"); } else if (!strcasecmp(argv[arg], "-nomouse")) { doMouse = False; debug("will not capture mouse (eek!)\n"); } else if (!strcasecmp(argv[arg], "-nopointermap")) { doPointerMap = False; debug("will not do pointer mapping\n"); } else if (!strcasecmp(argv[arg], "-north")) { doEdge = EDGE_NORTH; debug("\"from\" is on the north side of \"to\"\n"); } else if (!strcasecmp(argv[arg], "-south")) { doEdge = EDGE_SOUTH; debug("\"from\" is on the south side of \"to\"\n"); } else if (!strcasecmp(argv[arg], "-east")) { doEdge = EDGE_EAST; debug("\"from\" is on the east side of \"to\"\n"); } else if (!strcasecmp(argv[arg], "-west")) { doEdge = EDGE_WEST; debug("\"from\" is on the west side of \"to\"\n"); } else if (!strcasecmp(argv[arg], "-nosel")) { doSel = False; debug("will not transmit X selections between displays\n"); } else if (!strcasecmp(argv[arg], "-noautoup")) { doAutoUp = False; debug("will not automatically lift keys and buttons\n"); } else if (!strcasecmp(argv[arg], "-buttonblock")) { doBtnBlock = True; debug("mouse buttons down will block disconnects\n"); } else if (!strcasecmp(argv[arg], "-capslockhack")) { doCapsLkHack = True; debug("behavior of CapsLock will be hacked\n"); } else if (!strcasecmp(argv[arg], "-dpmsmouse")) { doDpmsMouse = True; debug("mouse movement wakes monitor\n"); } else if (!strcasecmp(argv[arg], "-offset")) { if (++arg >= argc) Usage(); logicalOffset = atoi(argv[arg]); debug("logicalOffset %d\n", logicalOffset); } else if (!strcasecmp(argv[arg], "-clipcheck")) { doClipCheck = True; debug("Clipboard type will be checked for XA_STRING\n"); } else if (!strcasecmp(argv[arg], "-nocapslockhack")) { doCapsLkHack = False; debug("behavior of CapsLock will not be hacked\n"); } else if (!strcasecmp(argv[arg], "-sticky")) { if (++arg >= argc) Usage(); if ((keysym = XStringToKeysym(argv[arg])) != NoSymbol) { pNewSticky = (PSTICKY)xmalloc(sizeof(STICKY)); pNewSticky->pNext = stickies; pNewSticky->keysym = keysym; stickies = pNewSticky; debug("will press/release sticky key: %s\n", argv[arg]); } 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 { debug("will map button %d to keysyms '%s'\n", button, argv[arg]); 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; debug("will resurface the trigger window when obscured\n"); } else if (!strcasecmp(argv[arg], "-shadow")) { if (++arg >= argc) Usage(); pShadow = (PSHADOW)xmalloc(sizeof(SHADOW)); pShadow->DPMSstatus = -1; pShadow->name = argv[arg]; /* into the global list of shadows */ pShadow->pNext = shadows; shadows = pShadow; } else if (!strcasecmp(argv[arg], "-triggerw")) { if (++arg >= argc) Usage(); triggerw = atoi(argv[arg]); } else if (!strcasecmp(argv[arg], "-copyright")) { puts(lawyerese); } else { Usage(); } /* END if... */ } /* END for */ } /* END ParseCommandLine */ static void Usage() { #ifdef WIN_2_X printf("Usage: x2x [-fromwin | -from ][-to ] options..\n"); #else printf("Usage: x2x [-to | -from ] options...\n"); #endif printf(" -copyright\n"); printf(" -font \n"); printf(" -geometry \n"); printf(" -wait\n"); 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"); printf(" -noautoup\n"); printf(" -resurface\n"); printf(" -capslockhack\n"); printf(" -nocapslockhack\n"); printf(" -clipcheck\n"); printf(" -shadow \n"); printf(" -sticky \n"); printf(" -label