bugfix: give one more pixel to not cut status text with some fonts
[awesome.git] / util.c
blobc3db4cd5269f143b6cc546ac9dd64521a2da21fc
1 /*
2 * util.c - useful functions
4 * Copyright © 2007 Julien Danjou <julien@danjou.info>
5 * Copyright © 2006 Pierre Habouzit <madcoder@debian.org>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include <stdarg.h>
24 #include <stdio.h>
25 #include <sys/wait.h>
26 #include <unistd.h>
27 #include <limits.h>
29 #include <X11/Xutil.h>
30 #include <X11/Xatom.h>
31 #include <X11/extensions/Xinerama.h>
33 #include "util.h"
35 void
36 die(const char *fmt, ...)
38 va_list ap;
40 va_start(ap, fmt);
41 vfprintf(stderr, fmt, ap);
42 va_end(ap);
43 abort();
46 void
47 eprint(const char *fmt, ...)
49 va_list ap;
51 va_start(ap, fmt);
52 vfprintf(stderr, fmt, ap);
53 va_end(ap);
54 exit(EXIT_FAILURE);
57 void
58 uicb_exec(Display * disp,
59 DC *drawcontext __attribute__ ((unused)),
60 awesome_config * awesomeconf __attribute__ ((unused)),
61 const char *arg)
63 char path[PATH_MAX];
64 if(disp)
65 close(ConnectionNumber(disp));
67 sscanf(arg, "%s", path);
68 execlp(path, arg, NULL);
71 void
72 uicb_spawn(Display * disp,
73 DC *drawcontext __attribute__ ((unused)),
74 awesome_config * awesomeconf __attribute__ ((unused)),
75 const char *arg)
77 static char *shell = NULL;
78 char *display = NULL;
79 char *tmp, newdisplay[128];
81 if(!shell && !(shell = getenv("SHELL")))
82 shell = a_strdup("/bin/sh");
83 if(!arg)
84 return;
86 if(!XineramaIsActive(disp) && (tmp = getenv("DISPLAY")))
88 display = a_strdup(tmp);
89 if((tmp = strrchr(display, '.')))
90 *tmp = '\0';
91 snprintf(newdisplay, sizeof(newdisplay), "%s.%d", display, awesomeconf->screen);
92 setenv("DISPLAY", newdisplay, 1);
96 /* The double-fork construct avoids zombie processes and keeps the code
97 * clean from stupid signal handlers. */
98 if(fork() == 0)
100 if(fork() == 0)
102 if(disp)
103 close(ConnectionNumber(disp));
104 setsid();
105 execl(shell, shell, "-c", arg, (char *) NULL);
106 fprintf(stderr, "awesome: execl '%s -c %s'", shell, arg);
107 perror(" failed");
109 exit(EXIT_SUCCESS);
111 wait(0);
114 Bool
115 xgettextprop(Display *disp, Window w, Atom atom, char *text, ssize_t textlen)
117 char **list = NULL;
118 int n;
120 XTextProperty name;
122 if(!text || !textlen)
123 return False;
125 text[0] = '\0';
126 XGetTextProperty(disp, w, &name, atom);
128 if(!name.nitems)
129 return False;
131 if(name.encoding == XA_STRING)
132 a_strncpy(text, textlen, (char *) name.value, textlen - 1);
134 else if(XmbTextPropertyToTextList(disp, &name, &list, &n) >= Success && n > 0 && *list)
136 a_strncpy(text, textlen, *list, textlen - 1);
137 XFreeStringList(list);
140 text[textlen - 1] = '\0';
141 XFree(name.value);
143 return True;
146 double
147 compute_new_value_from_arg(const char *arg, double current_value)
149 double delta;
151 if(arg && sscanf(arg, "%lf", &delta) == 1)
153 if(arg[0] == '+' || arg[0] == '-')
154 current_value += delta;
155 else
156 current_value = delta;
159 return current_value;
162 /** \brief safe limited strcpy.
164 * Copies at most min(<tt>n-1</tt>, \c l) characters from \c src into \c dst,
165 * always adding a final \c \\0 in \c dst.
167 * \param[in] dst destination buffer.
168 * \param[in] n size of the buffer. Negative sizes are allowed.
169 * \param[in] src source string.
170 * \param[in] l maximum number of chars to copy.
172 * \return minimum of \c src \e length and \c l.
174 ssize_t a_strncpy(char *dst, ssize_t n, const char *src, ssize_t l)
176 ssize_t len = MIN(a_strlen(src), l);
178 if (n > 0)
180 ssize_t dlen = MIN(n - 1, len);
181 memcpy(dst, src, dlen);
182 dst[dlen] = '\0';
185 return len;
188 /** \brief safe strcpy.
190 * Copies at most <tt>n-1</tt> characters from \c src into \c dst, always
191 * adding a final \c \\0 in \c dst.
193 * \param[in] dst destination buffer.
194 * \param[in] n size of the buffer. Negative sizes are allowed.
195 * \param[in] src source string.
196 * \return \c src \e length. If this value is \>= \c n then the copy was
197 * truncated.
199 ssize_t a_strcpy(char *dst, ssize_t n, const char *src)
201 ssize_t len = a_strlen(src);
203 if (n > 0)
205 ssize_t dlen = MIN(n - 1, len);
206 memcpy(dst, src, dlen);
207 dst[dlen] = '\0';
210 return len;