wmii

git clone git://oldgit.suckless.org/wmii/
Log | Files | Refs | README | LICENSE

commit 780ad5c31a454ff99b3c7452e0e99822d9b4eba5
parent d386fe224c46dbcfeb9c2b71aa533766bee7154b
Author: Kris Maglione <bsdaemon@wmii.de>
Date:   Thu, 22 Jun 2006 16:35:45 -0400

Merge for whatver reason


Diffstat:
cmd/wm/bar.c | 55+++++++++++++++++++++++++++----------------------------
cmd/wm/client.c | 96++++++++++++++++++++++++++++++++++++++++----------------------------------------
cmd/wm/event.c | 89+++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------
cmd/wm/frame.c | 102++++++++++++++++++++++++++++++++++++++-----------------------------------------
cmd/wm/fs.c | 10++++------
cmd/wm/key.c | 48++++++++++++++++++++++++------------------------
cmd/wm/mouse.c | 48++++++++++++++++++++++++------------------------
cmd/wm/view.c | 14+++++++-------
cmd/wm/wm.c | 102+++++++++++++++++++++++++++++++++++++++----------------------------------------
cmd/wm/wm.h | 21+++++++++------------
cmd/wmiimenu.c | 151+++++++++++++++++++++++++++++++++++++++----------------------------------------
liblitz/Makefile | 2+-
liblitz/blitz.c | 16----------------
liblitz/blitz.h | 50+++++++++++++++++++++++++++++++-------------------
liblitz/brush.c | 81+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
liblitz/color.c | 14+++++++-------
liblitz/draw.c | 27+++++++++++++++++++++++++++
liblitz/font.c | 20+++++++++++++-------
liblitz/input.c | 142++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
liblitz/tile.c | 44--------------------------------------------
20 files changed, 620 insertions(+), 512 deletions(-)

diff --git a/cmd/wm/bar.c b/cmd/wm/bar.c @@ -27,9 +27,9 @@ create_bar(Bar **b_link, char *name) b->id = id++; cext_strlcpy(b->name, name, sizeof(b->name)); - b->widget = blitz_create_input(barpmap, bargc, &def.font); - b->widget->color = def.normcolor; - b->widget->align = CENTER; + b->brush = bbrush; + b->brush.color = def.normcolor; + b->brush.align = CENTER; for(i=b_link; *i; i=&(*i)->next) if(strcmp((*i)->name, name) >= 0) @@ -48,9 +48,6 @@ destroy_bar(Bar **b_link, Bar *b) *p = b->next; b->next = free_bars; - if(b->widget->text) - free(b->widget->text); - blitz_destroy_input(b->widget); free_bars = b; } @@ -71,12 +68,12 @@ resize_bar() brect = rect; brect.height = height_of_bar(); brect.y = rect.height - brect.height; - XMoveResizeWindow(dpy, barwin, brect.x, brect.y, brect.width, brect.height); - XSync(dpy, False); - XFreePixmap(dpy, barpmap); - barpmap = XCreatePixmap(dpy, barwin, brect.width, brect.height, - DefaultDepth(dpy, screen)); - XSync(dpy, False); + XMoveResizeWindow(blz.display, barwin, brect.x, brect.y, brect.width, brect.height); + XSync(blz.display, False); + XFreePixmap(blz.display, bbrush.drawable); + bbrush.drawable = XCreatePixmap(blz.display, barwin, brect.width, brect.height, + DefaultDepth(blz.display, blz.screen)); + XSync(blz.display, False); draw_bar(); for(v=view; v; v=v->next) { @@ -95,20 +92,21 @@ draw_bar() { unsigned int i = 0, w = 0, nb, size = 0; Bar *b = nil, *prev = nil; - blitz_draw_tile(bartile); + + blitz_draw_tile(&bbrush); if(!lbar && !rbar) goto MapBar; for(b=lbar, nb=2 ;nb; --nb && (b = rbar)) for(; b && (w < brect.width); b=b->next, size++) { - b->widget->rect.x = 0; - b->widget->rect.y = 0; - b->widget->rect.width = brect.height; - if(b->widget->text && strlen(b->widget->text)) - b->widget->rect.width += blitz_textwidth(b->widget->font, b->widget->text); - b->widget->rect.height = brect.height; - w += b->widget->rect.width; + b->brush.rect.x = 0; + b->brush.rect.y = 0; + b->brush.rect.width = brect.height; + if(b->text && strlen(b->text)) + b->brush.rect.width += blitz_textwidth(b->brush.font, b->text); + b->brush.rect.height = brect.height; + w += b->brush.rect.width; } if(b) { /* give all bars same width */ @@ -119,28 +117,29 @@ draw_bar() w = brect.width / size; for(b = lbar, nb=2 ;nb; b = rbar, nb--) { for(; b; b=b->next) { - b->widget->rect.x = i * w; - b->widget->rect.width = w; + b->brush.rect.x = i * w; + b->brush.rect.width = w; } } } else { /* expand rbar properly */ if(rbar) - rbar->widget->rect.width += (brect.width - w); + rbar->brush.rect.width += (brect.width - w); for(b=lbar, nb=2 ;nb--; b = rbar) for(; b; prev = b, b=b->next) - if(prev) b->widget->rect.x = prev->widget->rect.x + prev->widget->rect.width; + if(prev) b->brush.rect.x = prev->brush.rect.x + prev->brush.rect.width; } for(b=lbar, nb=2 ;nb; b=rbar, nb--) for(; b; b=b->next) { if(b == rbar) - b->widget->align = EAST; - blitz_draw_input(b->widget); + b->brush.align = EAST; + blitz_draw_label(&b->brush, b->text); } MapBar: - XCopyArea(dpy, barpmap, barwin, bargc, 0, 0, brect.width, brect.height, 0, 0); - XSync(dpy, False); + XCopyArea(blz.display, bbrush.drawable, barwin, bbrush.gc, 0, 0, + brect.width, brect.height, 0, 0); + XSync(blz.display, False); } Bar * diff --git a/cmd/wm/client.c b/cmd/wm/client.c @@ -21,15 +21,15 @@ update_client_name(Client *c) name.nitems = 0; c->name[0] = 0; - XGetTextProperty(dpy, c->win, &name, net_atom[NetWMName]); + XGetTextProperty(blz.display, c->win, &name, net_atom[NetWMName]); if(!name.nitems) - XGetWMName(dpy, c->win, &name); + XGetWMName(blz.display, c->win, &name); if(!name.nitems) return; if(name.encoding == XA_STRING) cext_strlcpy(c->name, (char *)name.value, sizeof(c->name)); else { - if(XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success + if(XmbTextPropertyToTextList(blz.display, &name, &list, &n) >= Success && n > 0 && *list) { cext_strlcpy(c->name, *list, sizeof(c->name)); @@ -37,7 +37,7 @@ update_client_name(Client *c) } } XFree(name.value); - if(XGetClassHint(dpy, c->win, &ch)) { + if(XGetClassHint(blz.display, c->win, &ch)) { snprintf(c->props, sizeof(c->props), "%s:%s:%s", ch.res_class ? ch.res_class : "", ch.res_name ? ch.res_name : "", @@ -66,10 +66,10 @@ create_client(Window w, XWindowAttributes *wa) c->border = wa->border_width; c->rect.width = wa->width + 2 * c->border; c->rect.height = wa->height + 2 * c->border; - XSetWindowBorderWidth(dpy, c->win, 0); + XSetWindowBorderWidth(blz.display, c->win, 0); c->proto = win_proto(c->win); - XGetTransientForHint(dpy, c->win, &c->trans); - if(!XGetWMNormalHints(dpy, c->win, &c->size, &msize) || !c->size.flags) + XGetTransientForHint(blz.display, c->win, &c->trans); + if(!XGetWMNormalHints(blz.display, c->win, &c->size, &msize) || !c->size.flags) c->size.flags = PSize; if(c->size.flags & PMinSize && c->size.flags & PMaxSize && c->size.min_width == c->size.max_width @@ -77,21 +77,22 @@ create_client(Window w, XWindowAttributes *wa) c->fixedsize = True; else c->fixedsize = False; - XAddToSaveSet(dpy, c->win); + XAddToSaveSet(blz.display, c->win); update_client_name(c); fwa.override_redirect = 1; fwa.background_pixmap = ParentRelative; - fwa.event_mask = SubstructureRedirectMask | SubstructureNotifyMask - | ExposureMask | ButtonPressMask | ButtonReleaseMask; + fwa.event_mask = + SubstructureRedirectMask | SubstructureNotifyMask | ExposureMask + | ButtonPressMask | PointerMotionMask | ButtonReleaseMask; - c->framewin = XCreateWindow(dpy, root, c->rect.x, c->rect.y, + c->framewin = XCreateWindow(blz.display, blz.root, c->rect.x, c->rect.y, c->rect.width + 2 * def.border, c->rect.height + def.border + height_of_bar(), 0, - DefaultDepth(dpy, screen), CopyFromParent, - DefaultVisual(dpy, screen), + DefaultDepth(blz.display, blz.screen), CopyFromParent, + DefaultVisual(blz.display, blz.screen), CWOverrideRedirect | CWBackPixmap | CWEventMask, &fwa); - c->gc = XCreateGC(dpy, c->framewin, 0, 0); - XSync(dpy, False); + c->gc = XCreateGC(blz.display, c->framewin, 0, 0); + XSync(blz.display, False); for(t=&client, i=0; *t; t=&(*t)->next, i++); c->next = *t; /* *t == nil */ @@ -109,7 +110,7 @@ set_client_state(Client * c, int state) data[0] = (long) state; data[1] = (long) None; - XChangeProperty(dpy, c->win, wm_atom[WMState], wm_atom[WMState], 32, + XChangeProperty(blz.display, c->win, wm_atom[WMState], wm_atom[WMState], 32, PropModeReplace, (unsigned char *) data, 2); } @@ -154,7 +155,7 @@ focus_client(Client *c, Bool restack) if(!c->floating && f->area->mode == Colstack) arrange_column(f->area, False); - XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); + XSetInputFocus(blz.display, c->win, RevertToPointerRoot, CurrentTime); if(old && old != old_in_area && old != c) { update_frame_widget_colors(old->sel); draw_frame(old->sel); @@ -165,7 +166,7 @@ focus_client(Client *c, Bool restack) } update_frame_widget_colors(c->sel); draw_frame(c->sel); - XSync(dpy, False); + XSync(blz.display, False); snprintf(buf, sizeof(buf), "ClientFocus %d\n", idx_of_client(c)); write_event(buf); } @@ -173,27 +174,27 @@ focus_client(Client *c, Bool restack) void map_client(Client *c) { - XSelectInput(dpy, c->win, CLIENT_MASK & ~StructureNotifyMask); - XMapWindow(dpy, c->win); - XSelectInput(dpy, c->win, CLIENT_MASK); + XSelectInput(blz.display, c->win, CLIENT_MASK & ~StructureNotifyMask); + XMapWindow(blz.display, c->win); + XSelectInput(blz.display, c->win, CLIENT_MASK); set_client_state(c, NormalState); } void unmap_client(Client *c) { - XSelectInput(dpy, c->win, CLIENT_MASK & ~StructureNotifyMask); - XUnmapWindow(dpy, c->win); - XSelectInput(dpy, c->win, CLIENT_MASK); + XSelectInput(blz.display, c->win, CLIENT_MASK & ~StructureNotifyMask); + XUnmapWindow(blz.display, c->win); + XSelectInput(blz.display, c->win, CLIENT_MASK); set_client_state(c, WithdrawnState); } void reparent_client(Client *c, Window w, int x, int y) { - XSelectInput(dpy, c->win, CLIENT_MASK & ~StructureNotifyMask); - XReparentWindow(dpy, c->win, w, x, y); - XSelectInput(dpy, c->win, CLIENT_MASK); + XSelectInput(blz.display, c->win, CLIENT_MASK & ~StructureNotifyMask); + XReparentWindow(blz.display, c->win, w, x, y); + XSelectInput(blz.display, c->win, CLIENT_MASK); } void @@ -215,10 +216,10 @@ configure_client(Client *c) e.border_width = c->border; e.above = None; e.override_redirect = False; - XSelectInput(dpy, c->win, CLIENT_MASK & ~StructureNotifyMask); - XSendEvent(dpy, c->win, False, StructureNotifyMask, (XEvent *) & e); - XSelectInput(dpy, c->win, CLIENT_MASK); - XSync(dpy, False); + XSelectInput(blz.display, c->win, CLIENT_MASK & ~StructureNotifyMask); + XSendEvent(blz.display, c->win, False, StructureNotifyMask, (XEvent *) & e); + XSelectInput(blz.display, c->win, CLIENT_MASK); + XSync(blz.display, False); } static void @@ -232,8 +233,8 @@ send_client_message(Window w, Atom a, long value) e.xclient.data.l[0] = value; e.xclient.data.l[1] = CurrentTime; - XSendEvent(dpy, w, False, NoEventMask, &e); - XSync(dpy, False); + XSendEvent(blz.display, w, False, NoEventMask, &e); + XSync(blz.display, False); } void @@ -242,7 +243,7 @@ kill_client(Client * c) if(c->proto & WM_PROTOCOL_DELWIN) send_client_message(c->win, wm_atom[WMProtocols], wm_atom[WMDelete]); else - XKillClient(dpy, c->win); + XKillClient(blz.display, c->win); } void @@ -257,10 +258,10 @@ prop_client(Client *c, XPropertyEvent *e) } switch (e->atom) { case XA_WM_TRANSIENT_FOR: - XGetTransientForHint(dpy, c->win, &c->trans); + XGetTransientForHint(blz.display, c->win, &c->trans); break; case XA_WM_NORMAL_HINTS: - if(!XGetWMNormalHints(dpy, c->win, &c->size, &msize) || !c->size.flags) { + if(!XGetWMNormalHints(blz.display, c->win, &c->size, &msize) || !c->size.flags) { c->size.flags = PSize; } if(c->size.flags & PMinSize && c->size.flags & PMaxSize @@ -353,8 +354,8 @@ manage_client(Client *c) reparent_client(c, c->framewin, c->rect.x, c->rect.y); update_views(); map_client(c); - XMapWindow(dpy, c->framewin); - XSync(dpy, False); + XMapWindow(blz.display, c->framewin); + XSync(blz.display, False); if(c->sel->area->view == sel) focus_client(c, False); flush_masked_events(EnterWindowMask); @@ -372,7 +373,7 @@ destroy_client(Client *c) View *v; Client **tc; - XGrabServer(dpy); + XGrabServer(blz.display); XSetErrorHandler(dummy_error_handler); if(c->frame) { @@ -387,9 +388,9 @@ destroy_client(Client *c) unmap_client(c); - reparent_client(c, root, c->rect.x, c->rect.y); - XFreeGC(dpy, c->gc); - XDestroyWindow(dpy, c->framewin); + reparent_client(c, blz.root, c->rect.x, c->rect.y); + XFreeGC(blz.display, c->gc); + XDestroyWindow(blz.display, c->framewin); for(tc=&client; *tc && *tc != c; tc=&(*tc)->next); cext_assert(*tc == c); @@ -398,9 +399,9 @@ destroy_client(Client *c) update_views(); free(c); - XSync(dpy, False); + XSync(blz.display, False); XSetErrorHandler(wmii_error_handler); - XUngrabServer(dpy); + XUngrabServer(blz.display); flush_masked_events(EnterWindowMask); } @@ -507,12 +508,11 @@ resize_client(Client *c, XRectangle *r, Bool ignore_xcall) f->rect.y = -height_of_bar(); } if(f->area->view == sel) - XMoveResizeWindow(dpy, c->framewin, f->rect.x, + XMoveResizeWindow(blz.display, c->framewin, f->rect.x, f->rect.y, f->rect.width, f->rect.height); else - XMoveResizeWindow(dpy, c->framewin, 2 * rect.width + f->rect.x, + XMoveResizeWindow(blz.display, c->framewin, 2 * rect.width + f->rect.x, f->rect.y, f->rect.width, f->rect.height); - resize_frame(f); } c->rect.x = def.border; @@ -521,7 +521,7 @@ resize_client(Client *c, XRectangle *r, Bool ignore_xcall) c->rect.width = f->rect.width - 2 * def.border; c->rect.height = f->rect.height - def.border - height_of_bar(); } - XMoveResizeWindow(dpy, c->win, c->rect.x, c->rect.y, + XMoveResizeWindow(blz.display, c->win, c->rect.x, c->rect.y, c->rect.width, c->rect.height); configure_client(c); } diff --git a/cmd/wm/event.c b/cmd/wm/event.c @@ -11,18 +11,19 @@ #include "wm.h" /* local functions */ -static void handle_buttonpress(XEvent * e); -static void handle_buttonrelease(XEvent * e); -static void handle_configurerequest(XEvent * e); -static void handle_destroynotify(XEvent * e); -static void handle_enternotify(XEvent * e); -static void handle_leavenotify(XEvent * e); -static void handle_expose(XEvent * e); -static void handle_keypress(XEvent * e); -static void handle_keymapnotify(XEvent * e); -static void handle_maprequest(XEvent * e); -static void handle_propertynotify(XEvent * e); -static void handle_unmapnotify(XEvent * e); +static void handle_buttonpress(XEvent *e); +static void handle_buttonrelease(XEvent *e); +static void handle_configurerequest(XEvent *e); +static void handle_destroynotify(XEvent *e); +static void handle_enternotify(XEvent *e); +static void handle_leavenotify(XEvent *e); +static void handle_expose(XEvent *e); +static void handle_keypress(XEvent *e); +static void handle_keymapnotify(XEvent *e); +static void handle_maprequest(XEvent *e); +static void handle_motionnotify(XEvent *e); +static void handle_propertynotify(XEvent *e); +static void handle_unmapnotify(XEvent *e); void (*handler[LASTEvent]) (XEvent *) = { [ButtonPress] = handle_buttonpress, @@ -34,6 +35,7 @@ void (*handler[LASTEvent]) (XEvent *) = { [Expose] = handle_expose, [KeyPress] = handle_keypress, [KeymapNotify] = handle_keymapnotify, + [MotionNotify] = handle_motionnotify, [MapRequest] = handle_maprequest, [PropertyNotify]= handle_propertynotify, [UnmapNotify] = handle_unmapnotify @@ -43,8 +45,8 @@ void check_x_event(IXPConn *c) { XEvent ev; - while(XPending(dpy)) { /* main event loop */ - XNextEvent(dpy, &ev); + while(XPending(blz.display)) { /* main event loop */ + XNextEvent(blz.display, &ev); if(handler[ev.type]) (handler[ev.type]) (&ev); /* call handler */ } @@ -55,10 +57,12 @@ flush_masked_events(long even_mask) { XEvent ev; unsigned int n = 0; - while(XCheckMaskEvent(dpy, even_mask, &ev)) n++; + while(XCheckMaskEvent(blz.display, even_mask, &ev)) n++; return n; } +static Bool drag = False; + static void handle_buttonrelease(XEvent *e) { @@ -68,14 +72,14 @@ handle_buttonrelease(XEvent *e) static char buf[32]; if(ev->window == barwin) { for(b=lbar; b; b=b->next) - if(ispointinrect(ev->x, ev->y, &b->widget->rect)) { + if(ispointinrect(ev->x, ev->y, &b->brush.rect)) { snprintf(buf, sizeof(buf), "LeftBarClick %s %d\n", b->name, ev->button); write_event(buf); return; } for(b=rbar; b; b=b->next) - if(ispointinrect(ev->x, ev->y, &b->widget->rect)) { + if(ispointinrect(ev->x, ev->y, &b->brush.rect)) { snprintf(buf, sizeof(buf), "RightBarClick %s %d\n", b->name, ev->button); write_event(buf); @@ -83,9 +87,37 @@ handle_buttonrelease(XEvent *e) } } else if((c = frame_of_win(ev->window)) && c->frame) { + if(ispointinrect(ev->x, ev->y, &c->sel->tagbar.rect)) { + c->sel->tagbar.cursor = c->sel->tagbar.selend + = blitz_charof(&c->sel->tagbar, ev->x, ev->y); + draw_frame(c->sel); + } snprintf(buf, sizeof(buf), "ClientClick %d %d\n", idx_of_client(c), ev->button); write_event(buf); + drag = False; + } +} + +static void +handle_motionnotify(XEvent *e) +{ + Client *c; + XMotionEvent *ev = &e->xmotion; + + if(!drag) + return; + + if((c = frame_of_win(ev->window))) { + if(ispointinrect(ev->x, ev->y, &c->sel->tagbar.rect)) { + c->sel->tagbar.selend = blitz_charof(&c->sel->tagbar, ev->x, ev->y); + if(c->sel->tagbar.selend < c->sel->tagbar.selstart) { + char *tmp = c->sel->tagbar.selend; + c->sel->tagbar.selend = c->sel->tagbar.selstart; + c->sel->tagbar.selstart = tmp; + } + draw_frame(c->sel); + } } } @@ -97,6 +129,13 @@ handle_buttonpress(XEvent *e) if((c = frame_of_win(ev->window))) { ev->state &= valid_mask; + if(ispointinrect(ev->x, ev->y, &c->sel->tagbar.rect)) { + c->sel->tagbar.cursor = c->sel->tagbar.selstart + = c->sel->tagbar.selend + = blitz_charof(&c->sel->tagbar, ev->x, ev->y); + draw_frame(c->sel); + drag = True; + } if((ev->state & def.mod) == def.mod) { focus(c, True); switch(ev->button) { @@ -160,7 +199,7 @@ handle_configurerequest(XEvent *e) wc.stack_mode = ev->detail; if(f->area->view != sel) wc.x += 2 * rect.width; - XConfigureWindow(dpy, c->framewin, ev->value_mask, &wc); + XConfigureWindow(blz.display, c->framewin, ev->value_mask, &wc); configure_client(c); } } @@ -183,8 +222,8 @@ handle_configurerequest(XEvent *e) wc.stack_mode = Above; ev->value_mask &= ~CWStackMode; ev->value_mask |= CWBorderWidth; - XConfigureWindow(dpy, ev->window, ev->value_mask, &wc); - XSync(dpy, False); + XConfigureWindow(blz.display, ev->window, ev->value_mask, &wc); + XSync(blz.display, False); } static void @@ -213,7 +252,7 @@ handle_enternotify(XEvent *e) c = a->sel->client; focus(c, False); } - else if(ev->window == root) { + else if(ev->window == blz.root) { sel_screen = True; draw_frames(); } @@ -224,7 +263,7 @@ handle_leavenotify(XEvent *e) { XCrossingEvent *ev = &e->xcrossing; - if((ev->window == root) && !ev->same_screen) { + if((ev->window == blz.root) && !ev->same_screen) { sel_screen = True; draw_frames(); } @@ -248,7 +287,7 @@ handle_keypress(XEvent *e) { XKeyEvent *ev = &e->xkey; ev->state &= valid_mask; - handle_key(root, ev->state, (KeyCode) ev->keycode); + handle_key(blz.root, ev->state, (KeyCode) ev->keycode); } static void @@ -263,11 +302,11 @@ handle_maprequest(XEvent *e) XMapRequestEvent *ev = &e->xmaprequest; static XWindowAttributes wa; - if(!XGetWindowAttributes(dpy, ev->window, &wa)) + if(!XGetWindowAttributes(blz.display, ev->window, &wa)) return; if(wa.override_redirect) { - XSelectInput(dpy, ev->window, + XSelectInput(blz.display, ev->window, (StructureNotifyMask | PropertyChangeMask)); return; } diff --git a/cmd/wm/frame.c b/cmd/wm/frame.c @@ -24,15 +24,21 @@ create_frame(Area *a, Client *c) f->rect.height += def.border + height_of_bar(); f->collapsed = False; - f->tile = blitz_create_tile(c->framewin, c->gc); - f->tagbar = blitz_create_input(c->framewin, c->gc, &def.font); - f->titlebar = blitz_create_input(c->framewin, c->gc, &def.font); - f->posbar = blitz_create_input(c->framewin, c->gc, &def.font); - f->tile->notch = &c->rect; - f->tagbar->text = c->tags; - f->titlebar->text = c->name; - f->titlebar->align = WEST; - f->tagbar->align = f->posbar->align = CENTER; + f->tile.blitz = &blz; + f->tile.drawable = pmap; + f->tile.gc = c->gc; + f->tile.font = &def.font; + f->tile.color = def.normcolor; + f->titlebar = f->posbar = f->tile; + f->titlebar.align = WEST; + f->posbar.align = CENTER; + + f->tagbar.blitz = &blz; + f->tagbar.drawable = pmap; + f->tagbar.gc = c->gc; + f->tagbar.font = &def.font; + f->tagbar.norm = def.normcolor; + f->tagbar.sel = def.selcolor; a->sel = f; c->sel = f; @@ -77,13 +83,6 @@ destroy_frame(Frame *f) Area *a = f->area; Frame **ft, *pr = nil; - blitz_destroy_tile(f->tile); - blitz_destroy_input(f->tagbar); - blitz_destroy_input(f->titlebar); - if(f->posbar->text) - free(f->posbar->text); - blitz_destroy_input(f->posbar); - for(ft=&c->frame; *ft && *ft != f; pr = *ft, ft=&(*ft)->cnext); cext_assert(*ft == f); *ft = f->cnext; @@ -128,69 +127,66 @@ void update_frame_widget_colors(Frame *f) { if(sel_screen && (f->client == sel_client())) - f->tile->color = f->tagbar->color = f->titlebar->color - = def.selcolor; + f->tile.color = f->titlebar.color = def.selcolor; else - f->tile->color = f->tagbar->color = f->titlebar->color - = def.normcolor; + f->tile.color = f->titlebar.color = def.normcolor; if(f->area->sel == f) - f->posbar->color = def.selcolor; + f->posbar.color = def.selcolor; else - f->posbar->color = def.normcolor; + f->posbar.color = def.normcolor; } void -resize_frame(Frame *f) +draw_frame(Frame *f) { Frame *p; unsigned int fidx, size, w; char buf[256]; + char *test = "tag1 tag2 tag3 tag4 | xterm"; for(fidx=0, p=f->area->frame; p && p != f; p=p->anext, fidx++); for(size=fidx; p; p=p->anext, size++); if(def.border) { - f->tile->rect = f->rect; - f->tile->rect.x = f->tile->rect.y = 0; + f->tile.rect = f->rect; + f->tile.rect.x = f->tile.rect.y = 0; } - f->posbar->rect = f->tile->rect; - f->posbar->rect.height = height_of_bar(); + f->posbar.rect = f->tile.rect; + f->posbar.rect.height = height_of_bar(); snprintf(buf, sizeof(buf), "%s%d/%d", (f->area == f->area->view->area) ? "~" : "", fidx + 1, size); - if(f->posbar->text) - free(f->posbar->text); - f->posbar->text = strdup(buf); - w = f->posbar->rect.width = - f->posbar->rect.height + blitz_textwidth(&def.font, f->posbar->text); + w = f->posbar.rect.width = + f->posbar.rect.height + blitz_textwidth(&def.font, buf); - f->posbar->rect.x = f->rect.width - f->posbar->rect.width; + f->posbar.rect.x = f->rect.width - f->posbar.rect.width; /* tag bar */ - f->tagbar->rect = f->posbar->rect; - f->tagbar->rect.x = 0; - f->tagbar->rect.width = - f->tagbar->rect.height + blitz_textwidth(&def.font, f->tagbar->text); - - if(f->tagbar->rect.width > f->rect.width / 3) - f->tagbar->rect.width = f->rect.width / 3; - - f->titlebar->rect = f->tagbar->rect; - f->titlebar->rect.x = f->tagbar->rect.x + f->tagbar->rect.width; - f->titlebar->rect.width = f->rect.width - (f->tagbar->rect.width + f->posbar->rect.width); -} - -void -draw_frame(Frame *f) -{ - blitz_draw_input(f->tile); - blitz_draw_input(f->tagbar); - blitz_draw_input(f->titlebar); - blitz_draw_input(f->posbar); + f->tagbar.rect = f->posbar.rect; + f->tagbar.rect.x = 0; + f->tagbar.rect.width = +/* f->tagbar.rect.height + blitz_textwidth(&def.font, f->client->tags);*/ + f->tagbar.rect.height + blitz_textwidth(&def.font, test); + + if(f->tagbar.rect.width > f->rect.width / 3) + f->tagbar.rect.width = f->rect.width / 3; + + f->titlebar.rect = f->tagbar.rect; + f->titlebar.rect.x = f->tagbar.rect.x + f->tagbar.rect.width; + f->titlebar.rect.width = f->rect.width - (f->tagbar.rect.width + f->posbar.rect.width); + + blitz_draw_tile(&f->tile); + f->tagbar.text = test;/*f->client->tags;*/ + blitz_draw_input(&f->tagbar); + blitz_draw_label(&f->titlebar, f->client->name); + blitz_draw_label(&f->posbar, buf); + XCopyArea(blz.display, pmap, f->client->framewin, f->tagbar.gc, + 0, 0, f->rect.width, f->rect.height, 0, 0); + XSync(blz.display, False); } void diff --git a/cmd/wm/fs.c b/cmd/wm/fs.c @@ -235,7 +235,7 @@ parse_colors(char **buf, int *buflen, BlitzColor *col) { return Ebadvalue; (*buflen) -= 23; bcopy(*buf, col->colstr, 23); - blitz_loadcolor(col); + blitz_loadcolor(&blz, col); (*buf) += 23; if(**buf == '\n' || **buf == ' ') { @@ -268,7 +268,7 @@ message_root(char *message) message += 5; free(def.font.fontstr); def.font.fontstr = strdup(message); - blitz_loadfont(&def.font); + blitz_loadfont(&blz, &def.font); return nil; }if(!strncmp(message, "grabmod ", 8)) { message += 8; @@ -825,12 +825,10 @@ fs_clunk(Req *r) { case FsFBar: buf = f->bar->buf; i = strlen(f->bar->buf); - parse_colors(&buf, &i, &f->bar->widget->color); + parse_colors(&buf, &i, &f->bar->brush.color); while(buf[i - 1] == '\n') buf[--i] = '\0'; - if(f->bar->widget->text) - free(f->bar->widget->text); - f->bar->widget->text = strdup(buf); + cext_strlcpy(f->bar->text, buf, sizeof(f->bar->text)); draw_bar(); break; case FsFEvent: diff --git a/cmd/wm/key.c b/cmd/wm/key.c @@ -22,8 +22,8 @@ init_lock_keys() int i; num_lock_mask = 0; - modmap = XGetModifierMapping(dpy); - num_lock = XKeysymToKeycode(dpy, XStringToKeysym("Num_Lock")); + modmap = XGetModifierMapping(blz.display); + num_lock = XKeysymToKeycode(blz.display, XStringToKeysym("Num_Lock")); if(modmap && modmap->max_keypermod > 0) { int max = (sizeof(masks) / sizeof(int)) * modmap->max_keypermod; @@ -60,26 +60,26 @@ mod_key_of_str(char *val) static void grab_key(Key *k) { - XGrabKey(dpy, k->key, k->mod, root, + XGrabKey(blz.display, k->key, k->mod, blz.root, True, GrabModeAsync, GrabModeAsync); if(num_lock_mask) { - XGrabKey(dpy, k->key, k->mod | num_lock_mask, root, + XGrabKey(blz.display, k->key, k->mod | num_lock_mask, blz.root, True, GrabModeAsync, GrabModeAsync); - XGrabKey(dpy, k->key, k->mod | num_lock_mask | LockMask, root, + XGrabKey(blz.display, k->key, k->mod | num_lock_mask | LockMask, blz.root, True, GrabModeAsync, GrabModeAsync); } - XSync(dpy, False); + XSync(blz.display, False); } static void ungrab_key(Key *k) { - XUngrabKey(dpy, k->key, k->mod, root); + XUngrabKey(blz.display, k->key, k->mod, blz.root); if(num_lock_mask) { - XUngrabKey(dpy, k->key, k->mod | num_lock_mask, root); - XUngrabKey(dpy, k->key, k->mod | num_lock_mask | LockMask, root); + XUngrabKey(blz.display, k->key, k->mod | num_lock_mask, blz.root); + XUngrabKey(blz.display, k->key, k->mod | num_lock_mask | LockMask, blz.root); } - XSync(dpy, False); + XSync(blz.display, False); } static Key * @@ -121,7 +121,7 @@ get_key(const char *name) kstr++; else kstr = seq[i]; - k->key = XKeysymToKeycode(dpy, XStringToKeysym(kstr)); + k->key = XKeysymToKeycode(blz.display, XStringToKeysym(kstr)); k->mod = mod_key_of_str(seq[i]); } if(r) { @@ -140,10 +140,10 @@ next_keystroke(unsigned long *mod, KeyCode *keyCode) KeySym sym; *mod = 0; do { - XMaskEvent(dpy, KeyPressMask, &e); + XMaskEvent(blz.display, KeyPressMask, &e); *mod |= e.xkey.state & valid_mask; *keyCode = (KeyCode) e.xkey.keycode; - sym = XKeycodeToKeysym(dpy, e.xkey.keycode, 0); + sym = XKeycodeToKeysym(blz.display, e.xkey.keycode, 0); } while(IsModifierKey(sym)); } @@ -154,18 +154,18 @@ emulate_key_press(unsigned long mod, KeyCode key) Window client_win; int revert; - XGetInputFocus(dpy, &client_win, &revert); + XGetInputFocus(blz.display, &client_win, &revert); e.xkey.type = KeyPress; e.xkey.time = CurrentTime; e.xkey.window = client_win; - e.xkey.display = dpy; + e.xkey.display = blz.display; e.xkey.state = mod; e.xkey.keycode = key; - XSendEvent(dpy, client_win, True, KeyPressMask, &e); + XSendEvent(blz.display, client_win, True, KeyPressMask, &e); e.xkey.type = KeyRelease; - XSendEvent(dpy, client_win, True, KeyReleaseMask, &e); - XSync(dpy, False); + XSendEvent(blz.display, client_win, True, KeyReleaseMask, &e); + XSync(blz.display, False); } static Key * @@ -198,7 +198,7 @@ handle_key_seq(Window w, Key *done) emulate_key_press(mod, key); /* double key */ else { if(!found) { - XBell(dpy, 0); + XBell(blz.display, 0); } /* grabbed but not found */ else if(!found->tnext && !found->next) { snprintf(buf, sizeof(buf), "Key %s\n", found->name); @@ -219,17 +219,17 @@ handle_key(Window w, unsigned long mod, KeyCode keycode) Key *found = match_keys(key, mod, keycode, False); if(!found) { - XBell(dpy, 0); + XBell(blz.display, 0); } /* grabbed but not found */ else if(!found->tnext && !found->next) { snprintf(buf, sizeof(buf), "Key %s\n", found->name); write_event(buf); } else { - XGrabKeyboard(dpy, w, True, GrabModeAsync, GrabModeAsync, CurrentTime); + XGrabKeyboard(blz.display, w, True, GrabModeAsync, GrabModeAsync, CurrentTime); handle_key_seq(w, found); - XUngrabKeyboard(dpy, CurrentTime); - XSync(dpy, False); + XUngrabKeyboard(blz.display, CurrentTime); + XSync(blz.display, False); } } @@ -267,5 +267,5 @@ update_keys() grab_key(k); } - XSync(dpy, False); + XSync(blz.display, False); } diff --git a/cmd/wm/mouse.c b/cmd/wm/mouse.c @@ -159,14 +159,14 @@ draw_xor_border(XRectangle *r) xor.y += 2; xor.width = xor.width > 4 ? xor.width - 4 : 0; xor.height = xor.height > 4 ? xor.height - 4 : 0; - XSetLineAttributes(dpy, xorgc, 1, LineSolid, CapNotLast, JoinMiter); - XDrawLine(dpy, root, xorgc, xor.x + 2, xor.y + xor.height / 2, + XSetLineAttributes(blz.display, xorgc, 1, LineSolid, CapNotLast, JoinMiter); + XDrawLine(blz.display, blz.root, xorgc, xor.x + 2, xor.y + xor.height / 2, xor.x + xor.width - 2, xor.y + xor.height / 2); - XDrawLine(dpy, root, xorgc, xor.x + xor.width / 2, xor.y + 2, + XDrawLine(blz.display, blz.root, xorgc, xor.x + xor.width / 2, xor.y + 2, xor.x + xor.width / 2, xor.y + xor.height - 2); - XSetLineAttributes(dpy, xorgc, 4, LineSolid, CapNotLast, JoinMiter); - XDrawRectangles(dpy, root, xorgc, &xor, 1); - XSync(dpy, False); + XSetLineAttributes(blz.display, xorgc, 4, LineSolid, CapNotLast, JoinMiter); + XDrawRectangles(blz.display, blz.root, xorgc, &xor, 1); + XSync(blz.display, False); } void @@ -186,7 +186,7 @@ do_mouse_resize(Client *c, BlitzAlign align) XRectangle origin = frect; XPoint pt; - XQueryPointer(dpy, c->framewin, &dummy, &dummy, &i, &i, &ox, &oy, &di); + XQueryPointer(blz.display, c->framewin, &dummy, &dummy, &i, &i, &ox, &oy, &di); rx = (float)ox / frect.width; ry = (float)oy / frect.height; @@ -202,21 +202,21 @@ do_mouse_resize(Client *c, BlitzAlign align) if(align&WEST) ox -= px; - XWarpPointer(dpy, None, c->framewin, 0, 0, 0, 0, ox, oy); + XWarpPointer(blz.display, None, c->framewin, 0, 0, 0, 0, ox, oy); } - XTranslateCoordinates(dpy, c->framewin, root, ox, oy, &ox, &oy, &dummy); + XTranslateCoordinates(blz.display, c->framewin, blz.root, ox, oy, &ox, &oy, &dummy); pt.x = ox; pt.y = oy; - XSync(dpy, False); - if(XGrabPointer(dpy, c->framewin, False, MouseMask, GrabModeAsync, GrabModeAsync, + XSync(blz.display, False); + if(XGrabPointer(blz.display, c->framewin, False, MouseMask, GrabModeAsync, GrabModeAsync, None, cursor[CurResize], CurrentTime) != GrabSuccess) return; - XGrabServer(dpy); + XGrabServer(blz.display); draw_xor_border(&frect); for(;;) { - XMaskEvent(dpy, MouseMask | ExposureMask, &ev); + XMaskEvent(blz.display, MouseMask | ExposureMask, &ev); switch (ev.type) { case ButtonRelease: draw_xor_border(&frect); @@ -226,11 +226,11 @@ do_mouse_resize(Client *c, BlitzAlign align) resize_client(c, &frect, False); if(rects) free(rects); - XUngrabServer(dpy); - XUngrabPointer(dpy, CurrentTime); - XSync(dpy, False); + XUngrabServer(blz.display); + XUngrabPointer(blz.display, CurrentTime); + XSync(blz.display, False); - XWarpPointer(dpy, None, c->framewin, 0, 0, 0, 0, + XWarpPointer(blz.display, None, c->framewin, 0, 0, 0, 0, frect.width * rx, frect.height * ry); return; break; @@ -239,7 +239,7 @@ do_mouse_resize(Client *c, BlitzAlign align) pt.x = ev.xmotion.x; pt.y = ev.xmotion.y; - XTranslateCoordinates(dpy, c->framewin, root, ev.xmotion.x, + XTranslateCoordinates(blz.display, c->framewin, blz.root, ev.xmotion.x, ev.xmotion.y, &px, &py, &dummy); rect_morph_xy(&origin, px-ox, py-oy, &align); @@ -266,12 +266,12 @@ do_mouse_resize(Client *c, BlitzAlign align) void grab_mouse(Window w, unsigned long mod, unsigned int button) { - XGrabButton(dpy, button, mod, w, False, ButtonMask, + XGrabButton(blz.display, button, mod, w, False, ButtonMask, GrabModeAsync, GrabModeSync, None, None); if((mod != AnyModifier) && num_lock_mask) { - XGrabButton(dpy, button, mod | num_lock_mask, w, False, ButtonMask, + XGrabButton(blz.display, button, mod | num_lock_mask, w, False, ButtonMask, GrabModeAsync, GrabModeSync, None, None); - XGrabButton(dpy, button, mod | num_lock_mask | LockMask, w, False, + XGrabButton(blz.display, button, mod | num_lock_mask | LockMask, w, False, ButtonMask, GrabModeAsync, GrabModeSync, None, None); } } @@ -279,9 +279,9 @@ grab_mouse(Window w, unsigned long mod, unsigned int button) void ungrab_mouse(Window w, unsigned long mod, unsigned int button) { - XUngrabButton(dpy, button, mod, w); + XUngrabButton(blz.display, button, mod, w); if(mod != AnyModifier && num_lock_mask) { - XUngrabButton(dpy, button, mod | num_lock_mask, w); - XUngrabButton(dpy, button, mod | num_lock_mask | LockMask, w); + XUngrabButton(blz.display, button, mod | num_lock_mask, w); + XUngrabButton(blz.display, button, mod | num_lock_mask | LockMask, w); } } diff --git a/cmd/wm/view.c b/cmd/wm/view.c @@ -92,7 +92,7 @@ focus_view(View *v) cext_assert(v); - XGrabServer(dpy); + XGrabServer(blz.display); assign_sel_view(v); update_frame_selectors(v); @@ -102,19 +102,19 @@ focus_view(View *v) if(c->sel) { Frame *f = c->sel; if(f && f->area->view == v) { - XMoveWindow(dpy, c->framewin, f->rect.x, f->rect.y); + XMoveWindow(blz.display, c->framewin, f->rect.x, f->rect.y); resize_client(c, &f->rect, False); } else - XMoveWindow(dpy, c->framewin, 2 * rect.width + f->rect.x, f->rect.y); + XMoveWindow(blz.display, c->framewin, 2 * rect.width + f->rect.x, f->rect.y); } if((c = sel_client())) focus_client(c, True); draw_frames(); - XSync(dpy, False); - XUngrabServer(dpy); + XSync(blz.display, False); + XUngrabServer(blz.display); flush_masked_events(EnterWindowMask); } @@ -188,7 +188,7 @@ detach_from_view(View *v, Client *c) next=a->next; if(is_of_area(a, c)) { detach_from_area(a, c); - XMoveWindow(dpy, c->framewin, 2 * rect.width, 0); + XMoveWindow(blz.display, c->framewin, 2 * rect.width, 0); } } } @@ -241,7 +241,7 @@ restack_view(View *v) } if(n) - XRestackWindows(dpy, wins, n); + XRestackWindows(blz.display, wins, n); } void diff --git a/cmd/wm/wm.c b/cmd/wm/wm.c @@ -17,8 +17,6 @@ #include "wm.h" -IXPServer srv = {0}; - static int other_wm_running; static int (*x_error_handler) (Display *, XErrorEvent *); static char version[] = "wmiiwm - " VERSION ", (C)opyright MMIV-MMVI Anselm R. Garbe\n"; @@ -30,7 +28,7 @@ usage() exit(1); } -void +static void scan_wins() { int i; @@ -39,11 +37,11 @@ scan_wins() XWindowAttributes wa; Window d1, d2; - if(XQueryTree(dpy, root, &d1, &d2, &wins, &num)) { + if(XQueryTree(blz.display, blz.root, &d1, &d2, &wins, &num)) { for(i = 0; i < num; i++) { - if(!XGetWindowAttributes(dpy, wins[i], &wa)) + if(!XGetWindowAttributes(blz.display, wins[i], &wa)) continue; - if(wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1)) + if(wa.override_redirect || XGetTransientForHint(blz.display, wins[i], &d1)) continue; if(wa.map_state == IsViewable) manage_client(create_client(wins[i], &wa)); @@ -61,7 +59,7 @@ win_property(Window w, Atom a, Atom t, long l, unsigned char **prop) unsigned long res, extra; int status; - status = XGetWindowProperty(dpy, w, a, 0L, l, False, t, &real, &format, + status = XGetWindowProperty(blz.display, w, a, 0L, l, False, t, &real, &format, &res, &extra, prop); if(status != Success || *prop == 0) { @@ -98,7 +96,7 @@ int win_state(Window w) { /* state hints */ - XWMHints *hints = XGetWMHints(dpy, w); + XWMHints *hints = XGetWMHints(blz.display, w); int res; long *prop = 0; @@ -120,22 +118,22 @@ win_state(Window w) static void init_atoms() { - wm_atom[WMState] = XInternAtom(dpy, "WM_STATE", False); - wm_atom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); - wm_atom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False); - net_atom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); - net_atom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False); + wm_atom[WMState] = XInternAtom(blz.display, "WM_STATE", False); + wm_atom[WMProtocols] = XInternAtom(blz.display, "WM_PROTOCOLS", False); + wm_atom[WMDelete] = XInternAtom(blz.display, "WM_DELETE_WINDOW", False); + net_atom[NetSupported] = XInternAtom(blz.display, "_NET_SUPPORTED", False); + net_atom[NetWMName] = XInternAtom(blz.display, "_NET_WM_NAME", False); - XChangeProperty(dpy, root, net_atom[NetSupported], XA_ATOM, 32, + XChangeProperty(blz.display, blz.root, net_atom[NetSupported], XA_ATOM, 32, PropModeReplace, (unsigned char *) net_atom, NetLast); } static void init_cursors() { - cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr); - cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing); - cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur); + cursor[CurNormal] = XCreateFontCursor(blz.display, XC_left_ptr); + cursor[CurResize] = XCreateFontCursor(blz.display, XC_sizing); + cursor[CurMove] = XCreateFontCursor(blz.display, XC_fleur); } static void @@ -151,15 +149,15 @@ init_screen() gcv.foreground = def.selcolor.bg; gcv.plane_mask = AllPlanes; gcv.graphics_exposures = False; - xorgc = XCreateGC(dpy, root, GCForeground | GCGraphicsExposures | + xorgc = XCreateGC(blz.display, blz.root, GCForeground | GCGraphicsExposures | GCFunction | GCSubwindowMode | GCPlaneMask, &gcv); rect.x = rect.y = 0; - rect.width = DisplayWidth(dpy, screen); - rect.height = DisplayHeight(dpy, screen); + rect.width = DisplayWidth(blz.display, blz.screen); + rect.height = DisplayHeight(blz.display, blz.screen); def.snap = rect.height / 63; - sel_screen = XQueryPointer(dpy, root, &w, &w, &ret, &ret, &ret, &ret, &mask); + sel_screen = XQueryPointer(blz.display, blz.root, &w, &w, &ret, &ret, &ret, &ret, &mask); } /* @@ -187,7 +185,7 @@ wmii_error_handler(Display *dpy, XErrorEvent *error) return 0; fprintf(stderr, "wmiiwm: fatal error: Xrequest code=%d, Xerror code=%d\n", error->request_code, error->error_code); - return x_error_handler(dpy, error); /* calls exit() */ + return x_error_handler(blz.display, error); /* calls exit() */ } /* @@ -206,9 +204,9 @@ cleanup() { Client *c; for(c=client; c; c=c->next) - reparent_client(c, root, c->sel->rect.x, c->sel->rect.y); - XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); - XSync(dpy, False); + reparent_client(c, blz.root, c->sel->rect.x, c->sel->rect.y); + XSetInputFocus(blz.display, PointerRoot, RevertToPointerRoot, CurrentTime); + XSync(blz.display, False); } int @@ -243,27 +241,27 @@ main(int argc, char *argv[]) } } - dpy = XOpenDisplay(0); - if(!dpy) { + blz.display = XOpenDisplay(0); + if(!blz.display) { fputs("wmiiwm: cannot open display\n", stderr); exit(1); } - screen = DefaultScreen(dpy); - root = RootWindow(dpy, screen); + blz.screen = DefaultScreen(blz.display); + blz.root = RootWindow(blz.display, blz.screen); /* check if another WM is already running */ other_wm_running = 0; XSetErrorHandler(startup_error_handler); /* this causes an error if some other WM is running */ - XSelectInput(dpy, root, SubstructureRedirectMask | EnterWindowMask); - XSync(dpy, False); + XSelectInput(blz.display, blz.root, SubstructureRedirectMask | EnterWindowMask); + XSync(blz.display, False); if(other_wm_running) { fputs("wmiiwm: another window manager is already running\n", stderr); exit(1); } if(checkwm) { - XCloseDisplay(dpy); + XCloseDisplay(blz.display); exit(0); } /* above -c is checked */ @@ -283,9 +281,7 @@ main(int argc, char *argv[]) ixp_server_open_conn(&srv, i, &p9srv, serve_9pcon, nil); /* X server */ - ixp_server_open_conn(&srv, ConnectionNumber(dpy), nil, check_x_event, nil); - blitz_x11_init(dpy); - + ixp_server_open_conn(&srv, ConnectionNumber(blz.display), nil, check_x_event, nil); view = nil; client = nil; sel = nil; @@ -304,21 +300,21 @@ main(int argc, char *argv[]) def.border = 2; def.colmode = Coldefault; cext_strlcpy(def.selcolor.colstr, BLITZ_SELCOLORS, sizeof(def.selcolor.colstr)); - blitz_loadcolor(&def.selcolor); + blitz_loadcolor(&blz, &def.selcolor); cext_strlcpy(def.normcolor.colstr, BLITZ_NORMCOLORS, sizeof(def.normcolor.colstr)); - blitz_loadcolor(&def.normcolor); + blitz_loadcolor(&blz, &def.normcolor); cext_strlcpy(def.grabmod, "Mod1", sizeof(def.grabmod)); def.mod = Mod1Mask; init_atoms(); init_cursors(); - blitz_loadfont(&def.font); + blitz_loadfont(&blz, &def.font); init_lock_keys(); init_screen(); wa.event_mask = SubstructureRedirectMask | EnterWindowMask | LeaveWindowMask; wa.cursor = cursor[CurNormal]; - XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa); + XChangeWindowAttributes(blz.display, blz.root, CWEventMask | CWCursor, &wa); wa.override_redirect = 1; wa.background_pixmap = ParentRelative; @@ -328,21 +324,24 @@ main(int argc, char *argv[]) brect = rect; brect.height = height_of_bar(); brect.y = rect.height - brect.height; - barwin = XCreateWindow(dpy, RootWindow(dpy, screen), brect.x, brect.y, - brect.width, brect.height, 0, DefaultDepth(dpy, screen), - CopyFromParent, DefaultVisual(dpy, screen), + barwin = XCreateWindow(blz.display, RootWindow(blz.display, blz.screen), brect.x, brect.y, + brect.width, brect.height, 0, DefaultDepth(blz.display, blz.screen), + CopyFromParent, DefaultVisual(blz.display, blz.screen), CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); - XSync(dpy, False); + XSync(blz.display, False); - bargc = XCreateGC(dpy, barwin, 0, 0); + bbrush.blitz = &blz; + bbrush.gc = XCreateGC(blz.display, barwin, 0, 0); + bbrush.drawable = XCreatePixmap(blz.display, barwin, brect.width, brect.height, + DefaultDepth(blz.display, blz.screen)); + bbrush.rect = brect; + bbrush.color = def.normcolor; + bbrush.font = &def.font; - barpmap = XCreatePixmap(dpy, barwin, brect.width, brect.height, - DefaultDepth(dpy, screen)); - bartile = blitz_create_tile(barpmap, bargc); - bartile->rect = brect; - bartile->color = def.normcolor; + pmap = XCreatePixmap(blz.display, blz.root, rect.width, rect.height, + DefaultDepth(blz.display, blz.screen)); - XMapRaised(dpy, barwin); + XMapRaised(blz.display, barwin); draw_bar(); scan_wins(); @@ -351,10 +350,9 @@ main(int argc, char *argv[]) if(errstr) fprintf(stderr, "wmii: fatal: %s\n", errstr); - blitz_destroy_tile(bartile); ixp_server_close(&srv); cleanup(); - XCloseDisplay(dpy); + XCloseDisplay(blz.display); return errstr ? 1 : 0; } diff --git a/cmd/wm/wm.h b/cmd/wm/wm.h @@ -83,10 +83,10 @@ struct Frame { XRectangle revert; Client *client; Bool collapsed; - BlitzWidget *tile; - BlitzWidget *tagbar; - BlitzWidget *titlebar; - BlitzWidget *posbar; + BlitzBrush tile; + BlitzInput tagbar; + BlitzBrush titlebar; + BlitzBrush posbar; }; struct Client { @@ -126,9 +126,10 @@ typedef struct Bar Bar; struct Bar { Bar *next; char buf[280]; + char text[256]; char name[256]; unsigned short id; - BlitzWidget *widget; + BlitzBrush brush; }; typedef struct Rule Rule; @@ -169,16 +170,12 @@ Bar *rbar; View *sel; P9Srv p9srv; -Display *dpy; -int screen; -Window root; +Blitz blz; XRectangle rect; IXPServer srv; -Pixmap barpmap; Window barwin; -GC bargc; GC xorgc; -BlitzWidget *bartile; +BlitzBrush bbrush; XRectangle brect; char *user; Default def; @@ -188,6 +185,7 @@ Cursor cursor[CurLast]; unsigned int valid_mask; unsigned int num_lock_mask; Bool sel_screen; +Pixmap pmap; void (*handler[LASTEvent]) (XEvent *); /* wm.c */ @@ -325,7 +323,6 @@ void update_views(); unsigned int newcolw_of_view(View *v); /* wm.c */ -void scan_wins(); int win_proto(Window w); int win_state(Window w); int wmii_error_handler(Display *dpy, XErrorEvent *error); diff --git a/cmd/wmiimenu.c b/cmd/wmiimenu.c @@ -27,10 +27,8 @@ static int ret = 0; static char text[4096]; static BlitzColor selcolor; static BlitzColor normcolor; -static Display *dpy; static Window win; static XRectangle irect; -static int screen; static ItemVector allitem = {0}; static ItemVector item = {0}; static int sel = -1; @@ -40,7 +38,8 @@ static unsigned int curroff = 0; static unsigned int cmdw = 0; static unsigned int twidth = 0; static unsigned int cwidth = 0; -static BlitzWidget *menu = nil; +static Blitz blz = {0}; +static BlitzBrush brush = {0}; static const int seek = 30; /* 30px */ static void draw_menu(void); @@ -71,7 +70,7 @@ update_offsets() return; for(i = curroff; i < item.size; i++) { - tw = blitz_textwidth(menu->font, item.data[i]); + tw = blitz_textwidth(brush.font, item.data[i]); if(tw > irect.width / 3) tw = irect.width / 3; w += tw + irect.height; @@ -82,7 +81,7 @@ update_offsets() w = cmdw + 2 * seek; for(i = curroff; i > 0; i--) { - tw = blitz_textwidth(menu->font, item.data[i]); + tw = blitz_textwidth(brush.font, item.data[i]); if(tw > irect.width / 3) tw = irect.width / 3; w += tw + irect.height; @@ -123,72 +122,67 @@ update_items(char *pattern) return item.size; } -/* creates menu structs for menu mode drawing */ +/* creates brush structs for brush mode drawing */ static void draw_menu() { unsigned int i, offx = 0; - menu->align = WEST; + brush.align = WEST; - menu->rect = irect; - menu->rect.x = 0; - menu->rect.y = 0; - menu->color = normcolor; - menu->text = nil; - blitz_draw_tile(menu); + brush.rect = irect; + brush.rect.x = 0; + brush.rect.y = 0; + brush.color = normcolor; + blitz_draw_tile(&brush); /* print command */ if(!title || text[0]) { - menu->text = text; - menu->color = normcolor; + brush.color = normcolor; cmdw = cwidth; if(cmdw && item.size) - menu->rect.width = cmdw; + brush.rect.width = cmdw; + blitz_draw_label(&brush, text); } else { cmdw = twidth; - menu->text = title; - menu->color = selcolor; - menu->rect.width = cmdw; + brush.color = selcolor; + brush.rect.width = cmdw; + blitz_draw_label(&brush, title); } - blitz_draw_input(menu); - offx += menu->rect.width; + offx += brush.rect.width; - menu->align = CENTER; + brush.align = CENTER; if(item.size) { - menu->color = normcolor; - menu->text = prevoff < curroff ? "<" : nil; - menu->rect.x = offx; - menu->rect.width = seek; - offx += menu->rect.width; - blitz_draw_input(menu); + brush.color = normcolor; + brush.rect.x = offx; + brush.rect.width = seek; + offx += brush.rect.width; + blitz_draw_label(&brush, prevoff < curroff ? "<" : nil); /* determine maximum items */ for(i = curroff; i < nextoff; i++) { - menu->text = item.data[i]; - menu->rect.x = offx; - menu->rect.width = blitz_textwidth(menu->font, menu->text); - if(menu->rect.width > irect.width / 3) - menu->rect.width = irect.width / 3; - menu->rect.width += irect.height; + brush.rect.x = offx; + brush.rect.width = blitz_textwidth(brush.font, item.data[i]); + if(brush.rect.width > irect.width / 3) + brush.rect.width = irect.width / 3; + brush.rect.width += irect.height; if(sel == i) - menu->color = selcolor; + brush.color = selcolor; else - menu->color = normcolor; - blitz_draw_input(menu); - offx += menu->rect.width; + brush.color = normcolor; + blitz_draw_label(&brush, item.data[i]); + offx += brush.rect.width; } - menu->color = normcolor; - menu->text = item.size > nextoff ? ">" : nil; - menu->rect.x = irect.width - seek; - menu->rect.width = seek; - blitz_draw_input(menu); + brush.color = normcolor; + brush.rect.x = irect.width - seek; + brush.rect.width = seek; + blitz_draw_label(&brush, item.size > nextoff ? ">" : nil); } - XCopyArea(dpy, menu->drawable, win, menu->gc, 0, 0, irect.width, + XCopyArea(blz.display, brush.drawable, win, brush.gc, 0, 0, irect.width, irect.height, 0, 0); - XSync(dpy, False); + XSync(blz.display, False); } static void @@ -368,73 +362,76 @@ main(int argc, char *argv[]) usage(); } - dpy = XOpenDisplay(0); - if(!dpy) { + blz.display = XOpenDisplay(0); + if(!blz.display) { fprintf(stderr, "%s", "wmiimenu: cannot open display\n"); exit(1); } - screen = DefaultScreen(dpy); + blz.screen = DefaultScreen(blz.display); + blz.root = RootWindow(blz.display, blz.screen); maxname = read_allitems(); /* grab as early as possible, but after reading all items!!! */ while(XGrabKeyboard - (dpy, RootWindow(dpy, screen), True, GrabModeAsync, + (blz.display, blz.root, True, GrabModeAsync, GrabModeAsync, CurrentTime) != GrabSuccess) usleep(1000); - /* set font and colors */ - blitz_x11_init(dpy); - font.fontstr = getenv("WMII_FONT"); if (!font.fontstr) font.fontstr = strdup(BLITZ_FONT); - blitz_loadfont(&font); + blitz_loadfont(&blz, &font); if((p = getenv("WMII_NORMCOLORS"))) cext_strlcpy(normcolor.colstr, p, sizeof(normcolor.colstr)); if(strlen(normcolor.colstr) != 23) cext_strlcpy(normcolor.colstr, BLITZ_NORMCOLORS, sizeof(normcolor.colstr)); - blitz_loadcolor(&normcolor); + blitz_loadcolor(&blz, &normcolor); if((p = getenv("WMII_SELCOLORS"))) cext_strlcpy(selcolor.colstr, p, sizeof(selcolor.colstr)); if(strlen(selcolor.colstr) != 23) cext_strlcpy(selcolor.colstr, BLITZ_SELCOLORS, sizeof(selcolor.colstr)); - blitz_loadcolor(&selcolor); + blitz_loadcolor(&blz, &selcolor); wa.override_redirect = 1; wa.background_pixmap = ParentRelative; wa.event_mask = ExposureMask | ButtonPressMask | KeyPressMask | SubstructureRedirectMask | SubstructureNotifyMask; - irect.width = DisplayWidth(dpy, screen); + irect.width = DisplayWidth(blz.display, blz.screen); irect.height = font.ascent + font.descent + 4; - irect.y = DisplayHeight(dpy, screen) - irect.height; + irect.y = DisplayHeight(blz.display, blz.screen) - irect.height; irect.x = 0; - win = XCreateWindow(dpy, RootWindow(dpy, screen), irect.x, irect.y, - irect.width, irect.height, 0, DefaultDepth(dpy, screen), - CopyFromParent, DefaultVisual(dpy, screen), + win = XCreateWindow(blz.display, blz.root, irect.x, irect.y, + irect.width, irect.height, 0, DefaultDepth(blz.display, blz.screen), + CopyFromParent, DefaultVisual(blz.display, blz.screen), CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); - XDefineCursor(dpy, win, XCreateFontCursor(dpy, XC_xterm)); - XSync(dpy, False); + XDefineCursor(blz.display, win, XCreateFontCursor(blz.display, XC_xterm)); + XSync(blz.display, False); /* pixmap */ - gc = XCreateGC(dpy, win, 0, 0); - pmap = XCreatePixmap(dpy, win, irect.width, irect.height, - DefaultDepth(dpy, screen)); + gc = XCreateGC(blz.display, win, 0, 0); + pmap = XCreatePixmap(blz.display, win, irect.width, irect.height, + DefaultDepth(blz.display, blz.screen)); - XSync(dpy, False); + XSync(blz.display, False); + + brush.blitz = &blz; + brush.color = normcolor; + brush.drawable = pmap; + brush.gc = gc; + brush.font = &font; - menu = blitz_create_input(pmap, gc, &font); if(maxname) - cwidth = blitz_textwidth(menu->font, maxname) + irect.height; + cwidth = blitz_textwidth(brush.font, maxname) + irect.height; if(cwidth > irect.width / 3) cwidth = irect.width / 3; if(title) { - twidth = blitz_textwidth(menu->font, title) + irect.height; + twidth = blitz_textwidth(brush.font, title) + irect.height; if(twidth > irect.width / 3) twidth = irect.width / 3; } @@ -443,12 +440,12 @@ main(int argc, char *argv[]) text[0] = 0; update_items(text); - XMapRaised(dpy, win); + XMapRaised(blz.display, win); draw_menu(); - XSync(dpy, False); + XSync(blz.display, False); /* main event loop */ - while(!XNextEvent(dpy, &ev)) { + while(!XNextEvent(blz.display, &ev)) { switch (ev.type) { case KeyPress: handle_kpress(&ev.xkey); @@ -465,11 +462,11 @@ main(int argc, char *argv[]) break; } - XUngrabKeyboard(dpy, CurrentTime); - XFreePixmap(dpy, pmap); - XFreeGC(dpy, gc); - XDestroyWindow(dpy, win); - XCloseDisplay(dpy); + XUngrabKeyboard(blz.display, CurrentTime); + XFreePixmap(blz.display, pmap); + XFreeGC(blz.display, gc); + XDestroyWindow(blz.display, win); + XCloseDisplay(blz.display); return ret; } diff --git a/liblitz/Makefile b/liblitz/Makefile @@ -6,7 +6,7 @@ include ../config.mk CFLAGS += -I../libixp -I../libcext LDFLAGS += -L../libixp -lixp -L../libcext -lcext -SRC = blitz.c color.c font.c input.c tile.c +SRC = brush.c color.c draw.c font.c input.c OBJ = ${SRC:.c=.o} all: liblitz.a diff --git a/liblitz/blitz.c b/liblitz/blitz.c @@ -1,16 +0,0 @@ -/* - * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com> - * See LICENSE file for license details. - */ - -#include <cext.h> - -#include "blitz.h" - -void -blitz_x11_init(Display *dpy) -{ - __blitz.display = dpy; - __blitz.screen = DefaultScreen(dpy); - __blitz.root = DefaultRootWindow(dpy); -} diff --git a/liblitz/blitz.h b/liblitz/blitz.h @@ -14,7 +14,8 @@ typedef struct Blitz Blitz; typedef enum BlitzAlign BlitzAlign; typedef struct BlitzColor BlitzColor; typedef struct BlitzFont BlitzFont; -typedef struct BlitzWidget BlitzWidget; +typedef struct BlitzBrush BlitzBrush; +typedef struct BlitzInput BlitzInput; struct Blitz { Display *display; @@ -46,39 +47,50 @@ struct BlitzFont { XFontSet set; int ascent; int descent; + int rbearing; + int lbearing; char *fontstr; }; -struct BlitzWidget { +struct BlitzBrush { + Blitz *blitz; Drawable drawable; GC gc; BlitzColor color; BlitzAlign align; BlitzFont *font; XRectangle rect; /* relative rect */ - XRectangle *notch; /* relative notch rect */ - char *text; }; -Blitz __blitz; +struct BlitzInput { + Blitz *blitz; + char *text; + char *selstart; + char *selend; + char *cursor; + unsigned int size; + Drawable drawable; + GC gc; + BlitzColor sel; + BlitzColor norm; + BlitzFont *font; + XRectangle rect; /* relative rect */ +}; -/* blitz.c */ -void blitz_x11_init(Display *dpy); -Bool blitz_x11_event(XEvent *ev); +/* brush.c */ +void blitz_draw_label(BlitzBrush *b, char *text); +void blitz_draw_tile(BlitzBrush *b); /* color.c */ -int blitz_loadcolor(BlitzColor *c); - -/* input.c */ -BlitzWidget *blitz_create_input(Drawable drawable, GC gc, BlitzFont *font); -void blitz_draw_input(BlitzWidget *i); -void blitz_destroy_input(BlitzWidget *i); +int blitz_loadcolor(Blitz *blitz, BlitzColor *c); -/* tile.c */ -BlitzWidget *blitz_create_tile(Drawable drawable, GC gc); -void blitz_draw_tile(BlitzWidget *t); -void blitz_destroy_tile(BlitzWidget *t); +void blitz_drawbg(Display *dpy, Drawable drawable, GC gc, + XRectangle rect, BlitzColor c); /* font.c */ unsigned int blitz_textwidth(BlitzFont *font, char *text); -void blitz_loadfont(BlitzFont *font); +void blitz_loadfont(Blitz *blitz, BlitzFont *font); + +/* input.c */ +void blitz_draw_input(BlitzInput *i); +char *blitz_charof(BlitzInput *i, int x, int y); diff --git a/liblitz/brush.c b/liblitz/brush.c @@ -0,0 +1,81 @@ +/* + * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com> + * See LICENSE file for license details. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <cext.h> +#include "blitz.h" + +void +blitz_draw_tile(BlitzBrush *b) +{ + blitz_drawbg(b->blitz->display, b->drawable, b->gc, b->rect, b->color); +} + +void +blitz_draw_label(BlitzBrush *b, char *text) +{ + unsigned int x, y, w, h, shortened, len; + static char buf[2048]; + XGCValues gcv; + + blitz_draw_tile(b); + + if (!text) + return; + + x = y = shortened = 0; + w = h = 1; + cext_strlcpy(buf, text, sizeof(buf)); + len = strlen(buf); + gcv.foreground = b->color.fg; + gcv.background = b->color.bg; + if(b->font->set) + XChangeGC(b->blitz->display, b->gc, GCForeground | GCBackground, &gcv); + else { + gcv.font = b->font->xfont->fid; + XChangeGC(b->blitz->display, b->gc, GCForeground | GCBackground | GCFont, &gcv); + } + + h = b->font->ascent + b->font->descent; + y = b->rect.y + b->rect.height / 2 - h / 2 + b->font->ascent; + + /* shorten text if necessary */ + while (len && (w = blitz_textwidth(b->font, buf)) > b->rect.width) { + buf[len - 1] = 0; + len--; + shortened = 1; + } + + if (w > b->rect.width) + return; + + /* mark shortened info in the string */ + if (shortened) { + if (len > 3) + buf[len - 3] = '.'; + if (len > 2) + buf[len - 2] = '.'; + if (len > 1) + buf[len - 1] = '.'; + } + switch (b->align) { + case EAST: + x = b->rect.x + b->rect.width - (h / 2 + w); + break; + case CENTER: + x = b->rect.x + (b->rect.width - w) / 2; + break; + default: + x = b->rect.x + h / 2; + break; + } + if(b->font->set) + XmbDrawImageString(b->blitz->display, b->drawable, b->font->set, b->gc, + x, y, buf, len); + else + XDrawImageString(b->blitz->display, b->drawable, b->gc, x, y, buf, len); +} diff --git a/liblitz/color.c b/liblitz/color.c @@ -9,26 +9,26 @@ #include "blitz.h" static unsigned long -xloadcolor(char *colstr) +xloadcolor(Blitz *blitz, char *colstr) { XColor color; char col[8]; cext_strlcpy(col, colstr, sizeof(col)); col[7] = 0; - XAllocNamedColor(__blitz.display, - DefaultColormap(__blitz.display, __blitz.screen), col, &color, &color); + XAllocNamedColor(blitz->display, + DefaultColormap(blitz->display, blitz->screen), col, &color, &color); return color.pixel; } int -blitz_loadcolor(BlitzColor *c) +blitz_loadcolor(Blitz *blitz, BlitzColor *c) { if(!c->colstr || strlen(c->colstr) != 23) return -1; - c->fg = xloadcolor(&c->colstr[0]); - c->bg = xloadcolor(&c->colstr[8]); - c->border = xloadcolor(&c->colstr[16]); + c->fg = xloadcolor(blitz, &c->colstr[0]); + c->bg = xloadcolor(blitz, &c->colstr[8]); + c->border = xloadcolor(blitz, &c->colstr[16]); return 0; } diff --git a/liblitz/draw.c b/liblitz/draw.c @@ -0,0 +1,27 @@ +/* + * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com> + * See LICENSE file for license details. + */ + +#include "blitz.h" + +void +blitz_drawbg(Display *dpy, Drawable drawable, GC gc, XRectangle rect, BlitzColor c) +{ + XPoint points[5]; + XSetForeground(dpy, gc, c.bg); + XFillRectangles(dpy, drawable, gc, &rect, 1); + XSetLineAttributes(dpy, gc, 1, LineSolid, CapButt, JoinMiter); + XSetForeground(dpy, gc, c.border); + points[0].x = rect.x; + points[0].y = rect.y; + points[1].x = rect.width - 1; + points[1].y = 0; + points[2].x = 0; + points[2].y = rect.height - 1; + points[3].x = -(rect.width - 1); + points[3].y = 0; + points[4].x = 0; + points[4].y = -(rect.height - 1); + XDrawLines(dpy, drawable, gc, points, 5, CoordModePrevious); +} diff --git a/liblitz/font.c b/liblitz/font.c @@ -23,7 +23,7 @@ blitz_textwidth(BlitzFont *font, char *text) } void -blitz_loadfont(BlitzFont *font) +blitz_loadfont(Blitz *blitz, BlitzFont *font) { char *fontname = font->fontstr; char **missing = nil, *def = "?"; @@ -31,14 +31,14 @@ blitz_loadfont(BlitzFont *font) setlocale(LC_ALL, ""); if(font->set) - XFreeFontSet(__blitz.display, font->set); - font->set = XCreateFontSet(__blitz.display, fontname, &missing, &n, &def); + XFreeFontSet(blitz->display, font->set); + font->set = XCreateFontSet(blitz->display, fontname, &missing, &n, &def); if(missing) { while(n--) fprintf(stderr, "liblitz: missing fontset: %s\n", missing[n]); XFreeStringList(missing); if(font->set) { - XFreeFontSet(__blitz.display, font->set); + XFreeFontSet(blitz->display, font->set); font->set = nil; } } @@ -56,17 +56,21 @@ blitz_loadfont(BlitzFont *font) font->ascent = (*xfonts)->ascent; if(font->descent < (*xfonts)->descent) font->descent = (*xfonts)->descent; + if(font->rbearing < (*xfonts)->max_bounds.rbearing) + font->rbearing = (*xfonts)->max_bounds.rbearing; + if(font->lbearing < (*xfonts)->min_bounds.lbearing) + font->lbearing = (*xfonts)->min_bounds.lbearing; xfonts++; } } else { if(font->xfont) - XFreeFont(__blitz.display, font->xfont); + XFreeFont(blitz->display, font->xfont); font->xfont = nil; - font->xfont = XLoadQueryFont(__blitz.display, fontname); + font->xfont = XLoadQueryFont(blitz->display, fontname); if (!font->xfont) { fontname = "fixed"; - font->xfont = XLoadQueryFont(__blitz.display, fontname); + font->xfont = XLoadQueryFont(blitz->display, fontname); } if (!font->xfont) { fprintf(stderr, "%s", "liblitz: error, cannot load 'fixed' font\n"); @@ -74,5 +78,7 @@ blitz_loadfont(BlitzFont *font) } font->ascent = font->xfont->ascent; font->descent = font->xfont->descent; + font->rbearing = font->xfont->max_bounds.rbearing; + font->lbearing = font->xfont->min_bounds.lbearing; } } diff --git a/liblitz/input.c b/liblitz/input.c @@ -3,87 +3,105 @@ * See LICENSE file for license details. */ +#include <stdio.h> #include <stdlib.h> #include <string.h> #include <cext.h> #include "blitz.h" -BlitzWidget * -blitz_create_input(Drawable drawable, GC gc, BlitzFont *font) +static void +xchangegc(BlitzInput *i, BlitzColor *c, Bool invert) { - BlitzWidget *i = cext_emallocz(sizeof(BlitzWidget)); - i->drawable = drawable; - i->gc = gc; - i->font = font; - return i; -} - -void -blitz_draw_input(BlitzWidget *i) -{ - unsigned int x, y, w, h, shortened, len; - static char text[2048]; XGCValues gcv; - blitz_draw_tile(i); - - if (!i->text) - return; - - x = y = shortened = 0; - w = h = 1; - cext_strlcpy(text, i->text, sizeof(text)); - len = strlen(text); - gcv.foreground = i->color.fg; - gcv.background = i->color.bg; + if(invert) { + gcv.foreground = c->bg; + gcv.background = c->fg; + } + else { + gcv.foreground = c->fg; + gcv.background = c->bg; + } if(i->font->set) - XChangeGC(__blitz.display, i->gc, GCForeground | GCBackground, &gcv); + XChangeGC(i->blitz->display, i->gc, GCForeground | GCBackground, &gcv); else { gcv.font = i->font->xfont->fid; - XChangeGC(__blitz.display, i->gc, GCForeground | GCBackground | GCFont, &gcv); + XChangeGC(i->blitz->display, i->gc, GCForeground | GCBackground | GCFont, &gcv); } +} - h = i->font->ascent + i->font->descent; - y = i->rect.y + i->rect.height / 2 - h / 2 + i->font->ascent; +static void +xdrawtextpart(BlitzInput *i, BlitzColor *c, char *start, char *end, + int *xoff, int yoff, unsigned int boxw) +{ + char *p, buf[2]; - /* shorten text if necessary */ - while (len && (w = blitz_textwidth(i->font, text)) > i->rect.width) { - text[len - 1] = 0; - len--; - shortened = 1; + xchangegc(i, c, False); + buf[1] = 0; + for(p = start; p && *p && p != end; p++) { + *buf = *p; + if(p == i->cursor) + xchangegc(i, c, True); + if(i->font->set) + XmbDrawImageString(i->blitz->display, i->drawable, i->font->set, i->gc, + *xoff, yoff, buf, 1); + else + XDrawImageString(i->blitz->display, i->drawable, i->gc, *xoff, yoff, + buf, 1); + *xoff += boxw; + if(p == i->cursor) + xchangegc(i, c, False); } +} - if (w > i->rect.width) - return; - /* mark shortened info in the string */ - if (shortened) { - if (len > 3) - text[len - 3] = '.'; - if (len > 2) - text[len - 2] = '.'; - if (len > 1) - text[len - 1] = '.'; - } - switch (i->align) { - case EAST: - x = i->rect.x + i->rect.width - (h / 2 + w); - break; - case CENTER: - x = i->rect.x + (i->rect.width - w) / 2; - break; - default: - x = i->rect.x + h / 2; - break; - } - if(i->font->set) - XmbDrawString(__blitz.display, i->drawable, i->font->set, i->gc, x, y, text, len); - else - XDrawString(__blitz.display, i->drawable, i->gc, x, y, text, len); +void +xget_fontmetric(BlitzInput *i, int *x, int *y, unsigned int *w, unsigned int *h) +{ + *w = i->font->rbearing - i->font->lbearing; + *h = i->font->ascent + i->font->descent; + *x = i->rect.x; + *y = i->rect.y + i->rect.height / 2 - *h / 2 + i->font->ascent; } void -blitz_destroy_input(BlitzWidget *i) +blitz_draw_input(BlitzInput *i) { - free(i); + int xoff, yoff; + unsigned int boxw, boxh, nbox; + + if (!i) + return; + + blitz_drawbg(i->blitz->display, i->drawable, i->gc, i->rect, i->norm); + xget_fontmetric(i, &xoff, &yoff, &boxw, &boxh); + nbox = i->rect.width / boxw; + + /* draw normal text */ + xdrawtextpart(i, &i->norm, i->text, i->selstart, &xoff, yoff, boxw); + /* draw sel text */ + xdrawtextpart(i, &i->sel, i->selstart, i->selend, &xoff, yoff, boxw); + /* draw remaining normal text */ + xdrawtextpart(i, &i->norm, i->selend, nil, &xoff, yoff, boxw); +} + +char * +blitz_charof(BlitzInput *i, int x, int y) +{ + int xoff, yoff; + unsigned int boxw, boxh, nbox, cbox, l; + + if(!i->text || (y < i->rect.y) || (y > i->rect.y + i->rect.height)) + return nil; + xget_fontmetric(i, &xoff, &yoff, &boxw, &boxh); + nbox = i->rect.width / boxw; + cbox = (x - i->rect.x) / boxw; + + if(cbox > nbox) + return nil; + + if((l = strlen(i->text)) > cbox) + return i->text + cbox; + else + return i->text + l; } diff --git a/liblitz/tile.c b/liblitz/tile.c @@ -1,44 +0,0 @@ -/* - * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com> - * See LICENSE file for license details. - */ - -#include <stdlib.h> -#include <cext.h> -#include "blitz.h" - -BlitzWidget * -blitz_create_tile(Drawable drawable, GC gc) -{ - BlitzWidget *t = cext_emallocz(sizeof(BlitzWidget)); - t->drawable = drawable; - t->gc = gc; - return t; -} - -void -blitz_draw_tile(BlitzWidget *t) -{ - XPoint points[5]; - XSetForeground(__blitz.display, t->gc, t->color.bg); - XFillRectangles(__blitz.display, t->drawable, t->gc, &t->rect, 1); - XSetLineAttributes(__blitz.display, t->gc, 1, LineSolid, CapButt, JoinMiter); - XSetForeground(__blitz.display, t->gc, t->color.border); - points[0].x = t->rect.x; - points[0].y = t->rect.y; - points[1].x = t->rect.width - 1; - points[1].y = 0; - points[2].x = 0; - points[2].y = t->rect.height - 1; - points[3].x = -(t->rect.width - 1); - points[3].y = 0; - points[4].x = 0; - points[4].y = -(t->rect.height - 1); - XDrawLines(__blitz.display, t->drawable, t->gc, points, 5, CoordModePrevious); -} - -void -blitz_destroy_tile(BlitzWidget *t) -{ - free(t); -}