Skip to content

Commit 9bfec1d

Browse files
committed
Add xinerama support
- Add a -s command line flag to set a destination screen - An unset screen (-1) defaults to the entire xcb screen without filtering - A set screen will size to fit its xinerama screen and filter by \sN,   where N is the screen number
1 parent 76c35ca commit 9bfec1d

File tree

1 file changed

+52
-10
lines changed

1 file changed

+52
-10
lines changed

bar.c

+52-10
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111

1212
#include "config.h"
1313

14+
#if XINERAMA
15+
#include <xcb/xinerama.h>
16+
#endif
17+
1418
// Here be dragons
1519

1620
#define MAX(a,b) ((a > b) ? a : b)
@@ -125,12 +129,13 @@ draw_char (int x, int align, wchar_t ch)
125129
}
126130

127131
void
128-
parse (char *text)
132+
parse (char *text, int screen)
129133
{
130134
unsigned char *p = text;
131135

132136
int pos_x = 0;
133137
int align = 0;
138+
bool is_screen = true;
134139

135140
xcb_fill_rect (clear_gc, 0, 0, bar_width, BAR_HEIGHT);
136141

@@ -140,7 +145,7 @@ parse (char *text)
140145
if (*p == '\n')
141146
return;
142147

143-
if (*p == '\\' && p++ && *p != '\\' && strchr ("fbulcr", *p)) {
148+
if (*p == '\\' && p++ && *p != '\\' && strchr ("fbuslcr", *p)) {
144149
switch (*p++) {
145150
case 'f':
146151
if (!isdigit (*p)) *p = '1';
@@ -154,6 +159,14 @@ parse (char *text)
154159
if (!isdigit (*p)) *p = '0';
155160
xcb_set_ud ((*p++)-'0');
156161
break;
162+
case 's':
163+
if (!isdigit (*p)) {
164+
++p;
165+
is_screen = true;
166+
} else {
167+
is_screen = (screen < 0) || (((*p++) - '0') == screen);
168+
}
169+
break;
157170

158171
case 'l':
159172
align = ALIGN_L;
@@ -194,7 +207,9 @@ parse (char *text)
194207
else
195208
xcb_set_fontset (FONT_MAIN);
196209

197-
pos_x += draw_char (pos_x, align, t);
210+
if (is_screen) {
211+
pos_x += draw_char (pos_x, align, t);
212+
}
198213
}
199214
}
200215
}
@@ -307,10 +322,11 @@ set_ewmh_atoms (xcb_window_t root)
307322
}
308323

309324
void
310-
init (void)
325+
init (int screen)
311326
{
312327
xcb_screen_t *scr;
313328
xcb_window_t root;
329+
int x;
314330
int y;
315331

316332
/* Connect to X */
@@ -325,16 +341,39 @@ init (void)
325341
root = scr->root;
326342

327343
/* where to place the window */
344+
x = BAR_OFFSET;
328345
y = (bar_bottom) ? (scr->height_in_pixels - BAR_HEIGHT) : 0;
329346
bar_width = (BAR_WIDTH < 0) ? (scr->width_in_pixels - BAR_OFFSET) : BAR_WIDTH;
330347

348+
#if XINERAMA
349+
if (screen >= 0) {
350+
xcb_xinerama_screen_info_t* xinerama_scr = NULL;
351+
xcb_xinerama_query_screens_cookie_t xinerama_query;
352+
xcb_xinerama_screen_info_iterator_t iter;
353+
xcb_generic_error_t* err = NULL;
354+
xinerama_query = xcb_xinerama_query_screens_unchecked(c);
355+
iter = xcb_xinerama_query_screens_screen_info_iterator(xcb_xinerama_query_screens_reply(c, xinerama_query, &err));
356+
for (; iter.rem; --screen, xcb_xinerama_screen_info_next(&iter)) {
357+
if (screen == 0) {
358+
xinerama_scr = iter.data;
359+
break;
360+
}
361+
}
362+
if (xinerama_scr != NULL) {
363+
y = (bar_bottom) ? (xinerama_scr->y_org + xinerama_scr->height - BAR_HEIGHT) : 0;
364+
x = xinerama_scr->x_org + BAR_OFFSET;
365+
bar_width = (BAR_WIDTH < 0) ? (xinerama_scr->width - BAR_OFFSET) : BAR_WIDTH;
366+
}
367+
}
368+
#endif
369+
331370
/* Load the font */
332371
if (font_load ((const char* []){ BAR_FONT }))
333372
exit (1);
334373

335374
/* Create the main window */
336375
win = xcb_generate_id (c);
337-
xcb_create_window (c, XCB_COPY_FROM_PARENT, win, root, BAR_OFFSET, y, bar_width,
376+
xcb_create_window (c, XCB_COPY_FROM_PARENT, win, root, x, y, bar_width,
338377
BAR_HEIGHT, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, scr->root_visual,
339378
XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK, (const uint32_t []){ palette[0], XCB_EVENT_MASK_EXPOSURE });
340379

@@ -361,7 +400,7 @@ init (void)
361400
/* Make the bar visible */
362401
xcb_map_window (c, win);
363402
/* Send a configure event. Needed to make bar work with Openbox */
364-
xcb_configure_window (c, win, XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, (const uint32_t []){ BAR_OFFSET, y });
403+
xcb_configure_window (c, win, XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, (const uint32_t []){ x, y });
365404

366405
xcb_flush (c);
367406
}
@@ -410,25 +449,28 @@ main (int argc, char **argv)
410449
xcb_expose_event_t *expose_ev;
411450

412451
int permanent = 0;
452+
int screen = -1;
413453

414454
char ch;
415-
while ((ch = getopt (argc, argv, "phb")) != -1) {
455+
while ((ch = getopt (argc, argv, "phbs:")) != -1) {
416456
switch (ch) {
417457
case 'h':
418458
printf ("usage: %s [-p | -h] [-b]\n"
419459
"\t-h Show this help\n"
420460
"\t-b Put bar at the bottom of the screen\n"
421-
"\t-p Don't close after the data ends\n", argv[0]);
461+
"\t-p Don't close after the data ends\n"
462+
"\t-s Select screen to use\n", argv[0]);
422463
exit (0);
423464
case 'p': permanent = 1; break;
424465
case 'b': bar_bottom = 1; break;
466+
case 's': screen = atoi(optarg); break;
425467
}
426468
}
427469

428470
atexit (cleanup);
429471
signal (SIGINT, sighandle);
430472
signal (SIGTERM, sighandle);
431-
init ();
473+
init (screen);
432474

433475
/* Get the fd to Xserver */
434476
pollin[1].fd = xcb_get_file_descriptor (c);
@@ -445,7 +487,7 @@ main (int argc, char **argv)
445487
}
446488
if (pollin[0].revents & POLLIN) { /* New input, process it */
447489
fgets (input, sizeof(input), stdin);
448-
parse (input);
490+
parse (input, screen);
449491
redraw = 1;
450492
}
451493
if (pollin[1].revents & POLLIN) { /* Xserver broadcasted an event */

0 commit comments

Comments
 (0)