fix the ultimate bug when restarting awesome, client misdisplayed
[awesome.git] / util.c
blob520e05871f03cfdafaf95513df4ad2858e874be2
1 /*
2 * util.c - useful functions
3 *
4 * Copyright © 2007 Julien Danjou <julien@danjou.info>
5 * Copyright © 2006 Pierre Habouzit <madcoder@debian.org>
6 *
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>
28 #include <X11/Xutil.h>
29 #include <X11/Xatom.h>
31 #include "util.h"
33 void
34 die(const char *fmt, ...)
36 va_list ap;
38 va_start(ap, fmt);
39 vfprintf(stderr, fmt, ap);
40 va_end(ap);
41 abort();
44 void
45 eprint(const char *fmt, ...)
47 va_list ap;
49 va_start(ap, fmt);
50 vfprintf(stderr, fmt, ap);
51 va_end(ap);
52 exit(EXIT_FAILURE);
55 void
56 uicb_spawn(Display * disp,
57 DC *drawcontext __attribute__ ((unused)),
58 awesome_config * awesomeconf __attribute__ ((unused)),
59 const char *arg)
61 static char *shell = NULL;
62 char *display = NULL;
63 char *tmp, newdisplay[128];
65 if(!shell && !(shell = getenv("SHELL")))
66 shell = strdup("/bin/sh");
67 if(!arg)
68 return;
70 if((tmp = getenv("DISPLAY")))
72 display = strdup(tmp);
73 if((tmp = strrchr(display, '.')))
74 *tmp = '\0';
75 snprintf(newdisplay, sizeof(newdisplay), "%s.%d", display, awesomeconf->screen);
76 setenv("DISPLAY", newdisplay, 1);
80 /* The double-fork construct avoids zombie processes and keeps the code
81 * clean from stupid signal handlers. */
82 if(fork() == 0)
84 if(fork() == 0)
86 if(disp)
87 close(ConnectionNumber(disp));
88 setsid();
89 execl(shell, shell, "-c", arg, (char *) NULL);
90 fprintf(stderr, "awesome: execl '%s -c %s'", shell, arg);
91 perror(" failed");
93 exit(EXIT_SUCCESS);
95 wait(0);
98 Bool
99 xgettextprop(Display *disp, Window w, Atom atom, char *text, unsigned int size)
101 char **list = NULL;
102 int n;
104 XTextProperty name;
106 if(!text || size == 0)
107 return False;
109 text[0] = '\0';
110 XGetTextProperty(disp, w, &name, atom);
112 if(!name.nitems)
113 return False;
115 if(name.encoding == XA_STRING)
116 strncpy(text, (char *) name.value, size - 1);
118 else if(XmbTextPropertyToTextList(disp, &name, &list, &n) >= Success && n > 0 && *list)
120 strncpy(text, *list, size - 1);
121 XFreeStringList(list);
124 text[size - 1] = '\0';
125 XFree(name.value);
127 return True;
130 double
131 compute_new_value_from_arg(const char *arg, double current_value)
133 double delta;
135 if(arg && sscanf(arg, "%lf", &delta) == 1)
137 if(arg[0] == '+' || arg[0] == '-')
138 current_value += delta;
139 else
140 current_value = delta;
143 return current_value;