2 xkbd - xlib based onscreen keyboard.
4 Copyright (C) 2001 Matthew Allum
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
24 #include <X11/Xutil.h>
25 #include <X11/Xatom.h>
26 #include <X11/extensions/XTest.h>
27 #include <X11/keysym.h>
28 #include <X11/extensions/shape.h>
29 #include "../config.h"
43 #define WIN_OVERIDE_AWAYS_TOP 0
44 #define WIN_OVERIDE_NOT_AWAYS_TOP 1
50 Display* display; /* ack globals due to sighandlers - another way ? */
62 get_current_window_manager_name (void)
64 Atom utf8_string, atom, atom_check, type;
66 unsigned char *retval;
71 Window *xwindow = NULL;
73 atom_check = XInternAtom (display, "_NET_SUPPORTING_WM_CHECK", False);
75 XGetWindowProperty (display,
76 RootWindow(display, DefaultScreen(display)),
78 0, 16L, False, XA_WINDOW, &type, &format,
79 &nitems, &bytes_after, (unsigned char **)&xwindow);
85 utf8_string = XInternAtom (display, "UTF8_STRING", False);
86 atom = XInternAtom (display, "_NET_WM_NAME", False);
88 result = XGetWindowProperty (display,
93 &type, &format, &nitems,
94 &bytes_after, (unsigned char **)&val);
96 if (result != Success)
99 if (type != utf8_string || format !=8 || nitems == 0)
101 if (val) XFree (val);
105 retval = strdup (val);
113 void handle_sig(int sig)
115 XWindowAttributes attr;
116 XGetWindowAttributes(display, win, &attr);
117 if (attr.map_state == IsUnmapped ||
118 attr.map_state == IsUnviewable )
120 XMapWindow(display, win);
121 XRaiseWindow(display,win);
123 XUnmapWindow(display, win);
129 printf("Version: %s \n", VERSION);
131 printf("XFT supported\n");
134 printf("XPM supported\n");
140 printf("Usage: xkbd <options>\n");
141 printf("Options:\n");
142 printf(" -display <display>\n");
143 printf(" -geometry <geometry>\n");
145 printf(" -font <font name> Select the xft AA font for xkbd\n");
147 printf(" -font <font name> Select the X11 font for xkbd\n");
149 printf(" ( NOTE: The above will overide the configs font )\n");
150 printf(" -k <keybaord file> Select the keyboard definition file\n");
151 printf(" other than" DEFAULTCONFIG "\n");
152 printf(" -xid used for gtk embedding \n");
153 printf(" -v version\n");
154 printf(" -h this help\n\n");
158 int main(int argc, char **argv)
160 char *window_name = "xkbd";
162 char *icon_name = "xkbd";
164 #define PROP_MOTIF_WM_HINTS_ELEMENTS 5
165 #define MWM_HINTS_DECORATIONS (1L << 1)
166 #define MWM_DECOR_BORDER (1L << 1)
171 unsigned long functions;
172 unsigned long decorations;
174 unsigned long status;
177 PropMotifWmHints *mwm_hints;
179 XSizeHints size_hints;
182 char *display_name = (char *)getenv("DISPLAY");
187 int wm_type = WM_UNKNOWN;
189 char *geometry = NULL;
190 int xret=0, yret=0, wret=0, hret=0;
191 char *conf_file = NULL;
192 char *font_name = NULL;
193 int cmd_xft_selected = 0; /* ugly ! */
195 Bool use_normal_win = False;
202 char userconffile[256];
204 KeySym mode_switch_ksym;
210 if ((bthid_pid = fork())) {
222 for (i=1; argv[i]; i++) {
226 case 'd' : /* display */
227 display_name = argv[i+1];
231 geometry = argv[i+1];
235 font_name = argv[i+1];
237 cmd_xft_selected = 1;
240 case 'o' : /* wm override */
242 fprintf( stderr, "Overide redirect support deprciated\n");
246 conf_file = argv[i+1];
253 use_normal_win = True;
267 display = XOpenDisplay(display_name);
271 Atom wm_protocols[]={
272 XInternAtom(display, "WM_DELETE_WINDOW",False),
273 XInternAtom(display, "WM_PROTOCOLS",False),
274 XInternAtom(display, "WM_NORMAL_HINTS", False),
277 Atom window_type_atom =
278 XInternAtom(display, "_NET_WM_WINDOW_TYPE" , False);
279 Atom window_type_toolbar_atom =
280 XInternAtom(display, "_NET_WM_WINDOW_TYPE_TOOLBAR",False);
282 XInternAtom(display, "_MOTIF_WM_HINTS",False);
284 Atom window_type_dock_atom =
285 XInternAtom(display, "_NET_WM_WINDOW_TYPE_DOCK",False);
288 /* HACK to get libvirtkeys to work without mode_switch */
290 screen_num = DefaultScreen(display);
292 if (XKeysymToKeycode(display, XK_Mode_switch) == 0)
297 XDisplayKeycodes(display, &min_kc, &max_kc);
299 for (keycode = min_kc; keycode <= max_kc; keycode++)
300 if (XKeycodeToKeysym (display, keycode, 0) == NoSymbol)
302 mode_switch_ksym = XStringToKeysym("Mode_switch");
303 XChangeKeyboardMapping(display,
305 &mode_switch_ksym, 1);
306 XSync(display, False);
310 wm_name = get_current_window_manager_name ();
311 use_normal_win = True;
315 wm_type = WM_EHWM_UNKNOWN;
316 if (!strcmp(wm_name, "metacity"))
317 wm_type = WM_METACITY;
318 else if (!strcmp(wm_name, "matchbox"))
321 use_normal_win = False;
322 wm_type = WM_MATCHBOX;
326 win = XCreateSimpleWindow(display,
327 RootWindow(display, screen_num),
330 0, BlackPixel(display, screen_num),
331 WhitePixel(display, screen_num));
333 if (geometry != NULL)
335 XParseGeometry(geometry, &xret, &yret, &wret, &hret );
339 if (wm_type != WM_MATCHBOX)
341 wret = DisplayWidth(display, screen_num);
342 hret = DisplayHeight(display, screen_num)/4;
344 yret = DisplayHeight(display, screen_num) - hret;
348 /* check for user selected keyboard conf file */
350 if (conf_file == NULL)
352 strcpy(userconffile,getenv("HOME"));
353 strcat(userconffile, "/.xkbd");
355 if ((fp = fopen(userconffile, "r")) != NULL)
357 conf_file = (char *)malloc(sizeof(char)*512);
358 if (fgets(conf_file, 512, fp) != NULL)
361 if ( conf_file[strlen(conf_file)-1] == '\n')
362 conf_file[strlen(conf_file)-1] = '\0';
367 conf_file = DEFAULTCONFIG;
371 kb = xkbd_realize(display, win, conf_file, font_name, 0, 0,
372 wret, hret, cmd_xft_selected);
374 XResizeWindow(display, win, xkbd_get_width(kb), xkbd_get_height(kb));
377 XMoveWindow(display,win,xret,yret);
379 size_hints.flags = PPosition | PSize | PMinSize;
382 size_hints.width = xkbd_get_width(kb);
383 size_hints.height = xkbd_get_height(kb);
384 size_hints.min_width = xkbd_get_width(kb);
385 size_hints.min_height = xkbd_get_height(kb);
387 XSetStandardProperties(display, win, window_name,
389 argv, argc, &size_hints);
391 wm_hints = XAllocWMHints();
392 wm_hints->input = False;
393 wm_hints->flags = InputHint;
394 XSetWMHints(display, win, wm_hints );
396 /* Tell the WM we dont want no borders */
397 mwm_hints = malloc(sizeof(PropMotifWmHints));
398 memset(mwm_hints, 0, sizeof(PropMotifWmHints));
400 mwm_hints->flags = MWM_HINTS_DECORATIONS;
401 mwm_hints->decorations = 0;
404 XChangeProperty(display, win, mwm_atom,
405 XA_ATOM, 32, PropModeReplace,
406 (unsigned char *)mwm_hints,
407 PROP_MOTIF_WM_HINTS_ELEMENTS);
412 XSetWMProtocols(display, win, wm_protocols, sizeof(wm_protocols) /
415 if (use_normal_win == False)
416 XChangeProperty(display, win, window_type_atom, XA_ATOM, 32,
418 (unsigned char *) &window_type_toolbar_atom, 1);
422 fprintf(stdout, "%i\n", win);
425 XMapWindow(display, win);
428 signal(SIGUSR1, handle_sig); /* for extenal mapping / unmapping */
430 XSelectInput(display, win,
435 StructureNotifyMask |
436 VisibilityChangeMask);
440 while ( XPending(display) )
443 XNextEvent(display, &an_event);
444 xkbd_process(kb, &an_event);
447 switch (an_event.type) {
449 if ((an_event.xclient.message_type == wm_protocols[1])
450 && (an_event.xclient.data.l[0] == wm_protocols[0]))
453 case ConfigureNotify:
454 if ( an_event.xconfigure.width != xkbd_get_width(kb)
455 || an_event.xconfigure.height != xkbd_get_height(kb))
458 an_event.xconfigure.width,
459 an_event.xconfigure.height );
467 xkbd_process_repeats(kb);
468 usleep(10000L); /* sleep for a 10th of a second */
471 XCloseDisplay(display);
474 fprintf(stderr, "%s: cannot connect to X server '%s'\n",
475 argv[0], display_name);