diff options
Diffstat (limited to 'x.c')
-rw-r--r-- | x.c | 94 |
1 files changed, 71 insertions, 23 deletions
@@ -63,7 +63,7 @@ typedef struct { /* X modifiers */ #define XK_ANY_MOD UINT_MAX #define XK_NO_MOD 0 -#define XK_SWITCH_MOD (1<<13) +#define XK_SWITCH_MOD (1<<13|1<<14) /* function definitions used in config.h */ static void clipcopy(const Arg *); @@ -173,9 +173,9 @@ static void xresize(int, int); static void xhints(void); static int xloadcolor(int, const char *, Color *); static int xloadfont(Font *, FcPattern *); -static void xloadfonts(char *, double); static int xloadsparefont(FcPattern *, int); static void xloadsparefonts(void); +static void xloadfonts(const char *, double); static void xunloadfont(Font *); static void xunloadfonts(void); static void xsetenv(void); @@ -277,6 +277,7 @@ static int focused = 0; static int oldbutton = 3; /* button event on startup: 3 = release */ static int cursorblinks = 0; +static uint buttons; /* bit field of pressed buttons */ void clipcopy(const Arg *dummy) @@ -459,7 +460,7 @@ mousereport(XEvent *e) if (IS_SET(MODE_MOUSESGR)) { len = snprintf(buf, sizeof(buf), "\033[<%d;%d;%d%c", button, x+1, y+1, - e->xbutton.type == ButtonRelease ? 'm' : 'M'); + e->type == ButtonRelease ? 'm' : 'M'); } else if (x < 223 && y < 223) { len = snprintf(buf, sizeof(buf), "\033[M%c%c%c", 32+button, 32+x+1, 32+y+1); @@ -505,9 +506,13 @@ mouseaction(XEvent *e, uint release) void bpress(XEvent *e) { + int btn = e->xbutton.button; struct timespec now; int snap; + if (1 <= btn && btn <= 11) + buttons |= 1 << (btn-1); + if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) { mousereport(e); return; @@ -516,7 +521,7 @@ bpress(XEvent *e) if (mouseaction(e, 0)) return; - if (e->xbutton.button == Button1) { + if (btn == Button1) { /* * If the user clicks below predefined timeouts specific * snapping behaviour is exposed. @@ -730,6 +735,11 @@ xsetsel(char *str) void brelease(XEvent *e) { + int btn = e->xbutton.button; + + if (1 <= btn && btn <= 11) + buttons &= ~(1 << (btn-1)); + if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) { mousereport(e); return; @@ -737,7 +747,7 @@ brelease(XEvent *e) if (mouseaction(e, 1)) return; - if (e->xbutton.button == Button1) + if (btn == Button1) mousesel(e, 1); } @@ -856,6 +866,19 @@ xloadcols(void) } int +xgetcolor(int x, unsigned char *r, unsigned char *g, unsigned char *b) +{ + if (!BETWEEN(x, 0, dc.collen)) + return 1; + + *r = dc.col[x].color.red >> 8; + *g = dc.col[x].color.green >> 8; + *b = dc.col[x].color.blue >> 8; + + return 0; +} + +int xsetcolorname(int x, const char *name) { Color ncolor; @@ -1008,7 +1031,7 @@ xloadfont(Font *f, FcPattern *pattern) } void -xloadfonts(char *fontstr, double fontsize) +xloadfonts(const char *fontstr, double fontsize) { FcPattern *pattern; double fontval; @@ -1016,7 +1039,7 @@ xloadfonts(char *fontstr, double fontsize) if (fontstr[0] == '-') pattern = XftXlfdParse(fontstr, False, False); else - pattern = FcNameParse((FcChar8 *)fontstr); + pattern = FcNameParse((const FcChar8 *)fontstr); if (!pattern) die("can't open font %s\n", fontstr); @@ -1642,11 +1665,11 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i /* Render underline and strikethrough. */ if (base.mode & ATTR_UNDERLINE) { XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent + 1, - width, 1); + width, 1); } if (base.mode & ATTR_STRUCK) { - XftDrawRect(xw.draw, fg, winx, winy + 2 * dc.font.ascent / 3, + XftDrawRect(xw.draw, fg, winx, winy + 2 * dc.font.ascent * chscale / 3, width, 1); } @@ -1782,8 +1805,9 @@ xseticontitle(char *p) XTextProperty prop; DEFAULT(p, opt_title); - Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle, - &prop); + if (Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle, + &prop) != Success) + return; XSetWMIconName(xw.dpy, xw.win, &prop); XSetTextProperty(xw.dpy, xw.win, &prop, xw.netwmiconname); XFree(prop.value); @@ -1795,8 +1819,9 @@ xsettitle(char *p) XTextProperty prop; DEFAULT(p, opt_title); - Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle, - &prop); + if (Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle, + &prop) != Success) + return; XSetWMName(xw.dpy, xw.win, &prop); XSetTextProperty(xw.dpy, xw.win, &prop, xw.netwmname); XFree(prop.value); @@ -2010,8 +2035,10 @@ kpress(XEvent *ev) { XKeyEvent *e = &ev->xkey; KeySym ksym; - char buf[64], *customkey; - int len; + char *buf = NULL, *customkey; + int len = 0; + int buf_size = 64; + int critical = - 1; Rune c; Status status; Shortcut *bp; @@ -2019,27 +2046,44 @@ kpress(XEvent *ev) if (IS_SET(MODE_KBDLOCK)) return; - if (xw.ime.xic) - len = XmbLookupString(xw.ime.xic, e, buf, sizeof buf, &ksym, &status); - else - len = XLookupString(e, buf, sizeof buf, &ksym, NULL); +reallocbuf: + if (critical > 0) + goto cleanup; + if (buf) + free(buf); + + buf = xmalloc((buf_size) * sizeof(char)); + critical += 1; + + if (xw.ime.xic) { + len = XmbLookupString(xw.ime.xic, e, buf, buf_size, &ksym, &status); + if (status == XBufferOverflow) { + buf_size = len; + goto reallocbuf; + } + } else { + // Not sure how to fix this and if it is fixable + // but at least it does write something into the buffer + // so it is not as critical + len = XLookupString(e, buf, buf_size, &ksym, NULL); + } /* 1. shortcuts */ for (bp = shortcuts; bp < shortcuts + LEN(shortcuts); bp++) { if (ksym == bp->keysym && match(bp->mod, e->state)) { bp->func(&(bp->arg)); - return; + goto cleanup; } } /* 2. custom keys from config.h */ if ((customkey = kmap(ksym, e->state))) { ttywrite(customkey, strlen(customkey), 1); - return; + goto cleanup; } /* 3. composed string from input method */ if (len == 0) - return; + goto cleanup; if (len == 1 && e->state & Mod1Mask) { if (IS_SET(MODE_8BIT)) { if (*buf < 0177) { @@ -2052,7 +2096,11 @@ kpress(XEvent *ev) len = 2; } } - ttywrite(buf, len, 1); + if (len <= buf_size) + ttywrite(buf, len, 1); +cleanup: + if (buf) + free(buf); } void |