summaryrefslogtreecommitdiff
path: root/src/format.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/format.c')
-rw-r--r--src/format.c291
1 files changed, 291 insertions, 0 deletions
diff --git a/src/format.c b/src/format.c
new file mode 100644
index 0000000..bbe463c
--- /dev/null
+++ b/src/format.c
@@ -0,0 +1,291 @@
+/*
+ * Copyright (C) 2006 Antti Nykänen <aon@iki.fi>
+ *
+ * This file is part of ratpoison.
+ *
+ * ratpoison is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * ratpoison is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this software; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307 USA
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "ratpoison.h"
+
+/* Function prototypes for format char expanders. */
+#define RP_FMT(fn) static void fmt_ ## fn (rp_window_elem *elem, struct sbuf *buf)
+RP_FMT(framenum);
+RP_FMT(lastaccess);
+RP_FMT(name);
+RP_FMT(number);
+RP_FMT(resname);
+RP_FMT(resclass);
+RP_FMT(status);
+RP_FMT(windowid);
+RP_FMT(height);
+RP_FMT(width);
+RP_FMT(incheight);
+RP_FMT(incwidth);
+RP_FMT(gravity);
+RP_FMT(screen);
+RP_FMT(xinescreen);
+RP_FMT(transient);
+
+struct fmt_item {
+ /* The format character */
+ char fmt_char;
+
+ /* Callback to return the expanded string. */
+ void (*fmt_fn)(rp_window_elem *, struct sbuf *);
+};
+
+struct fmt_item fmt_items[] = {
+ { 'a', fmt_resname },
+ { 'g', fmt_gravity },
+ { 'h', fmt_height },
+ { 'H', fmt_incheight },
+ { 'c', fmt_resclass },
+ { 'f', fmt_framenum },
+ { 'i', fmt_windowid },
+ { 'l', fmt_lastaccess },
+ { 'n', fmt_number },
+ { 's', fmt_status },
+ { 'S', fmt_screen },
+ { 't', fmt_name },
+ { 'T', fmt_transient },
+ { 'w', fmt_width },
+ { 'W', fmt_incwidth },
+ { 'x', fmt_xinescreen },
+ { 0, NULL }
+};
+
+/* if width >= 0 then limit the width of s to width chars. */
+static void
+concat_width (struct sbuf *buf, char *s, int width)
+{
+ if (width >= 0)
+ {
+ char *s1 = xsprintf ("%%.%ds", width);
+ char *s2 = xsprintf (s1, s);
+ sbuf_concat (buf, s2);
+ free (s1);
+ free (s2);
+ }
+ else
+ sbuf_concat (buf, s);
+}
+
+void
+format_string (char *fmt, rp_window_elem *win_elem, struct sbuf *buffer)
+{
+#define STATE_READ 0
+#define STATE_NUMBER 1
+#define STATE_ESCAPE 2
+ int state = STATE_READ;
+ char dbuf[10];
+ int width = -1;
+ struct sbuf *retbuf;
+ int fip, found;
+
+ retbuf = sbuf_new (0);
+
+ for(; *fmt; fmt++)
+ {
+ if (*fmt == '%' && state == STATE_READ)
+ {
+ state = STATE_ESCAPE;
+ continue;
+ }
+
+ if ((state == STATE_ESCAPE || state == STATE_NUMBER) && isdigit(*fmt))
+ {
+ /* Accumulate the width one digit at a time. */
+ if (state == STATE_ESCAPE)
+ width = 0;
+ width *= 10;
+ width += *fmt - '0';
+ state = STATE_NUMBER;
+ continue;
+ }
+
+ found = 0;
+ if (state == STATE_ESCAPE || state == STATE_NUMBER)
+ {
+ if (*fmt == '%')
+ sbuf_concat (buffer, "%");
+ else
+ {
+ for (fip = 0; fmt_items[fip].fmt_char; fip++)
+ {
+ if (fmt_items[fip].fmt_char == *fmt)
+ {
+ sbuf_clear (retbuf);
+ fmt_items[fip].fmt_fn(win_elem, retbuf);
+ concat_width (buffer, sbuf_get (retbuf), width);
+ found = 1;
+ break;
+ }
+ }
+ if (!found)
+ {
+ sbuf_printf_concat (buffer, "%%%c", *fmt);
+ break;
+ }
+ }
+ state = STATE_READ;
+ width = -1;
+ }
+ else
+ {
+ /* Insert the character. */
+ dbuf[0] = *fmt;
+ dbuf[1] = 0;
+ sbuf_concat (buffer, dbuf);
+ }
+ }
+ sbuf_free (retbuf);
+#undef STATE_READ
+#undef STATE_ESCAPE
+#undef STATE_NUMBER
+}
+
+static void
+fmt_framenum (rp_window_elem *win_elem, struct sbuf *buf)
+{
+ if (win_elem->win->frame_number != EMPTY)
+ {
+ sbuf_printf_concat (buf, "%d", win_elem->win->frame_number);
+ }
+ else
+ sbuf_copy (buf, " ");
+}
+
+static void
+fmt_lastaccess (rp_window_elem *win_elem, struct sbuf *buf)
+{
+ sbuf_printf_concat (buf, "%d", win_elem->win->last_access);
+}
+
+static void
+fmt_name (rp_window_elem *win_elem, struct sbuf *buf)
+{
+ sbuf_copy(buf, window_name (win_elem->win));
+}
+
+static void
+fmt_number (rp_window_elem *win_elem, struct sbuf *buf)
+{
+ sbuf_printf_concat (buf, "%d", win_elem->number);
+}
+
+static void
+fmt_resname (rp_window_elem *win_elem, struct sbuf *buf)
+{
+ if (win_elem->win->res_name)
+ sbuf_copy (buf, win_elem->win->res_name);
+ else
+ sbuf_copy (buf, "None");
+}
+
+static void
+fmt_resclass (rp_window_elem *win_elem, struct sbuf *buf)
+{
+ if (win_elem->win->res_class)
+ sbuf_copy (buf, win_elem->win->res_class);
+ else
+ sbuf_copy (buf, "None");
+}
+
+static void
+fmt_status (rp_window_elem *win_elem, struct sbuf *buf)
+{
+ rp_window *other_window;
+
+ other_window = find_window_other (current_screen());
+ if (win_elem->win == other_window)
+ sbuf_copy (buf, "+");
+ else if (win_elem->win == current_window())
+ sbuf_copy (buf, "*");
+ else
+ sbuf_copy (buf, "-");
+}
+
+static void
+fmt_windowid (rp_window_elem *elem, struct sbuf *buf)
+{
+ sbuf_printf_concat (buf, "%ld", (unsigned long)elem->win->w);
+}
+
+static void
+fmt_height (rp_window_elem *elem, struct sbuf *buf)
+{
+ sbuf_printf_concat (buf, "%d", elem->win->height);
+}
+
+static void
+fmt_width (rp_window_elem *elem, struct sbuf *buf)
+{
+ sbuf_printf_concat (buf, "%d", elem->win->width);
+}
+
+static void
+fmt_incheight (rp_window_elem *elem, struct sbuf *buf)
+{
+ int height;
+ height = elem->win->height;
+
+ if (elem->win->hints->flags & PResizeInc)
+ height /= elem->win->hints->height_inc;
+
+ sbuf_printf_concat (buf, "%d", height);
+}
+
+static void
+fmt_incwidth (rp_window_elem *elem, struct sbuf *buf)
+{
+ int width;
+ width = elem->win->width;
+
+ if (elem->win->hints->flags & PResizeInc)
+ width /= elem->win->hints->width_inc;
+
+ sbuf_printf_concat (buf, "%d", width);
+}
+
+static void
+fmt_gravity (rp_window_elem *elem, struct sbuf *buf)
+{
+ sbuf_copy (buf, wingravity_to_string (elem->win->gravity));
+}
+
+static void
+fmt_screen (rp_window_elem *elem, struct sbuf *buf)
+{
+ sbuf_printf_concat (buf, "%d", elem->win->scr->screen_num);
+}
+
+static void
+fmt_xinescreen (rp_window_elem *elem, struct sbuf *buf)
+{
+ sbuf_printf_concat (buf, "%d", elem->win->scr->xine_screen_num);
+}
+
+static void
+fmt_transient (rp_window_elem *elem, struct sbuf *buf)
+{
+ if (elem->win->transient)
+ sbuf_concat (buf, "Transient");
+}