mirror of
https://github.com/9fans/plan9port.git
synced 2025-01-24 11:41:58 +00:00
fix double free bug, simplify error handling, reduce X11 calls, improve style
This commit is contained in:
parent
52be2761ae
commit
3e764832bc
1 changed files with 74 additions and 100 deletions
|
@ -24,6 +24,7 @@ struct Win {
|
||||||
|
|
||||||
XDisplay *dpy;
|
XDisplay *dpy;
|
||||||
XWindow root;
|
XWindow root;
|
||||||
|
|
||||||
Atom net_active_window;
|
Atom net_active_window;
|
||||||
Reprog *exclude = nil;
|
Reprog *exclude = nil;
|
||||||
Win *win;
|
Win *win;
|
||||||
|
@ -36,14 +37,13 @@ int showwmnames;
|
||||||
Font *font;
|
Font *font;
|
||||||
Image *lightblue;
|
Image *lightblue;
|
||||||
|
|
||||||
XErrorHandler oldxerrorhandler;
|
|
||||||
|
|
||||||
enum {
|
enum
|
||||||
|
{
|
||||||
PAD = 3,
|
PAD = 3,
|
||||||
MARGIN = 5
|
MARGIN = 5
|
||||||
};
|
};
|
||||||
|
|
||||||
static jmp_buf savebuf;
|
|
||||||
|
|
||||||
int
|
int
|
||||||
winwatchxerrorhandler(XDisplay *disp, XErrorEvent *xe)
|
winwatchxerrorhandler(XDisplay *disp, XErrorEvent *xe)
|
||||||
|
@ -53,11 +53,7 @@ winwatchxerrorhandler(XDisplay *disp, XErrorEvent *xe)
|
||||||
XGetErrorText(disp, xe->error_code, buf, 100);
|
XGetErrorText(disp, xe->error_code, buf, 100);
|
||||||
fprint(2, "winwatch: X error %s, request code %d\n",
|
fprint(2, "winwatch: X error %s, request code %d\n",
|
||||||
buf, xe->request_code);
|
buf, xe->request_code);
|
||||||
XFlush(disp);
|
return 0;
|
||||||
XSync(disp, False);
|
|
||||||
XSetErrorHandler(oldxerrorhandler);
|
|
||||||
longjmp(savebuf, 1);
|
|
||||||
return(0); /* Not reached */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void*
|
void*
|
||||||
|
@ -75,7 +71,7 @@ estrdup(char *s)
|
||||||
s = strdup(s);
|
s = strdup(s);
|
||||||
if(s == nil)
|
if(s == nil)
|
||||||
sysfatal("out of memory allocating");
|
sysfatal("out of memory allocating");
|
||||||
return(s);
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
char*
|
char*
|
||||||
|
@ -89,18 +85,15 @@ getproperty(XWindow w, Atom a)
|
||||||
|
|
||||||
n = 100;
|
n = 100;
|
||||||
p = nil;
|
p = nil;
|
||||||
oldxerrorhandler = XSetErrorHandler(winwatchxerrorhandler);
|
|
||||||
s = XGetWindowProperty(dpy, w, a, 0, 100L, 0,
|
s = XGetWindowProperty(dpy, w, a, 0, 100L, 0,
|
||||||
AnyPropertyType, &type, &fmt, &n, &dummy, &p);
|
AnyPropertyType, &type, &fmt, &n, &dummy, &p);
|
||||||
XFlush(dpy);
|
|
||||||
XSync(dpy, False);
|
|
||||||
XSetErrorHandler(oldxerrorhandler);
|
|
||||||
if(s != 0){
|
if(s != 0){
|
||||||
XFree(p);
|
XFree(p);
|
||||||
return(nil);
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
return((char*)p);
|
return (char*)p;
|
||||||
}
|
}
|
||||||
|
|
||||||
XWindow
|
XWindow
|
||||||
|
@ -108,7 +101,7 @@ findname(XWindow w)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
uint nxwin;
|
uint nxwin;
|
||||||
XWindow dw1, dw2, *xwin;
|
XWindow dw1, dw2, *xwin, rwin;
|
||||||
char *p;
|
char *p;
|
||||||
int s;
|
int s;
|
||||||
Atom net_wm_name;
|
Atom net_wm_name;
|
||||||
|
@ -116,37 +109,32 @@ findname(XWindow w)
|
||||||
p = getproperty(w, XA_WM_NAME);
|
p = getproperty(w, XA_WM_NAME);
|
||||||
if(p){
|
if(p){
|
||||||
free(p);
|
free(p);
|
||||||
return(w);
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
net_wm_name = XInternAtom(dpy, "_NET_WM_NAME", FALSE);
|
net_wm_name = XInternAtom(dpy, "_NET_WM_NAME", FALSE);
|
||||||
p = getproperty(w, net_wm_name);
|
p = getproperty(w, net_wm_name);
|
||||||
if(p){
|
if(p){
|
||||||
free(p);
|
free(p);
|
||||||
return(w);
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
oldxerrorhandler = XSetErrorHandler(winwatchxerrorhandler);
|
rwin = 0;
|
||||||
|
|
||||||
s = XQueryTree(dpy, w, &dw1, &dw2, &xwin, &nxwin);
|
s = XQueryTree(dpy, w, &dw1, &dw2, &xwin, &nxwin);
|
||||||
XFlush(dpy);
|
|
||||||
XSync(dpy, False);
|
|
||||||
XSetErrorHandler(oldxerrorhandler);
|
|
||||||
if(s == 0) {
|
|
||||||
if (xwin != NULL)
|
|
||||||
XFree(xwin);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if(s != 0){
|
||||||
for (i = 0; i < nxwin; i++){
|
for (i = 0; i < nxwin; i++){
|
||||||
w = findname(xwin[i]);
|
w = findname(xwin[i]);
|
||||||
if(w != 0){
|
if(w != 0){
|
||||||
XFree(xwin);
|
rwin = w;
|
||||||
return w;
|
break ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
XFree(xwin);
|
XFree(xwin);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return rwin;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -156,7 +144,6 @@ wcmp(const void *w1, const void *w2)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* unicode-aware case-insensitive strcmp, taken from golang’s gc/subr.c */
|
/* unicode-aware case-insensitive strcmp, taken from golang’s gc/subr.c */
|
||||||
|
|
||||||
int
|
int
|
||||||
_cistrcmp(char *p, char *q)
|
_cistrcmp(char *p, char *q)
|
||||||
{
|
{
|
||||||
|
@ -200,17 +187,14 @@ refreshwin(void)
|
||||||
Status s;
|
Status s;
|
||||||
Atom net_wm_name;
|
Atom net_wm_name;
|
||||||
|
|
||||||
|
|
||||||
oldxerrorhandler = XSetErrorHandler(winwatchxerrorhandler);
|
|
||||||
s = XQueryTree(dpy, root, &dw1, &dw2, &xwin, &nxwin);
|
s = XQueryTree(dpy, root, &dw1, &dw2, &xwin, &nxwin);
|
||||||
XFlush(dpy);
|
|
||||||
XSync(dpy, False);
|
|
||||||
XSetErrorHandler(oldxerrorhandler);
|
|
||||||
if(s == 0){
|
if(s == 0){
|
||||||
if(xwin != NULL)
|
if(xwin != NULL)
|
||||||
XFree(xwin);
|
XFree(xwin);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
qsort(xwin, nxwin, sizeof(xwin[0]), wcmp);
|
qsort(xwin, nxwin, sizeof(xwin[0]), wcmp);
|
||||||
|
|
||||||
nw = 0;
|
nw = 0;
|
||||||
|
@ -220,11 +204,8 @@ refreshwin(void)
|
||||||
if(xwin[i] == 0)
|
if(xwin[i] == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
oldxerrorhandler = XSetErrorHandler(winwatchxerrorhandler);
|
|
||||||
s = XGetWindowAttributes(dpy, xwin[i], &attr);
|
s = XGetWindowAttributes(dpy, xwin[i], &attr);
|
||||||
XFlush(dpy);
|
|
||||||
XSync(dpy, False);
|
|
||||||
XSetErrorHandler(oldxerrorhandler);
|
|
||||||
if(s == 0)
|
if(s == 0)
|
||||||
continue;
|
continue;
|
||||||
if(attr.width <= 0 ||
|
if(attr.width <= 0 ||
|
||||||
|
@ -232,11 +213,7 @@ refreshwin(void)
|
||||||
attr.map_state != IsViewable)
|
attr.map_state != IsViewable)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
oldxerrorhandler = XSetErrorHandler(winwatchxerrorhandler);
|
|
||||||
s = XGetClassHint(dpy, xwin[i], &class);
|
s = XGetClassHint(dpy, xwin[i], &class);
|
||||||
XFlush(dpy);
|
|
||||||
XSync(dpy, False);
|
|
||||||
XSetErrorHandler(oldxerrorhandler);
|
|
||||||
|
|
||||||
if(s == 0)
|
if(s == 0)
|
||||||
continue;
|
continue;
|
||||||
|
@ -280,6 +257,7 @@ refreshwin(void)
|
||||||
mwin += 8;
|
mwin += 8;
|
||||||
win = erealloc(win, mwin * sizeof(win[0]));
|
win = erealloc(win, mwin * sizeof(win[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
win[nw].n = xwin[i];
|
win[nw].n = xwin[i];
|
||||||
win[nw].label = estrdup(label);
|
win[nw].label = estrdup(label);
|
||||||
win[nw].dirty = 1;
|
win[nw].dirty = 1;
|
||||||
|
@ -290,11 +268,7 @@ refreshwin(void)
|
||||||
nw++;
|
nw++;
|
||||||
}
|
}
|
||||||
|
|
||||||
oldxerrorhandler = XSetErrorHandler(winwatchxerrorhandler);
|
|
||||||
XFree(xwin);
|
XFree(xwin);
|
||||||
XFlush(dpy);
|
|
||||||
XSync(dpy, False);
|
|
||||||
XSetErrorHandler(oldxerrorhandler);
|
|
||||||
|
|
||||||
while(nwin > nw)
|
while(nwin > nw)
|
||||||
free(win[--nwin].label);
|
free(win[--nwin].label);
|
||||||
|
@ -481,9 +455,6 @@ main(int argc, char **argv)
|
||||||
if(argc)
|
if(argc)
|
||||||
usage();
|
usage();
|
||||||
|
|
||||||
/* moved up from original winwatch.c for p9p because there can be only one but we want to restart when needed */
|
|
||||||
einit(Emouse | Ekeyboard);
|
|
||||||
Etimer = etimer(0, 1000);
|
|
||||||
|
|
||||||
dpy = XOpenDisplay("");
|
dpy = XOpenDisplay("");
|
||||||
if(dpy == nil)
|
if(dpy == nil)
|
||||||
|
@ -500,11 +471,14 @@ main(int argc, char **argv)
|
||||||
if(font == nil)
|
if(font == nil)
|
||||||
sysfatal("font '%s' not found", fontname);
|
sysfatal("font '%s' not found", fontname);
|
||||||
|
|
||||||
/* reentry point upon X server errors */
|
einit(Emouse | Ekeyboard);
|
||||||
setjmp(savebuf);
|
Etimer = etimer(0, 1000);
|
||||||
|
|
||||||
|
XSetErrorHandler(winwatchxerrorhandler);
|
||||||
|
|
||||||
refreshwin();
|
refreshwin();
|
||||||
redraw(screen, 1);
|
redraw(screen, 1);
|
||||||
|
|
||||||
for(;;){
|
for(;;){
|
||||||
switch(eread(Emouse|Ekeyboard|Etimer, &e)){
|
switch(eread(Emouse|Ekeyboard|Etimer, &e)){
|
||||||
case Ekeyboard:
|
case Ekeyboard:
|
||||||
|
|
Loading…
Reference in a new issue