Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package st for openSUSE:Factory checked in 
at 2023-01-17 17:36:05
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/st (Old)
 and      /work/SRC/openSUSE:Factory/.st.new.32243 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "st"

Tue Jan 17 17:36:05 2023 rev:3 rq:1058922 version:0.9

Changes:
--------
--- /work/SRC/openSUSE:Factory/st/st.changes    2020-06-25 15:09:34.577769728 
+0200
+++ /work/SRC/openSUSE:Factory/.st.new.32243/st.changes 2023-01-17 
17:36:22.641545016 +0100
@@ -1,0 +2,19 @@
+Mon Jan  2 13:40:02 UTC 2023 - Dirk Müller <dmuel...@suse.com>
+
+- update to 0.9:
+  * avoid potential UB when using isprint()
+  * make underlines and strikethroughs respect `chscale`
+  * Delay redrawals on palette changes
+  * 10/SGR mouse: use alt as meta key instead of super/windows key
+  * Fix mousereport
+  * Fix overtyping wide characters.
+  * Fix null pointer access in strhandle
+  * Add support for OSC color sequences
+  * Fix possible rare crash when Xutf8TextPropertyToTextList fails
+  * fix a problem that the standard streams are unexpectedly closed
+  * Add 14th bit to XK_SWITCH_MOD bitmask
+  * fix: correctly encode mouse buttons >= 8 in X10 and SGR mode
+  * ST: Add WM_ICON_NAME property support
+- add compose-buffer-overflow.patch
+
+-------------------------------------------------------------------

Old:
----
  st-0.8.4.tar.gz

New:
----
  compose-buffer-overflow.patch
  st-0.9.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ st.spec ++++++
--- /var/tmp/diff_new_pack.vnl9s2/_old  2023-01-17 17:36:23.213548241 +0100
+++ /var/tmp/diff_new_pack.vnl9s2/_new  2023-01-17 17:36:23.221548287 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package st
 #
-# Copyright (c) 2020 SUSE LLC
+# Copyright (c) 2023 SUSE LLC
 # Copyright (c) 2013 Pascal Bleser <pascal.ble...@opensuse.org>
 #
 # All modifications and additions to the file contributed by third parties
@@ -18,7 +18,7 @@
 
 
 Name:           st
-Version:        0.8.4
+Version:        0.9
 Release:        0
 Summary:        Simple Terminal Implementation for X
 License:        MIT
@@ -26,6 +26,7 @@
 URL:            https://%{name}.suckless.org/
 Source:         https://dl.suckless.org/%{name}/%{name}-%{version}.tar.gz
 Source1:        %{name}.desktop
+Patch1:         compose-buffer-overflow.patch
 BuildRequires:  fontconfig-devel
 BuildRequires:  freetype2-devel
 BuildRequires:  gcc
@@ -41,7 +42,7 @@
 Simple and lightweight and unbloated X11 terminal.
 
 %prep
-%autosetup
+%autosetup -p1
 # terminfo entries are provided by terminfo from ncurses
 sed -e "/tic .*st.info/d" -i Makefile
 

++++++ compose-buffer-overflow.patch ++++++
fix buffer overflow when handling long composed input

To reproduce the issue:

"
If you already have the multi-key enabled on your system, then add this line
to your ~/.XCompose file:

[...]
<question> <T> <E> <S> <T> <question> :
"1234567890123456789012345678901234567890123456789012345678901234567890"
"

Reported by and an initial patch by Andy Gozas <a...@gozas.me>, thanks!

Adapted the patch, for now st (like dmenu) handles a fixed amount of composed
characters, or otherwise ignores it. This is done for simplicity sake.

--- a/x.c
+++ b/x.c
@@ -1833,7 +1833,7 @@ void
 kpress(XEvent *ev)
 {
        XKeyEvent *e = &ev->xkey;
-       KeySym ksym;
+       KeySym ksym = NoSymbol;
        char buf[64], *customkey;
        int len;
        Rune c;
@@ -1843,10 +1843,13 @@ kpress(XEvent *ev)
        if (IS_SET(MODE_KBDLOCK))
                return;
 
-       if (xw.ime.xic)
+       if (xw.ime.xic) {
                len = XmbLookupString(xw.ime.xic, e, buf, sizeof buf, &ksym, 
&status);
-       else
+               if (status == XBufferOverflow)
+                       return;
+       } else {
                len = XLookupString(e, buf, sizeof buf, &ksym, NULL);
+       }
        /* 1. shortcuts */
        for (bp = shortcuts; bp < shortcuts + LEN(shortcuts); bp++) {
                if (ksym == bp->keysym && match(bp->mod, e->state)) {

++++++ st-0.8.4.tar.gz -> st-0.9.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/st-0.8.4/FAQ new/st-0.9/FAQ
--- old/st-0.8.4/FAQ    2020-06-19 11:29:45.000000000 +0200
+++ new/st-0.9/FAQ      2022-10-04 19:41:26.000000000 +0200
@@ -29,8 +29,8 @@
 
 ## I would like to have utmp and/or scroll functionality by default
 
-You can add the absolute patch of both programs in your config.h
-file. You only have to modify the value of utmp and scroll variables.
+You can add the absolute path of both programs in your config.h file. You only
+have to modify the value of utmp and scroll variables.
 
 
 ## Why doesn't the Del key work in some programs?
@@ -248,3 +248,6 @@
 
 Please don't bother reporting this bug to st, but notify the upstream Xft
 developers about fixing this bug.
+
+As of 2022-09-05 this now seems to be finally fixed in libXft 2.3.5:
+https://gitlab.freedesktop.org/xorg/lib/libxft/-/blob/libXft-2.3.5/NEWS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/st-0.8.4/LICENSE new/st-0.9/LICENSE
--- old/st-0.8.4/LICENSE        2020-06-19 11:29:45.000000000 +0200
+++ new/st-0.9/LICENSE  2022-10-04 19:41:26.000000000 +0200
@@ -1,6 +1,6 @@
 MIT/X Consortium License
 
-© 2014-2020 Hiltjo Posthuma <hiltjo at codemadness dot org>
+© 2014-2022 Hiltjo Posthuma <hiltjo at codemadness dot org>
 © 2018 Devin J. Pohly <djpohly at gmail dot com>
 © 2014-2017 Quentin Rameau <quinq at fifth dot space>
 © 2009-2012 Aurélien APTEL <aurelien dot aptel at gmail dot com>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/st-0.8.4/config.def.h new/st-0.9/config.def.h
--- old/st-0.8.4/config.def.h   2020-06-19 11:29:45.000000000 +0200
+++ new/st-0.9/config.def.h     2022-10-04 19:41:26.000000000 +0200
@@ -120,6 +120,8 @@
        /* more colors can be added after 255 to use with DefaultXX */
        "#cccccc",
        "#555555",
+       "gray90", /* default foreground colour */
+       "black", /* default background colour */
 };
 
 
@@ -127,9 +129,9 @@
  * Default colors (colorname index)
  * foreground, background, cursor, reverse cursor
  */
-unsigned int defaultfg = 7;
-unsigned int defaultbg = 0;
-static unsigned int defaultcs = 256;
+unsigned int defaultfg = 258;
+unsigned int defaultbg = 259;
+unsigned int defaultcs = 256;
 static unsigned int defaultrcs = 257;
 
 /*
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/st-0.8.4/config.mk new/st-0.9/config.mk
--- old/st-0.8.4/config.mk      2020-06-19 11:29:45.000000000 +0200
+++ new/st-0.9/config.mk        2022-10-04 19:41:26.000000000 +0200
@@ -1,5 +1,5 @@
 # st version
-VERSION = 0.8.4
+VERSION = 0.9
 
 # Customize below to fit your system
 
@@ -30,6 +30,7 @@
 #LIBS = -L$(X11LIB) -lm -lX11 -lutil -lXft \
 #       `$(PKG_CONFIG) --libs fontconfig` \
 #       `$(PKG_CONFIG) --libs freetype2`
+#MANPREFIX = ${PREFIX}/man
 
 # compiler and linker
 # CC = c99
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/st-0.8.4/st.c new/st-0.9/st.c
--- old/st-0.8.4/st.c   2020-06-19 11:29:45.000000000 +0200
+++ new/st-0.9/st.c     2022-10-04 19:41:26.000000000 +0200
@@ -161,6 +161,7 @@
 static void csihandle(void);
 static void csiparse(void);
 static void csireset(void);
+static void osc_color_response(int, int, int);
 static int eschandle(uchar);
 static void strdump(void);
 static void strhandle(void);
@@ -186,18 +187,18 @@
 static void treset(void);
 static void tscrollup(int, int);
 static void tscrolldown(int, int);
-static void tsetattr(int *, int);
-static void tsetchar(Rune, Glyph *, int, int);
+static void tsetattr(const int *, int);
+static void tsetchar(Rune, const Glyph *, int, int);
 static void tsetdirt(int, int);
 static void tsetscroll(int, int);
 static void tswapscreen(void);
-static void tsetmode(int, int, int *, int);
+static void tsetmode(int, int, const int *, int);
 static int twrite(const char *, int, int);
 static void tfulldirt(void);
 static void tcontrolcode(uchar );
 static void tdectest(char );
 static void tdefutf8(char);
-static int32_t tdefcolor(int *, int *, int);
+static int32_t tdefcolor(const int *, int *, int);
 static void tdeftran(char);
 static void tstrsequence(uchar);
 
@@ -226,10 +227,10 @@
 static int cmdfd;
 static pid_t pid;
 
-static uchar utfbyte[UTF_SIZ + 1] = {0x80,    0, 0xC0, 0xE0, 0xF0};
-static uchar utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
-static Rune utfmin[UTF_SIZ + 1] = {       0,    0,  0x80,  0x800,  0x10000};
-static Rune utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
+static const uchar utfbyte[UTF_SIZ + 1] = {0x80,    0, 0xC0, 0xE0, 0xF0};
+static const uchar utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
+static const Rune utfmin[UTF_SIZ + 1] = {       0,    0,  0x80,  0x800,  
0x10000};
+static const Rune utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 
0x10FFFF};
 
 ssize_t
 xwrite(int fd, const char *s, size_t len)
@@ -269,12 +270,14 @@
 }
 
 char *
-xstrdup(char *s)
+xstrdup(const char *s)
 {
-       if ((s = strdup(s)) == NULL)
+       char *p;
+
+       if ((p = strdup(s)) == NULL)
                die("strdup: %s\n", strerror(errno));
 
-       return s;
+       return p;
 }
 
 size_t
@@ -347,25 +350,10 @@
        return i;
 }
 
-static const char base64_digits[] = {
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0,
-       63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, -1, 0, 0, 0, 0, 1,
-       2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
-       22, 23, 24, 25, 0, 0, 0, 0, 0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34,
-       35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
 char
 base64dec_getc(const char **src)
 {
-       while (**src && !isprint(**src))
+       while (**src && !isprint((unsigned char)**src))
                (*src)++;
        return **src ? *((*src)++) : '=';  /* emulate padding if string ends */
 }
@@ -375,6 +363,13 @@
 {
        size_t in_len = strlen(src);
        char *result, *dst;
+       static const char base64_digits[256] = {
+               [43] = 62, 0, 0, 0, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
+               0, 0, 0, -1, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+               13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0,
+               0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+               40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
+       };
 
        if (in_len % 4)
                in_len += 4 - (in_len % 4);
@@ -518,7 +513,7 @@
 {
        int newx, newy, xt, yt;
        int delim, prevdelim;
-       Glyph *gp, *prevgp;
+       const Glyph *gp, *prevgp;
 
        switch (sel.snap) {
        case SNAP_WORD:
@@ -591,7 +586,7 @@
 {
        char *str, *ptr;
        int y, bufsize, lastx, linelen;
-       Glyph *gp, *last;
+       const Glyph *gp, *last;
 
        if (sel.ob.x == -1)
                return NULL;
@@ -758,7 +753,7 @@
 }
 
 int
-ttynew(char *line, char *cmd, char *out, char **args)
+ttynew(const char *line, char *cmd, const char *out, char **args)
 {
        int m, s;
 
@@ -791,14 +786,15 @@
                break;
        case 0:
                close(iofd);
+               close(m);
                setsid(); /* create a new process group */
                dup2(s, 0);
                dup2(s, 1);
                dup2(s, 2);
                if (ioctl(s, TIOCSCTTY, NULL) < 0)
                        die("ioctl TIOCSCTTY failed: %s\n", strerror(errno));
-               close(s);
-               close(m);
+               if (s > 2)
+                       close(s);
 #ifdef __OpenBSD__
                if (pledge("stdio getpw proc exec", NULL) == -1)
                        die("pledge\n");
@@ -943,7 +939,7 @@
 }
 
 void
-ttyhangup()
+ttyhangup(void)
 {
        /* Send SIGHUP to shell */
        kill(pid, SIGHUP);
@@ -1186,9 +1182,9 @@
 }
 
 void
-tsetchar(Rune u, Glyph *attr, int x, int y)
+tsetchar(Rune u, const Glyph *attr, int x, int y)
 {
-       static char *vt100_0[62] = { /* 0x41 - 0x7e */
+       static const char *vt100_0[62] = { /* 0x41 - 0x7e */
                "↑", "↓", "→", "←", "█", "▚", "☃", /* A - G */
                0, 0, 0, 0, 0, 0, 0, 0, /* H - O */
                0, 0, 0, 0, 0, 0, 0, 0, /* P - W */
@@ -1300,7 +1296,7 @@
 }
 
 int32_t
-tdefcolor(int *attr, int *npar, int l)
+tdefcolor(const int *attr, int *npar, int l)
 {
        int32_t idx = -1;
        uint r, g, b;
@@ -1350,7 +1346,7 @@
 }
 
 void
-tsetattr(int *attr, int l)
+tsetattr(const int *attr, int l)
 {
        int i;
        int32_t idx;
@@ -1468,9 +1464,9 @@
 }
 
 void
-tsetmode(int priv, int set, int *args, int narg)
+tsetmode(int priv, int set, const int *args, int narg)
 {
-       int alt, *lim;
+       int alt; const int *lim;
 
        for (lim = args + narg; args < lim; ++args) {
                if (priv) {
@@ -1840,10 +1836,40 @@
 }
 
 void
+osc_color_response(int num, int index, int is_osc4)
+{
+       int n;
+       char buf[32];
+       unsigned char r, g, b;
+
+       if (xgetcolor(is_osc4 ? num : index, &r, &g, &b)) {
+               fprintf(stderr, "erresc: failed to fetch %s color %d\n",
+                       is_osc4 ? "osc4" : "osc",
+                       is_osc4 ? num : index);
+               return;
+       }
+
+       n = snprintf(buf, sizeof buf, 
"\033]%s%d;rgb:%02x%02x/%02x%02x/%02x%02x\007",
+                    is_osc4 ? "4;" : "", num, r, r, g, g, b, b);
+       if (n < 0 || n >= sizeof(buf)) {
+               fprintf(stderr, "error: %s while printing %s response\n",
+                       n < 0 ? "snprintf failed" : "truncation occurred",
+                       is_osc4 ? "osc4" : "osc");
+       } else {
+               ttywrite(buf, n, 1);
+       }
+}
+
+void
 strhandle(void)
 {
        char *p = NULL, *dec;
        int j, narg, par;
+       const struct { int idx; char *str; } osc_table[] = {
+               { defaultfg, "foreground" },
+               { defaultbg, "background" },
+               { defaultcs, "cursor" }
+       };
 
        term.esc &= ~(ESC_STR_END|ESC_STR);
        strparse();
@@ -1853,7 +1879,15 @@
        case ']': /* OSC -- Operating System Command */
                switch (par) {
                case 0:
+                       if (narg > 1) {
+                               xsettitle(strescseq.args[1]);
+                               xseticontitle(strescseq.args[1]);
+                       }
+                       return;
                case 1:
+                       if (narg > 1)
+                               xseticontitle(strescseq.args[1]);
+                       return;
                case 2:
                        if (narg > 1)
                                xsettitle(strescseq.args[1]);
@@ -1869,14 +1903,35 @@
                                }
                        }
                        return;
+               case 10:
+               case 11:
+               case 12:
+                       if (narg < 2)
+                               break;
+                       p = strescseq.args[1];
+                       if ((j = par - 10) < 0 || j >= LEN(osc_table))
+                               break; /* shouldn't be possible */
+
+                       if (!strcmp(p, "?")) {
+                               osc_color_response(par, osc_table[j].idx, 0);
+                       } else if (xsetcolorname(osc_table[j].idx, p)) {
+                               fprintf(stderr, "erresc: invalid %s color: 
%s\n",
+                                       osc_table[j].str, p);
+                       } else {
+                               tfulldirt();
+                       }
+                       return;
                case 4: /* color set */
                        if (narg < 3)
                                break;
                        p = strescseq.args[2];
                        /* FALLTHROUGH */
-               case 104: /* color reset, here p = NULL */
+               case 104: /* color reset */
                        j = (narg > 1) ? atoi(strescseq.args[1]) : -1;
-                       if (xsetcolorname(j, p)) {
+
+                       if (p && !strcmp(p, "?")) {
+                               osc_color_response(j, 0, 1);
+                       } else if (xsetcolorname(j, p)) {
                                if (par == 104 && narg <= 1)
                                        return; /* color reset without 
parameter */
                                fprintf(stderr, "erresc: invalid color j=%d, 
p=%s\n",
@@ -1886,7 +1941,7 @@
                                 * TODO if defaultbg color is changed, borders
                                 * are dirty
                                 */
-                               redraw();
+                               tfulldirt();
                        }
                        return;
                }
@@ -2012,7 +2067,7 @@
 tdumpline(int n)
 {
        char buf[UTF_SIZ];
-       Glyph *bp, *end;
+       const Glyph *bp, *end;
 
        bp = &term.line[n][0];
        end = &bp[MIN(tlinelen(n), term.col) - 1];
@@ -2418,6 +2473,10 @@
        if (width == 2) {
                gp->mode |= ATTR_WIDE;
                if (term.c.x+1 < term.col) {
+                       if (gp[1].mode == ATTR_WIDE && term.c.x+2 < term.col) {
+                               gp[2].u = ' ';
+                               gp[2].mode &= ~ATTR_WDUMMY;
+                       }
                        gp[1].u = '\0';
                        gp[1].mode = ATTR_WDUMMY;
                }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/st-0.8.4/st.h new/st-0.9/st.h
--- old/st-0.8.4/st.h   2020-06-19 11:29:45.000000000 +0200
+++ new/st-0.9/st.h     2022-10-04 19:41:26.000000000 +0200
@@ -91,7 +91,7 @@
 void tresize(int, int);
 void tsetdirtattr(int);
 void ttyhangup(void);
-int ttynew(char *, char *, char *, char **);
+int ttynew(const char *, char *, const char *, char **);
 size_t ttyread(void);
 void ttyresize(int, int);
 void ttywrite(const char *, size_t, int);
@@ -109,7 +109,7 @@
 
 void *xmalloc(size_t);
 void *xrealloc(void *, size_t);
-char *xstrdup(char *);
+char *xstrdup(const char *);
 
 /* config.h globals */
 extern char *utmp;
@@ -123,3 +123,4 @@
 extern unsigned int tabspaces;
 extern unsigned int defaultfg;
 extern unsigned int defaultbg;
+extern unsigned int defaultcs;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/st-0.8.4/win.h new/st-0.9/win.h
--- old/st-0.8.4/win.h  2020-06-19 11:29:45.000000000 +0200
+++ new/st-0.9/win.h    2022-10-04 19:41:26.000000000 +0200
@@ -30,6 +30,8 @@
 void xfinishdraw(void);
 void xloadcols(void);
 int xsetcolorname(int, const char *);
+int xgetcolor(int, unsigned char *, unsigned char *, unsigned char *);
+void xseticontitle(char *);
 void xsettitle(char *);
 int xsetcursor(int);
 void xsetmode(int, unsigned int);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/st-0.8.4/x.c new/st-0.9/x.c
--- old/st-0.8.4/x.c    2020-06-19 11:29:45.000000000 +0200
+++ new/st-0.9/x.c      2022-10-04 19:41:26.000000000 +0200
@@ -48,7 +48,7 @@
 /* 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 *);
@@ -93,7 +93,7 @@
        Window win;
        Drawable buf;
        GlyphFontSpec *specbuf; /* font spec buffer used for rendering */
-       Atom xembed, wmdeletewin, netwmname, netwmpid;
+       Atom xembed, wmdeletewin, netwmname, netwmiconname, netwmpid;
        struct {
                XIM xim;
                XIC xic;
@@ -156,7 +156,7 @@
 static void xhints(void);
 static int xloadcolor(int, const char *, Color *);
 static int xloadfont(Font *, FcPattern *);
-static void xloadfonts(char *, double);
+static void xloadfonts(const char *, double);
 static void xunloadfont(Font *);
 static void xunloadfonts(void);
 static void xsetenv(void);
@@ -252,7 +252,7 @@
 static char *opt_name  = NULL;
 static char *opt_title = NULL;
 
-static int oldbutton = 3; /* button event on startup: 3 = release */
+static uint buttons; /* bit field of pressed buttons */
 
 void
 clipcopy(const Arg *dummy)
@@ -364,59 +364,68 @@
 void
 mousereport(XEvent *e)
 {
-       int len, x = evcol(e), y = evrow(e),
-           button = e->xbutton.button, state = e->xbutton.state;
+       int len, btn, code;
+       int x = evcol(e), y = evrow(e);
+       int state = e->xbutton.state;
        char buf[40];
        static int ox, oy;
 
-       /* from urxvt */
-       if (e->xbutton.type == MotionNotify) {
+       if (e->type == MotionNotify) {
                if (x == ox && y == oy)
                        return;
                if (!IS_SET(MODE_MOUSEMOTION) && !IS_SET(MODE_MOUSEMANY))
                        return;
-               /* MOUSE_MOTION: no reporting if no button is pressed */
-               if (IS_SET(MODE_MOUSEMOTION) && oldbutton == 3)
+               /* MODE_MOUSEMOTION: no reporting if no button is pressed */
+               if (IS_SET(MODE_MOUSEMOTION) && buttons == 0)
                        return;
-
-               button = oldbutton + 32;
-               ox = x;
-               oy = y;
+               /* Set btn to lowest-numbered pressed button, or 12 if no
+                * buttons are pressed. */
+               for (btn = 1; btn <= 11 && !(buttons & (1<<(btn-1))); btn++)
+                       ;
+               code = 32;
        } else {
-               if (!IS_SET(MODE_MOUSESGR) && e->xbutton.type == ButtonRelease) 
{
-                       button = 3;
-               } else {
-                       button -= Button1;
-                       if (button >= 3)
-                               button += 64 - 3;
-               }
-               if (e->xbutton.type == ButtonPress) {
-                       oldbutton = button;
-                       ox = x;
-                       oy = y;
-               } else if (e->xbutton.type == ButtonRelease) {
-                       oldbutton = 3;
+               btn = e->xbutton.button;
+               /* Only buttons 1 through 11 can be encoded */
+               if (btn < 1 || btn > 11)
+                       return;
+               if (e->type == ButtonRelease) {
                        /* MODE_MOUSEX10: no button release reporting */
                        if (IS_SET(MODE_MOUSEX10))
                                return;
-                       if (button == 64 || button == 65)
+                       /* Don't send release events for the scroll wheel */
+                       if (btn == 4 || btn == 5)
                                return;
                }
+               code = 0;
        }
 
+       ox = x;
+       oy = y;
+
+       /* Encode btn into code. If no button is pressed for a motion event in
+        * MODE_MOUSEMANY, then encode it as a release. */
+       if ((!IS_SET(MODE_MOUSESGR) && e->type == ButtonRelease) || btn == 12)
+               code += 3;
+       else if (btn >= 8)
+               code += 128 + btn - 8;
+       else if (btn >= 4)
+               code += 64 + btn - 4;
+       else
+               code += btn - 1;
+
        if (!IS_SET(MODE_MOUSEX10)) {
-               button += ((state & ShiftMask  ) ? 4  : 0)
-                       + ((state & Mod4Mask   ) ? 8  : 0)
-                       + ((state & ControlMask) ? 16 : 0);
+               code += ((state & ShiftMask  ) ?  4 : 0)
+                     + ((state & Mod1Mask   ) ?  8 : 0) /* meta key: alt */
+                     + ((state & ControlMask) ? 16 : 0);
        }
 
        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');
+                               code, x+1, y+1,
+                               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);
+                               32+code, 32+x+1, 32+y+1);
        } else {
                return;
        }
@@ -459,9 +468,13 @@
 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;
@@ -470,7 +483,7 @@
        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.
@@ -684,6 +697,11 @@
 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;
@@ -691,7 +709,7 @@
 
        if (mouseaction(e, 1))
                return;
-       if (e->xbutton.button == Button1)
+       if (btn == Button1)
                mousesel(e, 1);
 }
 
@@ -798,6 +816,19 @@
 }
 
 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;
@@ -950,7 +981,7 @@
 }
 
 void
-xloadfonts(char *fontstr, double fontsize)
+xloadfonts(const char *fontstr, double fontsize)
 {
        FcPattern *pattern;
        double fontval;
@@ -958,7 +989,7 @@
        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);
@@ -1186,6 +1217,7 @@
        xw.xembed = XInternAtom(xw.dpy, "_XEMBED", False);
        xw.wmdeletewin = XInternAtom(xw.dpy, "WM_DELETE_WINDOW", False);
        xw.netwmname = XInternAtom(xw.dpy, "_NET_WM_NAME", False);
+       xw.netwmiconname = XInternAtom(xw.dpy, "_NET_WM_ICON_NAME", False);
        XSetWMProtocols(xw.dpy, xw.win, &xw.wmdeletewin, 1);
 
        xw.netwmpid = XInternAtom(xw.dpy, "_NET_WM_PID", False);
@@ -1461,12 +1493,12 @@
 
        /* Render underline and strikethrough. */
        if (base.mode & ATTR_UNDERLINE) {
-               XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent + 1,
+               XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent * chscale 
+ 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);
        }
 
@@ -1580,13 +1612,28 @@
 }
 
 void
+xseticontitle(char *p)
+{
+       XTextProperty prop;
+       DEFAULT(p, opt_title);
+
+       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);
+}
+
+void
 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);

Reply via email to