jcs ratpoison hax
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}