summaryrefslogtreecommitdiffstats
path: root/xlnch.c
diff options
context:
space:
mode:
authorgramanas <anastasis.gramm2@gmail.com>2020-11-28 05:09:59 +0200
committergramanas <anastasis.gramm2@gmail.com>2020-11-28 05:09:59 +0200
commit15d5be9e16b4a6b4265a35d31a46647207c475e2 (patch)
treeaee4b3ae0330605e8f07753f59a9968cba6b18f8 /xlnch.c
parentbe75eaf337170f0b0120d06e51bb796ac2407079 (diff)
downloadxlnch-15d5be9e16b4a6b4265a35d31a46647207c475e2.tar.gz
xlnch-15d5be9e16b4a6b4265a35d31a46647207c475e2.tar.bz2
xlnch-15d5be9e16b4a6b4265a35d31a46647207c475e2.zip
version 2
Diffstat (limited to 'xlnch.c')
-rw-r--r--xlnch.c144
1 files changed, 124 insertions, 20 deletions
diff --git a/xlnch.c b/xlnch.c
index 81dcf64..d2e3178 100644
--- a/xlnch.c
+++ b/xlnch.c
@@ -26,6 +26,7 @@
#include <X11/Xos.h>
#include <stdio.h>
+#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
@@ -35,6 +36,7 @@
#include <wordexp.h>
+#define MAX(A, B) ((A) > (B) ? (A) : (B))
Display *dis;
int screen;
@@ -44,6 +46,90 @@ GC gc;
Colormap cm;
XColor red;
+typedef struct {
+ unsigned int w, h;
+ Display *dis;
+ int screen;
+ Window root, win;
+ Drawable drawable;
+ GC gc;
+ // XftColor *scheme;
+} Drw;
+Drw drw;
+
+int w_width = 0;
+int w_height = 0;
+
+void
+die(const char *fmt, ...) {
+ va_list ap;
+
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+
+ if (fmt[0] && fmt[strlen(fmt)-1] == ':') {
+ fputc(' ', stderr);
+ perror(NULL);
+ } else {
+ fputc('\n', stderr);
+ }
+
+ exit(1);
+}
+
+void get_curson_pos(int *x, int *y)
+{
+ int win_x_return, win_y_return;
+ unsigned int mask_return;
+ Window root_return, child_return;
+
+ XQueryPointer(drw.dis, drw.root, &root_return, &child_return,
+ x, y, &win_x_return, &win_y_return, &mask_return);
+}
+
+void init()
+{
+ XWindowAttributes wa;
+ XSetWindowAttributes swa;
+
+ drw.dis = XOpenDisplay(NULL);
+ drw.screen = DefaultScreen(drw.dis);
+ drw.root = RootWindow(drw.dis, drw.screen);
+ if (!XGetWindowAttributes(drw.dis, drw.root, &wa))
+ die("could not get embedding window attributes: 0x%lx", drw.root);
+
+ drw.w = wa.width;
+ drw.h = wa.height;
+ //drw.drawable = XCreatePixmap(drw.dis, drw.root, drw.w, drw.h, DefaultDepth(drw.dis, drw.screen));
+ drw.gc = XCreateGC(drw.dis, drw.root, 0, NULL);
+ XSetLineAttributes(drw.dis, drw.gc, 1, LineSolid, CapButt, JoinMiter);
+
+ swa.override_redirect = True;
+ swa.background_pixel = BlackPixel(drw.dis, drw.screen);
+ swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
+
+ int x, y;
+ get_curson_pos(&x, &y);
+
+ int height = 16 + (9 + 3)*w_height - 3 + 16,
+ width = 16 + w_width*9;
+ drw.win = XCreateWindow(drw.dis, drw.root, x, y, width, height, 0,
+ CopyFromParent, CopyFromParent, CopyFromParent,
+ CWOverrideRedirect | CWBackPixel | CWEventMask, &swa);
+
+ printf("Window pos: {%d, %d}", x, y);
+ fflush(stdout);
+
+ cm = DefaultColormap(drw.dis, drw.screen);
+ if (! XAllocNamedColor(drw.dis, cm, "red", &red, &red)) {
+ fprintf(stderr, "XAllocNamedColor - failed to allocated 'red' color.\n");
+ exit(1);
+ }
+ XMapRaised(drw.dis, drw.win);
+ XRaiseWindow(drw.dis, drw.win);
+}
+
void init_x()
{
/* get the colors black and white (see section for details) */
@@ -109,9 +195,9 @@ void init_x()
void close_x()
{
- XFreeGC(dis, gc);
- XDestroyWindow(dis,win);
- XCloseDisplay(dis);
+ XFreeGC(drw.dis, drw.gc);
+ XDestroyWindow(drw.dis,drw.win);
+ XCloseDisplay(drw.dis);
}
@@ -154,6 +240,9 @@ int parse_line(char * line)
lnch[idx].exits = 1;
+ if (line[0] == '#')
+ return 0;
+
if (line[0] == '&') {
lnch[idx].exits = 0;
line++;
@@ -171,6 +260,9 @@ int parse_line(char * line)
/* Get description */
token = strtok(NULL, delim);
+ if (!token) return 1;
+
+ w_width = MAX((int) strlen(token), w_width);
strcpy(lnch[idx].desc, token);
line+=(strlen(token) + 1 ); // pass the decription, pass the `:`
@@ -235,10 +327,10 @@ void grabfocus()
int i, revertwin;
for (i = 0; i < 100; ++i) {
- XGetInputFocus(dis, &focuswin, &revertwin);
- if (focuswin == win)
+ XGetInputFocus(drw.dis, &focuswin, &revertwin);
+ if (focuswin == drw.win)
return;
- XSetInputFocus(dis, win, RevertToParent, CurrentTime);
+ XSetInputFocus(drw.dis, drw.win, RevertToParent, CurrentTime);
nanosleep(&ts, NULL);
}
printf("cannot grab focus\n");
@@ -251,7 +343,7 @@ void grabkeyboard()
/* try to grab keyboard, we may have to wait for another process to ungrab */
for (i = 0; i < 1000; i++) {
- if (XGrabKeyboard(dis, DefaultRootWindow(dis), True, GrabModeAsync,
+ if (XGrabKeyboard(drw.dis, drw.root, True, GrabModeAsync,
GrabModeAsync, CurrentTime) == GrabSuccess)
return;
nanosleep(&ts, NULL);
@@ -265,17 +357,17 @@ void draw_text()
int x = 10, y = 10;
for (unsigned int i = 0; i < idx; i++) {
if (lnch[i].exits)
- XSetForeground(dis,gc,WhitePixel(dis,DefaultScreen(dis)));
+ XSetForeground(drw.dis,drw.gc,WhitePixel(drw.dis,drw.screen));
else
- XSetForeground(dis,gc,red.pixel);
+ XSetForeground(drw.dis,drw.gc,red.pixel);
sprintf(text, "%c: %s", lnch[i].key, lnch[i].desc);
- XDrawString(dis,win,gc,x,y+=13, text, strlen(text));
+ XDrawString(drw.dis,drw.win,drw.gc,x,y+=13, text, strlen(text));
}
}
void redraw()
{
- XClearWindow(dis, win);
+ XClearWindow(drw.dis, drw.win);
draw_text();
}
@@ -286,27 +378,33 @@ int main (int argc, char *argv[])
printf("xlnchrc format:\n[&]<key>:<description>:<command>\n");
return -1;
}
+
FILE *f;
- f = fopen(argv[1], "r");
- if (!f) {
- printf("xlnchrc required\n");
- return -1;
+ if (!strcmp(argv[1], "-"))
+ f = stdin;
+ else {
+ f = fopen(argv[1], "r");
+ /* printf("xlnchrc required\n"); */
+ /* return -1; */
}
while (fgets(buf, BUF_SIZE, f)) {
trim(buf);
parse_line(buf);
+ w_height++;
}
- fclose(f);
+
+ if (f != stdin) fclose(f);
XEvent event; /* the XEvent declaration !!! */
KeySym key; /* a dealie-bob to handle KeyPress Events */
char text[255]; /* a char buffer for KeyPress Events */
int rc;
- init_x();
+ init();
+ // system("sleep 100");
grabkeyboard();
grabfocus();
@@ -315,13 +413,19 @@ int main (int argc, char *argv[])
/* get the next event and stuff it into our event variable.
Note: only events we set the mask for are detected!
*/
- XNextEvent(dis, &event);
+ XNextEvent(drw.dis, &event);
if (event.type==Expose && event.xexpose.count==0) {
/* the window was exposed redraw it! */
redraw();
}
+ /* Keep window in view */
+ if (event.type==VisibilityNotify &&
+ event.xvisibility.state != VisibilityUnobscured)
+ XRaiseWindow(drw.dis, drw.win);
+
+
if (event.type==KeyPress &&
XLookupString(&event.xkey,text,255,&key,0)==1) {
/* use the XLookupString routine to convert the invent
@@ -349,8 +453,8 @@ int main (int argc, char *argv[])
y=event.xbutton.y;
strcpy(text,">>xlnch<<");
- XSetForeground(dis,gc,rand()%255);
- XDrawString(dis,win,gc,x,y, text, strlen(text));
+ XSetForeground(drw.dis,drw.gc,rand()%255);
+ XDrawString(drw.dis,drw.win,drw.gc,x,y, text, strlen(text));
}
if (event.type==FocusIn) {