Fix formatting, make control characters ignored
[softwedge.git] / sw / softwedge.c
blob612e41cb4fa8e225479e0c6b3347537e2ee923a3
1 /*
2 softwedge - serial to X11 keyboard software wedge
3 Copyright (C) 2007 Yann Ramin
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <ctype.h>
23 #include <unistd.h>
24 #include <X11/Xlib.h>
25 #include <X11/Xutil.h>
26 #include <X11/extensions/XTest.h>
27 #include <X11/keysymdef.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <fcntl.h>
33 #include "softwedge.h"
35 static int serialPort;
36 static Display *dpy;
38 static void xtest_key_press(unsigned char letter) {
39 unsigned int shiftcode = XKeysymToKeycode(dpy, XStringToKeysym("Shift_L"));
40 int upper = 0;
41 int skip_lookup = 0;
42 char s[2];
43 s[0] = letter;
44 s[1] = 0;
45 KeySym sym = XStringToKeysym(s);
46 KeyCode keycode;
50 if (sym == 0) {
51 sym = letter;
55 if (sym == '\n') {
56 sym = XK_Return;
57 skip_lookup = 1;
59 } else if (sym == '\t') {
60 sym = XK_Tab;
61 skip_lookup = 1;
64 keycode = XKeysymToKeycode(dpy, sym);
65 if (keycode == 0) {
66 sym = 0xff00 | letter;
67 keycode = XKeysymToKeycode(dpy, sym);
71 if (!skip_lookup) {
72 // Here we try to determine if a keysym
73 // needs a modifier key (shift), such as a
74 // shifted letter or symbol.
75 // The second keysym should be the shifted char
76 KeySym *syms;
77 int keysyms_per_keycode;
78 syms = XGetKeyboardMapping(dpy, keycode, 1, &keysyms_per_keycode);
79 int i = 0;
80 for (i = 0; i <= keysyms_per_keycode; i++) {
81 if (syms[i] == 0)
82 break;
84 if (i == 0 && syms[i] != letter)
85 upper = 1;
91 if (upper)
92 XTestFakeKeyEvent(dpy, shiftcode, True, 0);
95 XTestFakeKeyEvent(dpy, keycode, True, 0);
96 XTestFakeKeyEvent(dpy, keycode, False, 0);
98 if (upper)
99 XTestFakeKeyEvent(dpy, shiftcode, False, 0);
105 static void press_keys(char* string) {
106 int len = strlen(string);
107 int i = 0;
108 for (i = 0; i < len; i++) {
109 xtest_key_press(string[i]);
111 XFlush(dpy);
115 int sw_open_serial(const char *port) {
116 serialPort = open(port, O_RDONLY);
117 if (serialPort < 0) {
118 fprintf(stderr, "Can't open serial port: %s\n", port);
119 exit(-1);
122 return 0;
125 void sw_init() {
127 int xtest_major_version = 0;
128 int xtest_minor_version = 0;
129 int dummy;
133 * Open the display using the $DISPLAY environment variable to locate
134 * the X server. See Section 2.1.
136 if ((dpy = XOpenDisplay(NULL)) == NULL) {
137 fprintf(stderr, "%s: can't open %s\en", "softwedge", XDisplayName(NULL));
138 exit(1);
141 Bool success = XTestQueryExtension(dpy, &dummy, &dummy,
142 &xtest_major_version, &xtest_minor_version);
143 if(success == False || xtest_major_version < 2 ||
144 (xtest_major_version <= 2 && xtest_minor_version < 2))
146 fprintf(stderr,"XTEST extension not supported. Can't continue\n");
147 exit(1);
153 void sw_read_loop() {
155 char readbuf[2];
156 readbuf[1] = 0;
158 while(read(serialPort, readbuf, 1) > 0) {
159 if (readbuf[0] == 0x02 || readbuf[0] == 0x03)
160 continue;
161 press_keys(readbuf);
163 // We're done now
164 close(serialPort);