aboutsummaryrefslogtreecommitdiff
path: root/x.c
diff options
context:
space:
mode:
Diffstat (limited to 'x.c')
-rw-r--r--x.c94
1 files changed, 71 insertions, 23 deletions
diff --git a/x.c b/x.c
index c1d37a2..8942a46 100644
--- a/x.c
+++ b/x.c
@@ -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