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