A tiling window manager
at master 284 lines 6.3 kB view raw
1/* 2 * Copyright (C) 2006 Antti Nyk�nen <aon@iki.fi> 3 * 4 * This program is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License as published by the Free 6 * Software Foundation; either version 2 of the License, or (at your option) 7 * any later version. 8 * 9 * This program is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 * more details. 13 * 14 * You should have received a copy of the GNU General Public License along with 15 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple 16 * Place, Suite 330, Boston, MA 02111-1307 USA. 17 */ 18 19#include <ctype.h> 20#include <stdio.h> 21#include <stdlib.h> 22#include <string.h> 23#include "sdorfehs.h" 24 25/* Function prototypes for format char expanders. */ 26#define RP_FMT(fn) static void fmt_ ## fn (rp_window_elem *elem, struct sbuf *buf) 27RP_FMT(framenum); 28RP_FMT(lastaccess); 29RP_FMT(name); 30RP_FMT(number); 31RP_FMT(resname); 32RP_FMT(resclass); 33RP_FMT(status); 34RP_FMT(windowid); 35RP_FMT(height); 36RP_FMT(width); 37RP_FMT(incheight); 38RP_FMT(incwidth); 39RP_FMT(gravity); 40RP_FMT(screen); 41RP_FMT(xrandrscreen); 42RP_FMT(transient); 43RP_FMT(maxsize); 44RP_FMT(pid); 45 46struct fmt_item { 47 /* The format character */ 48 char fmt_char; 49 50 /* Callback to return the expanded string. */ 51 void (*fmt_fn) (rp_window_elem *, struct sbuf *); 52}; 53 54struct fmt_item fmt_items[] = { 55 {'a', fmt_resname}, 56 {'g', fmt_gravity}, 57 {'h', fmt_height}, 58 {'H', fmt_incheight}, 59 {'c', fmt_resclass}, 60 {'f', fmt_framenum}, 61 {'i', fmt_windowid}, 62 {'l', fmt_lastaccess}, 63 {'M', fmt_maxsize}, 64 {'n', fmt_number}, 65 {'p', fmt_pid}, 66 {'s', fmt_status}, 67 {'S', fmt_screen}, 68 {'t', fmt_name}, 69 {'T', fmt_transient}, 70 {'w', fmt_width}, 71 {'W', fmt_incwidth}, 72 {'x', fmt_xrandrscreen}, 73 {0, NULL} 74}; 75 76void 77format_string(char *fmt, rp_window_elem *win_elem, struct sbuf *buffer) 78{ 79#define STATE_READ 0 80#define STATE_NUMBER 1 81#define STATE_ESCAPE 2 82 int state = STATE_READ; 83 char dbuf[10]; 84 int width = -1; 85 struct sbuf *retbuf; 86 int fip, found; 87 88 retbuf = sbuf_new(0); 89 90 for (; *fmt; fmt++) { 91 if (*fmt == '%' && state == STATE_READ) { 92 state = STATE_ESCAPE; 93 continue; 94 } 95 if ((state == STATE_ESCAPE || state == STATE_NUMBER) && 96 isdigit(*fmt)) { 97 /* Accumulate the width one digit at a time. */ 98 if (state == STATE_ESCAPE) 99 width = 0; 100 width *= 10; 101 width += *fmt - '0'; 102 state = STATE_NUMBER; 103 continue; 104 } 105 found = 0; 106 if (state == STATE_ESCAPE || state == STATE_NUMBER) { 107 if (*fmt == '%') 108 sbuf_concat(buffer, "%"); 109 else { 110 for (fip = 0; fmt_items[fip].fmt_char; fip++) { 111 if (fmt_items[fip].fmt_char == *fmt) { 112 sbuf_clear(retbuf); 113 fmt_items[fip].fmt_fn(win_elem, 114 retbuf); 115 sbuf_utf8_nconcat(buffer, 116 sbuf_get(retbuf), width); 117 found = 1; 118 break; 119 } 120 } 121 if (!found) { 122 sbuf_printf_concat(buffer, "%%%c", *fmt); 123 break; 124 } 125 } 126 state = STATE_READ; 127 width = -1; 128 } else { 129 /* Insert the character. */ 130 dbuf[0] = *fmt; 131 dbuf[1] = 0; 132 sbuf_concat(buffer, dbuf); 133 } 134 } 135 sbuf_free(retbuf); 136#undef STATE_READ 137#undef STATE_ESCAPE 138#undef STATE_NUMBER 139} 140 141static void 142fmt_framenum(rp_window_elem *win_elem, struct sbuf *buf) 143{ 144 if (win_elem->win->frame_number != EMPTY) { 145 sbuf_printf_concat(buf, "%d", win_elem->win->frame_number); 146 } else 147 sbuf_copy(buf, " "); 148} 149 150static void 151fmt_lastaccess(rp_window_elem *win_elem, struct sbuf *buf) 152{ 153 sbuf_printf_concat(buf, "%d", win_elem->win->last_access); 154} 155 156static void 157fmt_name(rp_window_elem *win_elem, struct sbuf *buf) 158{ 159 sbuf_copy(buf, window_name(win_elem->win)); 160} 161 162static void 163fmt_number(rp_window_elem *win_elem, struct sbuf *buf) 164{ 165 sbuf_printf_concat(buf, "%d", win_elem->number); 166} 167 168static void 169fmt_resname(rp_window_elem *win_elem, struct sbuf *buf) 170{ 171 if (win_elem->win->res_name) 172 sbuf_copy(buf, win_elem->win->res_name); 173 else 174 sbuf_copy(buf, "None"); 175} 176 177static void 178fmt_resclass(rp_window_elem *win_elem, struct sbuf *buf) 179{ 180 if (win_elem->win->res_class) 181 sbuf_copy(buf, win_elem->win->res_class); 182 else 183 sbuf_copy(buf, "None"); 184} 185 186static void 187fmt_status(rp_window_elem *win_elem, struct sbuf *buf) 188{ 189 rp_window *other_window; 190 191 other_window = find_window_other(rp_current_vscreen); 192 if (win_elem->win == other_window) 193 sbuf_copy(buf, "+"); 194 else if (win_elem->win == current_window()) 195 sbuf_copy(buf, "*"); 196 else 197 sbuf_copy(buf, "-"); 198} 199 200static void 201fmt_windowid(rp_window_elem *elem, struct sbuf *buf) 202{ 203 sbuf_printf_concat(buf, "%ld", (unsigned long) elem->win->w); 204} 205 206static void 207fmt_height(rp_window_elem *elem, struct sbuf *buf) 208{ 209 sbuf_printf_concat(buf, "%d", elem->win->height); 210} 211 212static void 213fmt_width(rp_window_elem *elem, struct sbuf *buf) 214{ 215 sbuf_printf_concat(buf, "%d", elem->win->width); 216} 217 218static void 219fmt_incheight(rp_window_elem *elem, struct sbuf *buf) 220{ 221 int height; 222 height = elem->win->height; 223 224 if (elem->win->hints->flags & PResizeInc) 225 height /= elem->win->hints->height_inc; 226 227 sbuf_printf_concat(buf, "%d", height); 228} 229 230static void 231fmt_incwidth(rp_window_elem *elem, struct sbuf *buf) 232{ 233 int width; 234 width = elem->win->width; 235 236 if (elem->win->hints->flags & PResizeInc) 237 width /= elem->win->hints->width_inc; 238 239 sbuf_printf_concat(buf, "%d", width); 240} 241 242static void 243fmt_gravity(rp_window_elem *elem, struct sbuf *buf) 244{ 245 sbuf_copy(buf, wingravity_to_string(elem->win->gravity)); 246} 247 248static void 249fmt_screen(rp_window_elem *elem, struct sbuf *buf) 250{ 251 sbuf_printf_concat(buf, "%d", elem->win->vscreen->screen->screen_num); 252} 253 254static void 255fmt_xrandrscreen(rp_window_elem *elem, struct sbuf *buf) 256{ 257 sbuf_printf_concat(buf, "%d", elem->win->vscreen->screen->xrandr.output); 258} 259 260static void 261fmt_transient(rp_window_elem *elem, struct sbuf *buf) 262{ 263 if (elem->win->transient) 264 sbuf_concat(buf, "Transient"); 265} 266 267static void 268fmt_maxsize(rp_window_elem *elem, struct sbuf *buf) 269{ 270 if (elem->win->hints->flags & PMaxSize) 271 sbuf_concat(buf, "Maxsize"); 272} 273 274static void 275fmt_pid(rp_window_elem *elem, struct sbuf *buf) 276{ 277 struct rp_child_info *info; 278 279 info = get_child_info(elem->win->w, 0); 280 if (info) 281 sbuf_printf_concat(buf, "%d", info->pid); 282 else 283 sbuf_concat(buf, "?"); 284}