Account for window groups. Better focus semantics. Check size against iounit on dir reads. Misc. changes.

This commit is contained in:
Kris Maglione 2008-01-16 01:01:04 -05:00
parent aef6e4c22e
commit ba8e24be1e
16 changed files with 363 additions and 157 deletions

View File

@ -174,6 +174,17 @@ area_moveto(Area *to, Frame *f) {
area_attach(to, f);
}
void
area_setsel(Area *a, Frame *f) {
View *v;
v = a->view;
if(a == v->sel && f)
frame_focus(f);
else
a->sel = f;
}
void
area_attach(Area *a, Frame *f) {
uint n_frame;
@ -202,12 +213,8 @@ area_attach(Area *a, Frame *f) {
client_resize(f->client, f->r);
}
if(!a->sel) {
if(a == a->view->sel)
frame_focus(f);
else
a->sel = f;
}
if(!a->sel)
area_setsel(a, f);
view_restack(a->view);
if(!a->floating)
@ -220,7 +227,7 @@ area_attach(Area *a, Frame *f) {
void
area_detach(Frame *f) {
Frame *pr;
Client *c, *cp;
Client *c;
Area *a;
View *v;
@ -234,10 +241,8 @@ area_detach(Frame *f) {
if(a->sel == f) {
if(!pr)
pr = a->frame;
if(pr && (v->sel == a))
frame_focus(pr);
else
a->sel = pr;
if(pr)
area_setsel(a, pr);
}
if(!a->floating) {
@ -248,20 +253,14 @@ area_detach(Frame *f) {
area_destroy(a);
else if((a->frame == nil) && (v->area->frame))
area_focus(v->area);
view_arrange(v);
}
}else if(!a->frame) {
if(c->trans) {
cp = win2client(c->trans);
if(cp && cp->frame) {
a = cp->sel->area;
if(a->view == v) {
area_focus(a);
return;
}
if(c->trans || (c->w.ewmh.type & (TypeDialog|TypeSplash)))
if(v->oldsel) {
area_focus(v->oldsel);
return;
}
}
if(v->area->next->frame)
area_focus(v->area->next);
}else

View File

@ -3,6 +3,7 @@
* See LICENSE file for license details.
*/
#include "dat.h"
#include <assert.h>
#include <ctype.h>
#include <X11/Xatom.h>
#include "fns.h"
@ -22,10 +23,74 @@ enum {
| ButtonReleaseMask
};
static Group* group;
static void
group_init(Client *c) {
Group *g;
long *ret;
XWindow w;
long n;
n = getprop_long(&c->w, "WM_CLIENT_LEADER", "WINDOW", 0L, &ret, 1L);
if(n == 0)
return;
w = *ret;
for(g=group; g; g=g->next)
if(g->leader == w)
break;
if(g == nil) {
g = emallocz(sizeof *g);
g->leader = w;
g->next = group;
group = g;
}
c->group = g;
g->ref++;
}
static void
group_remove(Client *c) {
Group **gp;
Group *g;
g = c->group;
if(g == nil)
return;
if(g->client == c)
g->client = nil;
g->ref--;
if(g->ref == 0) {
for(gp=&group; *gp; gp=&gp[0]->next)
if(*gp == g)
break;
assert(*gp == g);
gp[0] = gp[0]->next;
}
}
static Client*
group_leader(Group *g) {
Client *c;
c = win2client(g->leader);
if(c)
return c;
if(g->client)
return g->client;
/* Could do better. */
for(c=client; c; c=c->next)
if(c->frame && c->group == g)
break;
return c;
}
Client*
client_create(XWindow w, XWindowAttributes *wa) {
Client **t, *c;
WinAttr fwa;
Point p;
c = emallocz(sizeof(Client));
c->border = wa->border_width;
@ -68,7 +133,12 @@ client_create(XWindow w, XWindowAttributes *wa) {
sethandler(c->framewin, &framehandler);
sethandler(&c->w, &handlers);
p.x = def.border;
p.y = labelh(def.font);
reparentwindow(&c->w, c->framewin, p);
ewmh_initclient(c);
group_init(c);
grab_button(c->framewin->w, AnyButton, AnyModifier);
@ -86,7 +156,6 @@ client_create(XWindow w, XWindowAttributes *wa) {
void
client_manage(Client *c) {
Point p;
Client *trans;
char *tags;
@ -94,18 +163,16 @@ client_manage(Client *c) {
if(tags == nil)
tags = gettextproperty(&c->w, "_WIN_TAGS");
if((trans = win2client(c->trans)))
utflcpy(c->tags, trans->tags, sizeof(c->tags));
else if(tags)
trans = win2client(c->trans);
if(trans == nil && c->group)
trans = group_leader(c->group);
if(tags)
utflcpy(c->tags, tags, sizeof(c->tags));
else if(trans)
utflcpy(c->tags, trans->tags, sizeof(c->tags));
free(tags);
p.x = def.border;
p.y = labelh(def.font);
reparentwindow(&c->w, c->framewin, p);
if(c->tags[0])
apply_tags(c, c->tags);
else
@ -116,8 +183,14 @@ client_manage(Client *c) {
if(c->sel->view == screen->sel)
if(!(c->w.ewmh.type & TypeSplash))
if(!c->group || c->group->ref == 1
|| selclient() && selclient()->group == c->group)
focus(c, false);
flushevents(EnterWindowMask, False);
else {
frame_restack(c->sel, c->sel->area->sel);
view_restack(c->sel->view);
}
flushenterevents();
}
static int /* Temporary Xlib error handler */
@ -156,7 +229,7 @@ client_destroy(Client *c) {
handler = XSetErrorHandler(ignoreerrors);
dummy = nil;
view_setclient(c, &dummy);
client_setviews(c, &dummy);
client_unmap(c, IconicState);
sethandler(&c->w, nil);
@ -171,9 +244,10 @@ client_destroy(Client *c) {
XUngrabServer(display);
ewmh_destroyclient(c);
group_remove(c);
event("DestroyClient %C\n", c);
flushevents(EnterWindowMask, False);
flushenterevents();
free(c->w.hints);
free(c);
}
@ -339,17 +413,19 @@ client_focus(Client *c) {
Dprint(DFocus, "client_focus(%p[%C]) => %s\n", c, c, clientname(c));
if(c && c->noinput)
return;
if(c) {
if(c->noinput)
return;
if(c->group)
c->group->client = c;
}
if(screen->focus != c) {
Dprint(DFocus, "\t%s => %s\n", clientname(screen->focus), clientname(c));
if(c)
setfocus(&c->w, RevertToParent);
else
setfocus(screen->barwin, RevertToParent);
event("ClientFocus %C\n", c);
sync();
@ -565,11 +641,10 @@ updatemwm(Client *c) {
};
Rectangle r;
ulong *ret;
Atom real;
int n;
n = getproperty(&c->w, "_MOTIF_WM_HINTS", "_MOTIF_WM_HINTS", &real,
0L, (void*)&ret, 3L);
n = getprop_long(&c->w, "_MOTIF_WM_HINTS", "_MOTIF_WM_HINTS",
0L, (long**)&ret, 3L);
if(c->sel)
r = frame_rect2client(c->sel, c->sel->r);
@ -671,8 +746,11 @@ configreq_event(Window *w, XConfigureRequestEvent *e) {
if((Dx(cr) == Dx(screen->r)) && (Dy(cr) == Dy(screen->r)))
fullscreen(c, True);
if(c->sel->area->floating)
if(c->sel->area->floating) {
client_resize(c, r);
sync();
flushenterevents();
}
else {
c->sel->revert = r;
client_configure(c);
@ -807,12 +885,12 @@ newcol_client(Client *c, char *arg) {
}
else
return;
flushevents(EnterWindowMask, False);
flushenterevents();
}
#endif
void
view_setclient(Client *c, char **tags) {
client_setviews(Client *c, char **tags) {
Frame **fp, *f;
int cmp;
@ -953,7 +1031,7 @@ apply_tags(Client *c, const char *tags) {
}
toks[n] = nil;
view_setclient(c, toks);
client_setviews(c, toks);
changeprop_string(&c->w, "_WMII_TAGS", c->tags);
}

View File

@ -268,7 +268,7 @@ scale_column(Area *a) {
j--;
}
/* Doesn't change if we 'continue' */
fp=&f->anext;
fp = &f->anext;
}
surplus = 0;

View File

@ -72,35 +72,16 @@ typedef struct Bar Bar;
typedef struct Client Client;
typedef struct Divide Divide;
typedef struct Frame Frame;
typedef struct Group Group;
typedef struct Key Key;
typedef struct Map Map;
typedef struct MapEnt MapEnt;
typedef struct Rule Rule;
typedef struct Ruleset Ruleset;
typedef struct Strut Strut;
typedef struct View View;
typedef struct WMScreen WMScreen;
struct Map {
MapEnt**bucket;
uint nhash;
};
struct MapEnt {
ulong hash;
const char* key;
void* val;
MapEnt* next;
};
struct View {
View* next;
char name[256];
ushort id;
Area* area;
Area* sel;
Area* revert;
};
struct Area {
Area* next;
Area* prev;
@ -114,23 +95,15 @@ struct Area {
Rectangle r;
};
struct Frame {
Frame* cnext;
Frame* anext;
Frame* aprev;
Frame* snext;
Frame* sprev;
View* view;
Area* area;
Client* client;
struct Bar {
Bar* next;
Bar* smaller;
char buf[280];
char text[256];
char name[256];
ushort id;
bool collapsed;
float ratio;
Rectangle r;
Rectangle crect;
Rectangle revert;
Rectangle grabbox;
Rectangle titlebar;
Rectangle r;
CTuple col;
};
struct Client {
@ -141,6 +114,8 @@ struct Client {
Window w;
Window* framewin;
XWindow trans;
Group* group;
Strut* strut;
Cursor cursor;
Rectangle r;
char name[256];
@ -165,6 +140,32 @@ struct Divide {
int x;
};
struct Frame {
Frame* cnext;
Frame* anext;
Frame* aprev;
Frame* snext;
Frame* sprev;
View* view;
Area* area;
Client* client;
ushort id;
bool collapsed;
float ratio;
Rectangle r;
Rectangle crect;
Rectangle revert;
Rectangle grabbox;
Rectangle titlebar;
};
struct Group {
Group* next;
XWindow leader;
Client *client;
int ref;
};
struct Key {
Key* next;
Key* lnext;
@ -175,15 +176,16 @@ struct Key {
KeyCode key;
};
struct Bar {
Bar* next;
Bar* smaller;
char buf[280];
char text[256];
char name[256];
ushort id;
Rectangle r;
CTuple col;
struct Map {
MapEnt**bucket;
uint nhash;
};
struct MapEnt {
ulong hash;
const char* key;
void* val;
MapEnt* next;
};
struct Rule {
@ -193,11 +195,28 @@ struct Rule {
};
struct Ruleset {
Rule *rule;
char *string;
Rule* rule;
char* string;
uint size;
};
struct Strut {
Rectangle left;
Rectangle right;
Rectangle top;
Rectangle bottom;
};
struct View {
View* next;
char name[256];
ushort id;
Area* area;
Area* sel;
Area* oldsel;
Area* revert;
};
#ifndef EXTERN
# define EXTERN extern
#endif

View File

@ -14,7 +14,8 @@ dispatch_event(XEvent *e) {
handler[e->type](e);
}
#define handle(w, fn, ev) if(!(w)->handler->fn) {}else (w)->handler->fn((w), ev)
#define handle(w, fn, ev) \
BLOCK(if((w)->handler->fn) (w)->handler->fn((w), ev))
uint
flushevents(long event_mask, bool dispatch) {
@ -29,6 +30,37 @@ flushevents(long event_mask, bool dispatch) {
return n;
}
static Bool
findenter(Display *d, XEvent *e, XPointer v) {
long *l;
l = (long*)v;
if(*l)
return False;
if(e->type == EnterNotify)
return True;
if(e->type == MotionNotify)
(*l)++;
return False;
}
/* This isn't perfect. If there were motion events in the queue
* before this was called, then it flushes nothing. If we don't
* check for them, we might lose a legitamate enter event.
*/
uint
flushenterevents(void) {
XEvent e;
long l;
int n;
l = 0;
n = 0;
while(XCheckIfEvent(display, &e, findenter, (void*)&l))
n++;
return n;
}
static void
buttonrelease(XEvent *e) {
XButtonPressedEvent *ev;
@ -236,11 +268,10 @@ maprequest(XEvent *e) {
XWindowAttributes wa;
ev = &e->xmaprequest;
if(!XGetWindowAttributes(display, ev->window, &wa))
return;
if(wa.override_redirect) {
/* Do I really want these? */
XSelectInput(display, ev->window,
(StructureNotifyMask | PropertyChangeMask));
return;

View File

@ -1,8 +1,9 @@
/* Copyright ©2007 Kris Maglione <fbsdaemon@gmail.com>
* See LICENSE file for license details.
*/
#include <assert.h>
#include "dat.h"
#include <assert.h>
#include <sys/limits.h>
#include "fns.h"
Window *ewmhwin;
@ -190,20 +191,40 @@ ewmh_getstrut(Client *c) {
enum {
Left, Right, Top, Bottom,
LeftMin, LeftMax,
RithtMin, RightMax,
RightMin, RightMax,
TopMin, TopMax,
BottomMin, BottomMax
BottomMin, BottomMax,
Last = BottomMax
};
Atom actual;
long strut[12];
long *strut;
ulong n;
n = getproperty(&c->w, Net("WM_STRUT_PARTIAL"), "CARDINAL", &actual,
0L, (void*)&strut, nelem(strut));
if(n != nelem(strut))
return;
if(actual != xatom("ATOM"))
return;
if(c->strut)
free(c->strut);
c->strut = nil;
n = getprop_long(&c->w, Net("WM_STRUT_PARTIAL"), "CARDINAL",
0L, &strut, Last);
if(n != nelem(strut)) {
free(strut);
n = getprop_long(&c->w, Net("WM_STRUT"), "CARDINAL",
0L, &strut, 4L);
if(n != 4) {
free(strut);
return;
}
strut = erealloc(strut, Last * sizeof *strut);
strut[LeftMin] = strut[RightMin] = 0;
strut[LeftMax] = strut[RightMax] = INT_MAX;
strut[TopMin] = strut[BottomMin] = 0;
strut[TopMax] = strut[BottomMax] = INT_MAX;
}
c->strut = emalloc(sizeof *c->strut);
c->strut->left = Rect(0, strut[LeftMin], strut[Left], strut[LeftMax]);
c->strut->right = Rect(-strut[Right], strut[RightMin], 0, strut[RightMax]);
c->strut->top = Rect(strut[TopMin], 0, strut[TopMax], strut[Top]);
c->strut->bottom = Rect(strut[BottomMin], -strut[Bottom], strut[BottomMax], 0);
free(strut);
}
int
@ -251,23 +272,24 @@ ewmh_clientmessage(XClientMessageEvent *e) {
if(msg == NET("ACTIVE_WINDOW")) {
if(e->format != 32)
return -1;
if(l[0] != 2)
return 1;
c == win2client(e->window);
Dprint(DEwmh, "\tsource: %ld\n", l[0]);
Dprint(DEwmh, "\twindow: 0x%lx\n", e->window);
c = win2client(e->window);
if(c == nil)
return 1;
Dprint(DEwmh, "\tclient: %s\n", clientname(c));
if(l[0] != 2)
return 1;
focus(c, true);
return 1;
}else
if(msg == NET("CURRENT_DESKTOP")) {
print("\t%ld\n", l[0]);
if(e->format != 32)
return -1;
print("\t%ld\n", l[0]);
for(v=view, i=l[0]; v; v=v->next, i--)
if(i == 0)
break;
print("\t%d\n", i);
Dprint(DEwmh, "\t%s\n", v->name);
if(i == 0)
view_select(v->name);
return 1;

View File

@ -57,6 +57,7 @@ uint area_idx(Area*);
void area_moveto(Area*, Frame*);
char* area_name(Area*);
Client* area_selclient(Area*);
void area_setsel(Area*, Frame*);
/* bar.c */
Bar* bar_create(Bar**, const char*);
@ -108,6 +109,7 @@ void div_update_all(void);
/* event.c */
void check_x_event(IxpConn*);
void dispatch_event(XEvent*);
uint flushenterevents(void);
uint flushevents(long, bool dispatch);
void print_focus(Client*, const char*);
@ -138,9 +140,9 @@ uint frame_idx(Frame*);
void frame_insert(Frame *pos, Frame*);
void frame_remove(Frame*);
void frame_resize(Frame*, Rectangle);
bool frame_restack(Frame*, Frame*);
void frame_setcursor(Frame*, Point);
void frame_swap(Frame*, Frame*);
bool frame_to_top(Frame*);
int ingrabbox_p(Frame*, int x, int y);
void move_focus(Frame*, Frame*);
Rectangle constrain(Rectangle);
@ -217,7 +219,7 @@ void view_restack(View*);
void view_scale(View*, int w);
Client* view_selclient(View*);
void view_select(const char*);
void view_setclient(Client*, char**);
void client_setviews(Client*, char**);
void view_update_all(void);
Rectangle* view_rects(View*, uint *num, Frame *ignore);

View File

@ -90,25 +90,34 @@ frame_insert(Frame *pos, Frame *f) {
}
bool
frame_to_top(Frame *f) {
frame_restack(Frame *f, Frame *above) {
Area *a;
a = f->area;
if(!a->floating || f == a->stack)
return False;
if(!a->floating)
return false;
if(above && above->area != a)
return false;
if(f->sprev)
f->sprev->snext = f->snext;
else
a->stack = f->snext;
if(f->snext)
f->snext->sprev = f->sprev;
f->snext = a->stack;
a->stack = f;
f->sprev = nil;
f->sprev = above;
if(above == nil)
a->stack = f;
else
f->snext = above->snext;
if(f->snext)
f->snext->sprev = f;
if(f->sprev)
f->sprev->snext = f;
return True;
return true;
}
/* Handlers */
@ -130,12 +139,12 @@ bdown_event(Window *w, XButtonEvent *e) {
case Button1:
mouse_resize(c, False, CENTER);
focus(c, false);
frame_to_top(f);
frame_restack(f, nil);
focus(c, false); /* Blech */
break;
case Button3:
mouse_resize(c, False, quadrant(f->r, Pt(e->x_root, e->y_root)));
frame_to_top(f);
frame_restack(f, nil);
focus(c, false);
break;
default:
@ -146,7 +155,7 @@ bdown_event(Window *w, XButtonEvent *e) {
XUngrabPointer(display, e->time);
}else{
if(e->button == Button1) {
if(frame_to_top(f))
if(frame_restack(f, nil))
view_restack(f->view);
else if(rect_haspoint_p(Pt(e->x, e->y), f->grabbox))
mouse_resize(c, True, CENTER);
@ -381,25 +390,29 @@ move_focus(Frame *old_f, Frame *f) {
void
frame_focus(Frame *f) {
Client *c;
Frame *old_f;
View *v;
Area *a, *old_a;
Frame *old_f;
a = f->area;
c = f->client;
v = f->view;
a = f->area;
old_a = v->sel;
old_f = old_a->sel;
a->sel = f;
if(a != old_a)
if(a != old_a) {
if(c->trans || (c->w.ewmh.type & (TypeDialog|TypeSplash)))
v->oldsel = v->sel;
area_focus(f->area);
}
if(v != screen->sel || a != v->sel)
return;
move_focus(old_f, f);
client_focus(f->client);
if(!a->floating && ((a->mode == Colstack) || (a->mode == Colmax)))

View File

@ -247,7 +247,7 @@ message(Ixp9Req *r, MsgFunc fn) {
c = *p;
*p = '\0';
m = ixp_message((uchar*)s, p-s, 0);
m = ixp_message(s, p-s, 0);
s = fn(f->p.ref, &m);
if(s)
err = s;
@ -563,7 +563,7 @@ fs_stat(Ixp9Req *r) {
IxpMsg m;
Stat s;
int size;
uchar *buf;
char *buf;
FileId *f;
f = r->fid->aux;
@ -589,7 +589,7 @@ fs_read(Ixp9Req *r) {
char *buf;
FileId *f, *tf;
int n, offset;
int size;
ulong size;
f = r->fid->aux;
@ -604,8 +604,10 @@ fs_read(Ixp9Req *r) {
offset = 0;
size = r->ifcall.count;
if(size > IXP_MAX_MSG)
size = r->fid->iounit;
buf = emallocz(size);
m = ixp_message((uchar*)buf, size, MsgPack);
m = ixp_message(buf, size, MsgPack);
tf = f = lookup_file(f, nil);
/* Note: f->tab.name == "." so we skip it */
@ -892,7 +894,7 @@ fs_clunk(Ixp9Req *r) {
case FsFBar:
p = toutf8(f->p.bar->buf);
m = ixp_message((uchar*)p, strlen(p), 0);
m = ixp_message(p, strlen(p), 0);
msg_parsecolors(&m, &f->p.bar->col);
q = (char*)m.end-1;

View File

@ -374,15 +374,18 @@ main(int argc, char *argv[]) {
wmiirc = "wmiistartrc";
ARGBEGIN{
case 'v':
print("%s", version);
exit(0);
case 'a':
address = EARGF(usage());
break;
case 'G':
debug |= DGeneric;
break;
case 'r':
wmiirc = EARGF(usage());
break;
case 'v':
print("%s", version);
exit(0);
default:
usage();
break;

View File

@ -598,7 +598,7 @@ msg_selectframe(Frame *f, IxpMsg *m, int sym) {
return "invalid selection";
frame_focus(fp);
frame_to_top(fp);
frame_restack(fp, nil);
if(f->view == screen->sel)
view_restack(f->view);
return nil;
@ -677,7 +677,7 @@ msg_sendclient(View *v, IxpMsg *m, bool swap) {
else
return Ebadvalue;
flushevents(EnterWindowMask, False);
flushenterevents();
frame_focus(f);
view_arrange(v);
view_update_all();
@ -716,7 +716,7 @@ msg_sendframe(Frame *f, int sym, bool swap) {
view_arrange(f->view);
flushevents(EnterWindowMask, False);
flushenterevents();
frame_focus(f);
view_update_all();
return nil;

View File

@ -139,7 +139,7 @@ view_focus(WMScreen *s, View *v) {
sync();
XUngrabServer(display);
flushevents(EnterWindowMask, False);
flushenterevents();
}
void
@ -161,6 +161,7 @@ view_select(const char *arg) {
void
view_attach(View *v, Frame *f) {
Client *c;
Frame *ff;
Area *a;
c = f->client;
@ -169,12 +170,14 @@ view_attach(View *v, Frame *f) {
a = v->sel;
if(c->trans || c->floating || c->fixedsize
|| c->titleless || c->borderless || c->fullscreen
|| (c->w.ewmh.type & TypeDialog))
|| (c->w.ewmh.type & (TypeDialog|TypeSplash|TypeDock)))
a = v->area;
else if(c->group && c->group->client
&& (ff = client_viewframe(c->group->client, v)))
a = ff->area;
else if(starting && v->sel->floating)
a = v->area->next;
if(!(c->w.ewmh.type & TypeSplash))
area_focus(a);
area_attach(a, f);
}
@ -213,10 +216,8 @@ view_restack(View *v) {
}
ewmh_updatestacking();
if(wins.n) {
XRaiseWindow(display, wins.ary[0]);
if(wins.n)
XRestackWindows(display, (ulong*)wins.ary, wins.n);
}
}
void

View File

@ -337,10 +337,10 @@ findwin(XWindow w) {
uint
winprotocols(Window *w) {
Atom *protocols;
Atom actual, delete;
Atom delete;
int i, n, protos;
n = getproperty(w, "WM_PROTOCOLS", "ATOM", &actual, 0L, (void*)&protocols, 20L);
n = getprop_long(w, "WM_PROTOCOLS", "ATOM", 0L, (long**)&protocols, 20L);
if(n == 0)
return 0;
@ -683,17 +683,17 @@ freestringlist(char *list[]) {
XFreeStringList(list);
}
ulong
getproperty(Window *w, char *prop, char *type, Atom *actual, ulong offset, uchar **ret, ulong length) {
static ulong
getprop(Window *w, char *prop, char *type, Atom *actual, int *format, ulong offset, uchar **ret, ulong length) {
Atom typea;
ulong n, extra;
int status, format;
int status;
typea = (type ? xatom(type) : 0L);
status = XGetWindowProperty(display, w->w,
xatom(prop), offset, length, False /* delete */,
typea, actual, &format, &n, &extra, ret);
typea, actual, format, &n, &extra, ret);
if(status != Success) {
*ret = nil;
@ -706,6 +706,29 @@ getproperty(Window *w, char *prop, char *type, Atom *actual, ulong offset, uchar
return n;
}
ulong
getproperty(Window *w, char *prop, char *type, Atom *actual, ulong offset, uchar **ret, ulong length) {
int format;
return getprop(w, prop, type, actual, &format, offset, ret, length);
}
ulong
getprop_long(Window *w, char *prop, char *type, ulong offset, long **ret, ulong length) {
Atom actual;
ulong n;
int format;
n = getprop(w, prop, type, &actual, &format, offset, (uchar**)ret, length);
if(n == 0 || format == 32 && xatom(type) == actual)
return n;
Dprint(DGeneric, "getprop_long(%W, %s, %s) format=%d, actual=\"%A\"\n",
w, prop, type, format, actual);
free(*ret);
*ret = 0;
return 0;
}
char**
strlistdup(char *list[], int n) {
char **p, *q;

View File

@ -14,7 +14,7 @@ LIBS = -L/usr/lib -lc -L${ROOT}/lib
# Flags
include ${ROOT}/mk/gcc.mk
CFLAGS += -g -O0 -DIXPlint
CFLAGS += ${DEBUGCFLAGS} -DIXPlint
LDFLAGS += -g ${LIBS}
STATIC = -static
MKDEP = cpp -M
@ -35,10 +35,14 @@ LIBICONV = # Leave blank if your libc includes iconv (glibc does)
LIBIXP = ${ROOT}/libixp/libixp.a
LIBIXP = ${LIBDIR}/libixp.a
# *BSD
#LIBICONV = -liconv
# +Darwin
#STATIC = # Darwon doesn't like static linking
# Solaris
#CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\"
#LDFLAGS = ${LIBS} -R${PREFIX}/lib
#LDFLAGS += -lsocket -lnsl
#CFLAGS += -xtarget=ultra

View File

@ -183,6 +183,7 @@ Window* findwin(XWindow);
void freefont(Font*);
void freeimage(Image *);
void freestringlist(char**);
ulong getprop_long(Window*, char*, char*, ulong, long**, ulong);
ulong getproperty(Window*, char *prop, char *type, Atom *actual, ulong offset, uchar **ret, ulong length);
int gettextlistproperty(Window *w, char *name, char **ret[]);
int grabpointer(Window*, Window *confine, Cursor, int mask);

View File

@ -1,7 +1,15 @@
DEBUGCFLAGS = \
-g \
-O1 \
-fno-builtin \
-fno-inline \
-fno-omit-frame-pointer \
-fno-optimize-sibling-calls \
-fno-unroll-loops
CFLAGS += \
-std=c99 \
-pipe \
-pedantic \
-pipe \
-Wall \
-Wimplicit \
-Wmissing-prototypes \
@ -13,4 +21,4 @@ CFLAGS += \
-Wpointer-arith \
-Wreturn-type \
-Wstrict-prototypes \
-Wtrigraphs \
-Wtrigraphs