Softwedge alpha 1.0 version - basic functionality, forking, etc, but it works
[softwedge.git] / softwedge.c
blob5be20ba569b6330195df01cd0d835809e7605977
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <ctype.h>
5 #include <unistd.h>
6 #include <X11/Xlib.h>
7 #include <X11/Xutil.h>
8 #include <X11/extensions/XTest.h>
9 #include <X11/keysymdef.h>
10 #include <sys/types.h>
11 #include <sys/stat.h>
12 #include <fcntl.h>
15 #include "softwedge.h"
17 int serialPort;
19 void xtest_key_press(Display *dpy, unsigned char letter) {
20 unsigned int shiftcode = XKeysymToKeycode(dpy, XStringToKeysym("Shift_L"));
21 int upper = 0;
22 int skip_lookup = 0;
23 char s[2];
24 s[0] = letter;
25 s[1] = 0;
26 KeySym sym = XStringToKeysym(s);
27 KeyCode keycode;
31 if (sym == 0) {
32 sym = letter;
36 if (sym == '\n') {
37 sym = XK_Return;
38 skip_lookup = 1;
40 } else if (sym == '\t') {
41 sym = XK_Tab;
42 skip_lookup = 1;
45 keycode = XKeysymToKeycode(dpy, sym);
46 if (keycode == 0) {
47 sym = 0xff00 | letter;
48 keycode = XKeysymToKeycode(dpy, sym);
52 if (!skip_lookup) {
53 // Here we try to determine if a keysym
54 // needs a modifier key (shift), such as a
55 // shifted letter or symbol.
56 // The second keysym should be the shifted char
57 KeySym *syms;
58 int keysyms_per_keycode;
59 syms = XGetKeyboardMapping(dpy, keycode, 1, &keysyms_per_keycode);
60 int i = 0;
61 for (i = 0; i <= keysyms_per_keycode; i++) {
62 if (syms[i] == 0)
63 break;
65 if (i == 0 && syms[i] != letter)
66 upper = 1;
72 if (upper)
73 XTestFakeKeyEvent(dpy, shiftcode, True, 0);
76 XTestFakeKeyEvent(dpy, keycode, True, 0);
77 XTestFakeKeyEvent(dpy, keycode, False, 0);
79 if (upper)
80 XTestFakeKeyEvent(dpy, shiftcode, False, 0);
86 void press_keys(Display *dpy, char* string) {
87 int len = strlen(string);
88 int i = 0;
89 for (i = 0; i < len; i++) {
90 xtest_key_press(dpy, string[i]);
92 XFlush(dpy);
96 int sw_open_serial(const char *port) {
97 serialPort = open(port, O_RDONLY);
98 if (serialPort < 0) {
99 fprintf(stderr, "Can't open serial port: %s\n", port);
100 exit(-1);
103 return 0;
107 int main(int argc, char**argv)
109 Display *dpy; /* X server connection */
110 int xtest_major_version = 0;
111 int xtest_minor_version = 0;
112 int dummy;
113 int c;
114 char *sport = NULL;
116 while ((c = getopt (argc, argv, "vc:")) != -1)
117 switch (c)
119 case 'v':
120 fprintf(stderr, "softwedge v %s: The serial softwedge X11 helper. ", SOFTWEDGE_VERSION);
121 fprintf(stderr, "(c) 2007 Yann Ramin <atrus@stackworks.net>\n(Exiting...)\n");
122 exit(0);
123 case 'c':
124 sport = optarg;
125 break;
126 case '?':
127 if (optopt == 'c')
128 fprintf (stderr, "Option -%c requires an argument.\n", optopt);
129 else if (isprint (optopt))
130 fprintf (stderr, "Unknown option `-%c'.\n", optopt);
131 else
132 fprintf (stderr,
133 "Unknown option character `\\x%x'.\n",
134 optopt);
135 return 1;
136 default:
137 abort ();
140 if (sport == NULL)
141 sport = DEFAULT_SERIAL;
146 * Open the display using the $DISPLAY environment variable to locate
147 * the X server. See Section 2.1.
149 if ((dpy = XOpenDisplay(NULL)) == NULL) {
150 fprintf(stderr, "%s: can't open %s\en", argv[0], XDisplayName(NULL));
151 exit(1);
154 Bool success = XTestQueryExtension(dpy, &dummy, &dummy,
155 &xtest_major_version, &xtest_minor_version);
156 if(success == False || xtest_major_version < 2 ||
157 (xtest_major_version <= 2 && xtest_minor_version < 2))
159 fprintf(stderr,"XTEST extension not supported. Can't continue\n");
160 exit(1);
164 sw_open_serial(sport);
169 if(fork()) {
170 return 0;
173 close(0);
174 close(1);
175 close(2);
178 char readbuf[2];
179 readbuf[1] = 0;
181 while(read(serialPort, readbuf, 1) > 0) {
183 press_keys(dpy, readbuf);
191 return 0;