jcs ratpoison hax
at oldjcs 314 lines 7.3 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(xinescreen); 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_xinescreen }, 76 { 0, NULL } 77}; 78 79/* if width >= 0 then limit the width of s to width chars. */ 80static void 81concat_width (struct sbuf *buf, char *s, int width) 82{ 83 if (width >= 0) 84 { 85 char *s1 = xsprintf ("%%.%ds", width); 86 char *s2 = xsprintf (s1, s); 87 sbuf_concat (buf, s2); 88 free (s1); 89 free (s2); 90 } 91 else 92 sbuf_concat (buf, s); 93} 94 95void 96format_string (char *fmt, rp_window_elem *win_elem, struct sbuf *buffer) 97{ 98#define STATE_READ 0 99#define STATE_NUMBER 1 100#define STATE_ESCAPE 2 101 int state = STATE_READ; 102 char dbuf[10]; 103 int width = -1; 104 struct sbuf *retbuf; 105 int fip, found; 106 107 retbuf = sbuf_new (0); 108 109 for(; *fmt; fmt++) 110 { 111 if (*fmt == '%' && state == STATE_READ) 112 { 113 state = STATE_ESCAPE; 114 continue; 115 } 116 117 if ((state == STATE_ESCAPE || state == STATE_NUMBER) && isdigit(*fmt)) 118 { 119 /* Accumulate the width one digit at a time. */ 120 if (state == STATE_ESCAPE) 121 width = 0; 122 width *= 10; 123 width += *fmt - '0'; 124 state = STATE_NUMBER; 125 continue; 126 } 127 128 found = 0; 129 if (state == STATE_ESCAPE || state == STATE_NUMBER) 130 { 131 if (*fmt == '%') 132 sbuf_concat (buffer, "%"); 133 else 134 { 135 for (fip = 0; fmt_items[fip].fmt_char; fip++) 136 { 137 if (fmt_items[fip].fmt_char == *fmt) 138 { 139 sbuf_clear (retbuf); 140 fmt_items[fip].fmt_fn(win_elem, retbuf); 141 concat_width (buffer, sbuf_get (retbuf), width); 142 found = 1; 143 break; 144 } 145 } 146 if (!found) 147 { 148 sbuf_printf_concat (buffer, "%%%c", *fmt); 149 break; 150 } 151 } 152 state = STATE_READ; 153 width = -1; 154 } 155 else 156 { 157 /* Insert the character. */ 158 dbuf[0] = *fmt; 159 dbuf[1] = 0; 160 sbuf_concat (buffer, dbuf); 161 } 162 } 163 sbuf_free (retbuf); 164#undef STATE_READ 165#undef STATE_ESCAPE 166#undef STATE_NUMBER 167} 168 169static void 170fmt_framenum (rp_window_elem *win_elem, struct sbuf *buf) 171{ 172 if (win_elem->win->frame_number != EMPTY) 173 { 174 sbuf_printf_concat (buf, "%d", win_elem->win->frame_number); 175 } 176 else 177 sbuf_copy (buf, " "); 178} 179 180static void 181fmt_lastaccess (rp_window_elem *win_elem, struct sbuf *buf) 182{ 183 sbuf_printf_concat (buf, "%d", win_elem->win->last_access); 184} 185 186static void 187fmt_name (rp_window_elem *win_elem, struct sbuf *buf) 188{ 189 sbuf_copy(buf, window_name (win_elem->win)); 190} 191 192static void 193fmt_number (rp_window_elem *win_elem, struct sbuf *buf) 194{ 195 sbuf_printf_concat (buf, "%d", win_elem->number); 196} 197 198static void 199fmt_resname (rp_window_elem *win_elem, struct sbuf *buf) 200{ 201 if (win_elem->win->res_name) 202 sbuf_copy (buf, win_elem->win->res_name); 203 else 204 sbuf_copy (buf, "None"); 205} 206 207static void 208fmt_resclass (rp_window_elem *win_elem, struct sbuf *buf) 209{ 210 if (win_elem->win->res_class) 211 sbuf_copy (buf, win_elem->win->res_class); 212 else 213 sbuf_copy (buf, "None"); 214} 215 216static void 217fmt_status (rp_window_elem *win_elem, struct sbuf *buf) 218{ 219 rp_window *other_window; 220 221 other_window = find_window_other (current_screen()); 222 if (win_elem->win == other_window) 223 sbuf_copy (buf, "+"); 224 else if (win_elem->win == current_window()) 225 sbuf_copy (buf, "*"); 226 else 227 sbuf_copy (buf, "-"); 228} 229 230static void 231fmt_windowid (rp_window_elem *elem, struct sbuf *buf) 232{ 233 sbuf_printf_concat (buf, "%ld", (unsigned long)elem->win->w); 234} 235 236static void 237fmt_height (rp_window_elem *elem, struct sbuf *buf) 238{ 239 sbuf_printf_concat (buf, "%d", elem->win->height); 240} 241 242static void 243fmt_width (rp_window_elem *elem, struct sbuf *buf) 244{ 245 sbuf_printf_concat (buf, "%d", elem->win->width); 246} 247 248static void 249fmt_incheight (rp_window_elem *elem, struct sbuf *buf) 250{ 251 int height; 252 height = elem->win->height; 253 254 if (elem->win->hints->flags & PResizeInc) 255 height /= elem->win->hints->height_inc; 256 257 sbuf_printf_concat (buf, "%d", height); 258} 259 260static void 261fmt_incwidth (rp_window_elem *elem, struct sbuf *buf) 262{ 263 int width; 264 width = elem->win->width; 265 266 if (elem->win->hints->flags & PResizeInc) 267 width /= elem->win->hints->width_inc; 268 269 sbuf_printf_concat (buf, "%d", width); 270} 271 272static void 273fmt_gravity (rp_window_elem *elem, struct sbuf *buf) 274{ 275 sbuf_copy (buf, wingravity_to_string (elem->win->gravity)); 276} 277 278static void 279fmt_screen (rp_window_elem *elem, struct sbuf *buf) 280{ 281 sbuf_printf_concat (buf, "%d", elem->win->scr->screen_num); 282} 283 284static void 285fmt_xinescreen (rp_window_elem *elem, struct sbuf *buf) 286{ 287 sbuf_printf_concat (buf, "%d", elem->win->scr->xine_screen_num); 288} 289 290static void 291fmt_transient (rp_window_elem *elem, struct sbuf *buf) 292{ 293 if (elem->win->transient) 294 sbuf_concat (buf, "Transient"); 295} 296 297static void 298fmt_maxsize (rp_window_elem *elem, struct sbuf *buf) 299{ 300 if (elem->win->hints->flags & PMaxSize) 301 sbuf_concat (buf, "Maxsize"); 302} 303 304static void 305fmt_pid (rp_window_elem *elem, struct sbuf *buf) 306{ 307 struct rp_child_info *info; 308 309 info = get_child_info (elem->win->w); 310 if (info) 311 sbuf_printf_concat (buf, "%d", info->pid); 312 else 313 sbuf_concat (buf, "?"); 314}