fookb-perso/fookb.c

198 lines
4.3 KiB
C

/*
* fookb.c
*
* (c) 1998-2004 Alexey Vyskubov <alexey@mawhrin.net>
*/
#include <stdlib.h> /* malloc() */
#include <stdio.h> /* puts() */
/* X Window headers */
#include <X11/Xlib.h>
#include <X11/Xutil.h>
/* Command line parsing and X resource manager */
#include <X11/Xresource.h>
/* XKB fun */
#include <X11/XKBlib.h>
/* My own fun */
#include "fookb.h"
#include "images.h"
#include "opts.h"
#include "params.h"
#define sterror(x) (void)printf("Strange error, please report! %s:%d, %s\n",\
__FILE__, __LINE__, x)
static void getGC(Window win, GC *gc, Display *dpy)
{
*gc = XCreateGC(dpy, win, 0, NULL);
//XSetBackground(dpy, *gc, 0L);
}
int main(int argc, register char *argv[])
{
Display *dpy;
int scr;
Window root;
int err;
int event_rtrn; /* for XkbOpenDisplay */
int error_rtrn;
int reason_rtrn;
XkbEvent labuda; /* Xkb event. X event will be labuda.core */
Window billy; /* _The_ Window */
int border = 0; /* _The_ Window parameters */
XWMHints *wm_hints;
XClassHint class_hints;
XColor col;
GC gc; /* Graphic context */
char resn[] = "fookb";
char resc[] = "Fookb";
int state = 0; /* We suppose that latin keyboard is the
primal state FIXME */
XrmInitialize(); /* We should initialize X resource
manager before doing something else
*/
ParseOptions(&argc, argv); /* We should parse command line
options and try to find '-display'
before opening X display */
/* Go, fighters, go! */
dpy = XkbOpenDisplay(mydispname,
&event_rtrn,
&error_rtrn, NULL, NULL, &reason_rtrn);
/* Oops. */
if (dpy == NULL) {
(void)puts("Cannot open display.");
exit(EXIT_FAILURE);
}
scr = DefaultScreen(dpy);
root = RootWindow(dpy, scr);
/* We would like receive the only Xkb event: XkbStateNotify. And only
* when XkbLockGroup happens. */
if (False == XkbSelectEvents(dpy,
XkbUseCoreKbd,
XkbAllEventsMask,
0)) {
sterror("Cannot XkbSelectEvents. It's your problem -- not mine.");
exit(EXIT_FAILURE);
} /* Deselect all events */
if (False == XkbSelectEventDetails(dpy,
XkbUseCoreKbd,
XkbStateNotify,
XkbAllEventsMask,
XkbGroupLockMask)) {
sterror("Cannot XkbSelectEventDetails. It's your problem -- not mine.");
exit(EXIT_FAILURE);
} /* Select XkbStateNotify/XkbgroupLock */
read_images(dpy); /* Let's read icon images */
/* Run out! */
billy = XCreateWindow(dpy,
root,
0, 0,
get_width(), get_height(),
border,
CopyFromParent, CopyFromParent,
CopyFromParent, 0, 0);
XParseColor(dpy, DefaultColormap(dpy, scr), read_param("Bg"), &col);
XAllocColor(dpy, DefaultColormap(dpy, scr), &col);
XSetWindowBackground(dpy, billy, col.pixel);
XStoreName(dpy, billy, "fookb");
class_hints.res_name = resn;
class_hints.res_class = resc;
err = XSetClassHint(dpy, billy, &class_hints);
switch(err) {
case BadAlloc:
sterror("BadAlloc");
exit(EXIT_FAILURE);
case BadWindow:
sterror("BadWindow");
exit(EXIT_FAILURE);
}
wm_hints = XAllocWMHints();
wm_hints->window_group = billy;
wm_hints->input = False;
wm_hints->flags = InputHint | WindowGroupHint;
err = XSetWMHints(dpy, billy, wm_hints);
switch(err) {
case BadAlloc:
sterror("BadAlloc");
exit(EXIT_FAILURE);
case BadWindow:
sterror("BadWindow");
exit(EXIT_FAILURE);
}
/* The only thing we would like to do - update our billy */
XSelectInput(dpy, billy, ExposureMask | ButtonPressMask);
XSetCommand(dpy, billy, argv, argc);
/* Programmer supplied functions */
getGC(billy, &gc, dpy);
/* Let's look */
XMapWindow(dpy, billy); /* We would like to see the window. */
/* HELLO! HELLO! HELLO! Is that our GOOD FRIEND main loop here? */
while (1) {
XNextEvent(dpy, &labuda.core);
switch (labuda.core.type) {
case Expose: /* We should update our window. */
if (labuda.core.xexpose.count != 0)
/* Well, I knew what does it mean,
but I forgot :) */
break;
update_window(billy, gc, state, dpy);
break;
default: /* XkbLockGroup happens : FIXME */
state = labuda.state.group;
#ifdef DEBUG
printf("%u\n", state);
#endif
if ((state < 0) || (state > 1))
state = 1;
update_window(billy, gc, state, dpy);
#ifdef DEBUG
puts("."); /* XkbLockGroup happens */
#endif
}
}
XFreeGC(dpy, gc);
XDestroyWindow(dpy, billy);
XCloseDisplay(dpy);
exit(0);
}