git.y1.nz

fbui

Framebuffer-based graphical environment
download: https://git.y1.nz/archives/fbui.tar.gz
README | Files | Log | Refs

libfbui/PanelManager/main.c

      1 
      2 /*=========================================================================
      3  *
      4  * fbpm, a window manager for FBUI (in-kernel framebuffer UI)
      5  * Copyright (C) 2004 Zachary T Smith, fbui@comcast.net
      6  *
      7  * This module is free software; you can redistribute it and/or modify
      8  * it under the terms of the GNU General Public License as published by
      9  * the Free Software Foundation; either version 2 of the License, or
     10  * (at your option) any later version.
     11  *
     12  * This module is distributed in the hope that it will be useful,
     13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15  * GNU General Public License for more details.
     16  *
     17  * You should have received a copy of the GNU General Public License
     18  * along with this module; if not, write to the Free Software
     19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     20  *
     21  * (See the file COPYING in the main directory of this archive for
     22  * more details.)
     23  *
     24  *=======================================================================*/
     25 
     26 /*
     27  * Changes:
     28  *
     29  * Oct 19, 2004, fbui@comcast.net: got rectangle subtraction working
     30  * Oct 19, 2004, fbui@comcast.net: got background image drawing working
     31  * Oct 21, 2004, fbui@comcast.net: began conversion to panel manager
     32  * Dec 12, 2004, fbui@comcast.net: implemented alt-key switching between apps
     33  * Dec 31, 2004, fbui@comcast.net: added drawing of background areas
     34  */
     35 
     36 
     37 
     38 #include <stdio.h>
     39 #include <time.h>
     40 #include <sys/types.h>
     41 #include <unistd.h>
     42 #include <math.h>
     43 #include <jpeglib.h>
     44 #include <signal.h>
     45 #include <errno.h>
     46 
     47 #include "libfbui.h"
     48 
     49 
     50 #define min(AA,BB) ( (AA)<(BB) ? (AA) : (BB) )
     51 #define max(AA,BB) ( (AA)>(BB) ? (AA) : (BB) )
     52 
     53 
     54 extern void draw_background (Display *dpy, Window *win);
     55 
     56 extern int read_JPEG_file (char*);
     57 
     58 void draw_titlebar (Display *dpy, Window *self, short width, char *title, char*);
     59 
     60 
     61 #define circle1_width 16
     62 #define circle1_height 16
     63 static unsigned char circle1_bits[] = {
     64    0xc0, 0x01, 0x30, 0x06, 0x0c, 0x18, 0x84, 0x10, 0xc2, 0x20, 0xc2, 0x20,
     65    0xa1, 0x40, 0x81, 0x40, 0x81, 0x40, 0x82, 0x20, 0x82, 0x20, 0x84, 0x10,
     66    0x0c, 0x18, 0x30, 0x06, 0xc0, 0x01, 0x00, 0x00};
     67 
     68 #define circle2_width 16
     69 #define circle2_height 16
     70 static unsigned char circle2_bits[] = {
     71    0xc0, 0x01, 0x30, 0x06, 0x0c, 0x18, 0xc4, 0x11, 0x22, 0x22, 0x02, 0x22,
     72    0x01, 0x42, 0x01, 0x41, 0x81, 0x40, 0x42, 0x20, 0x22, 0x20, 0xe4, 0x13,
     73    0x0c, 0x18, 0x30, 0x06, 0xc0, 0x01, 0x00, 0x00};
     74 
     75 #define circle3_width 16
     76 #define circle3_height 16
     77 static unsigned char circle3_bits[] = {
     78    0xc0, 0x01, 0x30, 0x06, 0x0c, 0x18, 0xe4, 0x13, 0x02, 0x21, 0x82, 0x20,
     79    0xc1, 0x41, 0x01, 0x42, 0x01, 0x42, 0x02, 0x22, 0x22, 0x22, 0xc4, 0x11,
     80    0x0c, 0x18, 0x30, 0x06, 0xc0, 0x01, 0x00, 0x00};
     81 
     82 #define circle8_width 16
     83 #define circle8_height 16
     84 static unsigned char circle8_bits[] = {
     85    0xc0, 0x01, 0x30, 0x06, 0x0c, 0x18, 0xc4, 0x11, 0x22, 0x22, 0x22, 0x22,
     86    0xc1, 0x41, 0x21, 0x42, 0x21, 0x42, 0x22, 0x22, 0x22, 0x22, 0xc4, 0x11,
     87    0x0c, 0x18, 0x30, 0x06, 0xc0, 0x01, 0x00, 0x00};
     88 
     89 #define circle4_width 16
     90 #define circle4_height 16
     91 static unsigned char circle4_bits[] = {
     92    0xc0, 0x01, 0x30, 0x06, 0x0c, 0x18, 0x04, 0x11, 0x22, 0x21, 0x22, 0x21,
     93    0x21, 0x41, 0xe1, 0x43, 0x01, 0x41, 0x02, 0x21, 0x02, 0x21, 0x04, 0x11,
     94    0x0c, 0x18, 0x30, 0x06, 0xc0, 0x01, 0x00, 0x00};
     95 
     96 #define circle5_width 16
     97 #define circle5_height 16
     98 static unsigned char circle5_bits[] = {
     99    0xc0, 0x01, 0x30, 0x06, 0x0c, 0x18, 0xe4, 0x13, 0x22, 0x20, 0x22, 0x20,
    100    0xe1, 0x41, 0x01, 0x42, 0x01, 0x42, 0x02, 0x22, 0x22, 0x22, 0xc4, 0x11,
    101    0x0c, 0x18, 0x30, 0x06, 0xc0, 0x01, 0x00, 0x00};
    102 
    103 #define circle6_width 16
    104 #define circle6_height 16
    105 static unsigned char circle6_bits[] = {
    106    0xc0, 0x01, 0x30, 0x06, 0x0c, 0x18, 0xc4, 0x11, 0x22, 0x22, 0x22, 0x20,
    107    0x21, 0x40, 0xe1, 0x41, 0x21, 0x42, 0x22, 0x22, 0x22, 0x22, 0xc4, 0x11,
    108    0x0c, 0x18, 0x30, 0x06, 0xc0, 0x01, 0x00, 0x00};
    109 
    110 #define circle7_width 16
    111 #define circle7_height 16
    112 static unsigned char circle7_bits[] = {
    113    0xc0, 0x01, 0x30, 0x06, 0x0c, 0x18, 0xe4, 0x13, 0x02, 0x22, 0x02, 0x22,
    114    0x01, 0x41, 0x81, 0x40, 0x81, 0x40, 0x82, 0x20, 0x82, 0x20, 0x84, 0x10,
    115    0x0c, 0x18, 0x30, 0x06, 0xc0, 0x01, 0x00, 0x00};
    116 
    117 #define circle9_width 16
    118 #define circle9_height 16
    119 static unsigned char circle9_bits[] = {
    120    0xc0, 0x01, 0x30, 0x06, 0x0c, 0x18, 0xc4, 0x11, 0x22, 0x22, 0x22, 0x22,
    121    0x21, 0x42, 0xc1, 0x43, 0x01, 0x41, 0x02, 0x21, 0x82, 0x20, 0x84, 0x10,
    122    0x0c, 0x18, 0x30, 0x06, 0xc0, 0x01, 0x00, 0x00};
    123 
    124 #define circle0_width 16
    125 #define circle0_height 16
    126 static unsigned char circle0_bits[] = {
    127    0xc0, 0x01, 0x30, 0x06, 0x0c, 0x18, 0xc4, 0x11, 0x22, 0x22, 0x22, 0x22,
    128    0x21, 0x42, 0x21, 0x42, 0x21, 0x42, 0x22, 0x22, 0x22, 0x22, 0xc4, 0x11,
    129    0x0c, 0x18, 0x30, 0x06, 0xc0, 0x01, 0x00, 0x00};
    130 
    131 
    132 static short icon_height = circle0_height;
    133 
    134 
    135 static unsigned char *bitmaps[10] = {
    136 	circle1_bits,
    137 	circle2_bits,
    138 	circle3_bits,
    139 	circle4_bits,
    140 	circle5_bits,
    141 	circle6_bits,
    142 	circle7_bits,
    143 	circle8_bits,
    144 	circle9_bits,
    145 	circle0_bits,
    146 };
    147 
    148 unsigned short reverse16 (unsigned short value)
    149 {
    150 	int i;
    151 	unsigned short result = 0;
    152 	for (i=0; i<16; i++) {
    153 		unsigned short j = 1 << i;
    154 		unsigned short j2 = 1 << (15-i);
    155 		if (j & value)
    156 			result |= j2;
    157 	}
    158 	return result;
    159 }
    160 
    161 short win_w, win_h;
    162 #define STEELBLUE 0x4682B4
    163 
    164 extern JSAMPLE * image_buffer;
    165 extern int image_height;
    166 extern int image_width;
    167 extern int image_ncomponents;
    168 extern int read_JPEG_file (char*);
    169 
    170 int foreground_id = -1;
    171 
    172 Font *font1;
    173 Font *font2;
    174 short line_height; // font1's
    175 
    176 static short separator_size = 2;
    177 
    178 static char grayscale=0; /* 1 forces bg image to grayscale */
    179 
    180 
    181 int window_count;
    182 
    183 #define MAXWINS (40)
    184 struct fbui_wininfo info[MAXWINS];
    185 
    186 
    187 
    188 static short mainarea_width;
    189 static short mainarea_height;
    190 
    191 static short bottomarea_width;
    192 static short bottomarea_height;
    193 
    194 static short rightarea_width;
    195 static short rightarea_height;
    196 
    197 static short listarea_width;
    198 static short listarea_height;
    199 
    200 static short rightarea_height_remaining;
    201 static short bottomarea_width_remaining;
    202 
    203 
    204 void
    205 draw_window_list (Display *dpy, Window *self)
    206 {
    207 	int i;
    208 	short icon_width;
    209 	short lx, ly;
    210 	short key=1;
    211 	short line_height = font1->ascent + font1->descent;
    212 
    213 	// The (#) icons
    214 	icon_width = 16;
    215 	icon_height = 16;
    216 
    217 	lx = win_w - listarea_width;
    218 	ly = win_h - listarea_height;
    219 	fbui_fill_area (dpy, self, lx,ly, win_w,win_h, RGB_CYAN);
    220 
    221 	int appcount = 0;
    222 	for (i=0; i < window_count; i++) {
    223 		int t = info[i].program_type;
    224 		unsigned char *bits_source = bitmaps [appcount < 10 ? appcount : 9];
    225 
    226 		if (t == FBUI_PROGTYPE_APP || 
    227 		    t == FBUI_PROGTYPE_EPHEMERAL || !t) 
    228 		{
    229 			int j;
    230 			for (j=0; j<icon_height; j++) {
    231 				unsigned short bits = 0;
    232 				int k = j << 1;
    233 				bits = bits_source [k+1]; 
    234 				bits <<= 8;
    235 				bits |= bits_source [k];
    236 				bits = reverse16 (bits);
    237 
    238 				fbui_tinyblit (dpy, self, lx+2, ly+j,
    239 					RGB_BLACK, RGB_NOCOLOR, 
    240 					icon_width, bits);
    241 			}
    242 
    243 			fbui_draw_string (dpy, self, font1,
    244 				lx+3+icon_width,ly, 
    245 				info[i].name, RGB_BLUE);
    246 
    247 			appcount++;
    248 			ly += max(line_height,icon_height);
    249 		}
    250 	}
    251 
    252 	// No apps? Clear out the title bar.
    253 	if (!appcount) {
    254 		// fbui_clear_area (dpy, self, 0, 0, mainarea_width-1, line_height-1);
    255 		fbui_draw_string (dpy, self, font1, lx+3, ly, "No apps.", RGB_BLUE);
    256 	}
    257 }
    258 
    259 
    260 void
    261 flip (Display *dpy, Window *self, int which /* 0...8 */ )
    262 {
    263 	int i, appcounter;
    264 	int count;
    265 
    266 	if (which < 0 || which > 8) {
    267 		return;
    268 	}
    269 
    270 	/* Firstly count the number of apps and ephemerals */
    271 	count=0;
    272 	i = 0;
    273 	while (i < window_count) {
    274 		char type = info[i].program_type;
    275 		if (type == FBUI_PROGTYPE_APP || type == FBUI_PROGTYPE_EPHEMERAL || !type)
    276 			count++;
    277 		i++;
    278 	}
    279 	/* Rule: overlarge # switches to last */
    280 	if (which >= count)
    281 		which = count - 1;
    282 
    283 	/* Secondly hide all */
    284 	i = 0;
    285 	while (i < window_count) {
    286 		char type = info[i].program_type;
    287 		if (type == FBUI_PROGTYPE_APP || type == FBUI_PROGTYPE_EPHEMERAL || !type) {
    288 			fbui_hide (dpy, self, info[i].id);
    289 		}
    290 		i++;
    291 	}
    292 
    293 	/* Thirdly bring the flipped-to window to the fore */
    294 	appcounter = 0; 
    295 	i = 0;
    296 	struct fbui_wininfo *wi = NULL;
    297 	while (i < window_count) {
    298 		char type = info[i].program_type;
    299 		if (type == FBUI_PROGTYPE_APP || type == FBUI_PROGTYPE_EPHEMERAL || !type) {
    300 			if (appcounter == which) {
    301 				int retval;
    302 				short id = info[i].id;
    303 				wi = &info[i];
    304 				foreground_id = id;
    305 				if (retval = fbui_unhide (dpy, self, id))
    306 					printf ("fbpm: unhide failed %d\n", retval);
    307 				fbui_assign_keyfocus (dpy, self, id);
    308 				break;
    309 			}
    310 			appcounter++;
    311 		}
    312 		i++;
    313 	}
    314 
    315 	if (wi)
    316 		draw_titlebar (dpy,self,wi->width, wi->name, wi->subtitle);
    317 }
    318 
    319 
    320 void
    321 flip_to_next (Display *dpy, Window *self)
    322 {
    323 	int i;
    324 	char found_current = 0;
    325 	char appcounter = 0;
    326 
    327 	if (foreground_id < 0)
    328 		return;
    329 
    330 	i = 0;
    331 	while (i < window_count) {
    332 		char type = info[i].program_type;
    333 		short id = info[i].id;
    334 
    335 		if (type == FBUI_PROGTYPE_APP || type == FBUI_PROGTYPE_EPHEMERAL || !type) {
    336 			if (found_current) {
    337 				flip (dpy, self, appcounter);
    338 				return;
    339 			}
    340 
    341 			if (id == foreground_id)
    342 				found_current = 1;
    343 
    344 			appcounter++;
    345 		}
    346 		i++;
    347 	}
    348 
    349 	// Not found, which means it was the last one.
    350 	flip (dpy, self, 0);
    351 }
    352 
    353 
    354 void draw_titlebar (Display *dpy, Window *self, short width, char *title, char *subtitle)
    355 {
    356 	if (!window_count)
    357 		return;
    358 
    359 	// draw gradient behind text
    360 	int j=0;
    361 	while (j < width) {
    362 		unsigned long r,g,b;
    363 		int n = 255 - j/2;
    364 		int k = n > 1 ? n : 0;
    365 		r = 30;
    366 		g = 32 + (7*k)/8;
    367 		b = k/3;
    368 		r <<= 16;
    369 		b <<= 8;
    370 		fbui_draw_vline (dpy, self, 
    371 				 j, 0, line_height-1, r|g|b);
    372 		j++;
    373 	}
    374 
    375 	// draw program name/pid
    376 	char tmp[200];
    377 	if (!subtitle || !*subtitle)
    378 		sprintf(tmp,"%s", title,subtitle);
    379 	else
    380 		sprintf(tmp,"%s (%s)", title,subtitle);
    381 	fbui_draw_string (dpy, self, font1,0,0,tmp, RGB_YELLOW);
    382 }
    383 
    384 
    385 int
    386 main(int argc, char** argv)
    387 {
    388 	int i,j;
    389 	Display *dpy;
    390 	Window *self;
    391 
    392 	window_count = 0;
    393 
    394         font1 = font_new ();  // main font
    395         // font2 = font_new ();  // subtitle font
    396 
    397         if (!pcf_read (font1, "timR12.pcf")) {
    398                 font_free (font1);
    399                 font1 = NULL;
    400 		FATAL ("cannot load font");
    401         }
    402 
    403 	/* Get text height...will determine size of list area.
    404  	 */
    405 	line_height = font1->ascent + font1->descent;
    406 
    407 	long fgcolor = RGB_NOCOLOR; // not used
    408 	long bgcolor = STEELBLUE;
    409 
    410 	dpy = fbui_display_open ();
    411 	if (!dpy)
    412 		FATAL ("cannot open display");
    413 
    414 	self = fbui_window_open (dpy, 1,1, &win_w, &win_h,
    415 		9999,9999, // no max wid/ht
    416 		0, 0, 
    417 		&fgcolor, &bgcolor, 
    418 		"fbpm", "", 
    419 		FBUI_PROGTYPE_WM, 
    420 		true,
    421 		true, 
    422 		-1,
    423 		false,
    424 		true, // all motion
    425 		false,// not hidden
    426 		argc,argv);
    427 	if (!self) {
    428 		fbui_display_close (dpy);
    429 		FATAL ("cannot open manager window");
    430 	}
    431 
    432         /* Check for a background image */
    433         image_width=0;
    434         image_height=0;
    435         image_ncomponents=0;
    436         image_buffer=NULL;
    437         char *image_path=NULL;
    438         i=1;
    439         while (i<argc) {
    440                 char *s = argv[i];
    441                 int ch = s ? s[0] : 0;
    442                 if (ch && '-' != ch) {
    443                         image_path = argv[i];
    444                         break;
    445                 }
    446                 i++;
    447         }
    448         if (image_path) {
    449                 int result;
    450                 result = read_JPEG_file (image_path);
    451                 if (image_ncomponents != 3)
    452                         result=0;
    453                 if (!result) {
    454                         WARNING ("cannot read background image");
    455 			if (image_buffer)
    456 				free(image_buffer);
    457 			image_buffer=NULL;
    458 			image_width=0;
    459 			image_height=0;
    460 			image_ncomponents=0;
    461 		}
    462 
    463         }
    464 
    465 	/* If the wm was started after windows appeared,
    466 	 * we need to hide those windows to prevent fbui_overlap_check
    467 	 * from complaining.
    468 	 */
    469 	window_count = fbui_window_info (dpy, self, &info[0], MAXWINS);
    470 	for (i=0; i<window_count; i++) {
    471 		int rv = fbui_hide (dpy, self, info[i].id);
    472 		if (rv) {
    473 			printf ("hide of %s failed! (%d)\n", info[i].name,rv);
    474 		}
    475 	}
    476 
    477 	listarea_height = icon_height * 10;
    478 	rightarea_width = 78;
    479 	listarea_width = rightarea_width;
    480 	bottomarea_width = win_w - rightarea_width;
    481 	mainarea_width = bottomarea_width;
    482 	bottomarea_height = 25;
    483 	mainarea_height = win_h - bottomarea_height;
    484 	rightarea_height = mainarea_height - listarea_height;
    485 	bottomarea_width_remaining = bottomarea_width;
    486 	rightarea_height_remaining = rightarea_height;
    487 
    488 	if (FBUI_SUCCESS != fbui_accelerator (dpy, self, '1', 1))
    489 		FATAL ("cannot register accelerator");
    490 	if (FBUI_SUCCESS != fbui_accelerator (dpy, self, '2', 1))
    491 		FATAL ("cannot register accelerator");
    492 	if (FBUI_SUCCESS != fbui_accelerator (dpy, self, '3', 1))
    493 		FATAL ("cannot register accelerator");
    494 	if (FBUI_SUCCESS != fbui_accelerator (dpy, self, '4', 1))
    495 		FATAL ("cannot register accelerator");
    496 	if (FBUI_SUCCESS != fbui_accelerator (dpy, self, '5', 1))
    497 		FATAL ("cannot register accelerator");
    498 	if (FBUI_SUCCESS != fbui_accelerator (dpy, self, '6', 1))
    499 		FATAL ("cannot register accelerator");
    500 	if (FBUI_SUCCESS != fbui_accelerator (dpy, self, '7', 1))
    501 		FATAL ("cannot register accelerator");
    502 	if (FBUI_SUCCESS != fbui_accelerator (dpy, self, '8', 1))
    503 		FATAL ("cannot register accelerator");
    504 	if (FBUI_SUCCESS != fbui_accelerator (dpy, self, '9', 1))
    505 		FATAL ("cannot register accelerator");
    506 	if (FBUI_SUCCESS != fbui_accelerator (dpy, self, '0', 1))
    507 		FATAL ("cannot register accelerator");
    508 
    509 	/* Alt-tab switches between apps
    510 	 */
    511 	if (FBUI_SUCCESS != fbui_accelerator (dpy, self, '\t', 1))
    512 		FATAL ("cannot register accelerator");
    513 
    514 	/* Alt-backsp shuts down FBUI on the current VC
    515 	 */
    516 	if (FBUI_SUCCESS != fbui_accelerator (dpy, self, '\b', 1))
    517 		FATAL ("cannot register accelerator");
    518 
    519 	/* Alt-PrtSc is to perform a screendump
    520 	 */
    521 	if (FBUI_SUCCESS != fbui_accelerator (dpy, self, FBUI_ACCEL_PRTSC, 1))
    522 		FATAL ("cannot register accelerator");
    523 
    524 	if (FBUI_SUCCESS != fbui_placement (dpy, self, 1))
    525 		FATAL ("cannot force auto-placement");
    526 
    527 	int need_list = 1;
    528 	int need_redraw = 0;
    529 	goto getlist;
    530 
    531 	while(1) {
    532 		Event ev;
    533 		int err;
    534 		if (err = fbui_wait_event (dpy, &ev,
    535                                      FBUI_EVENTMASK_ALL - FBUI_EVENTMASK_KEY))
    536 		{
    537 			fbui_print_error (err);
    538 			continue;
    539 		}
    540 printf ("%s got event %s\n", argv[0], fbui_get_event_name (ev.type));
    541 
    542 		int num = ev.type;
    543 
    544 		if (ev.win != self)
    545 			FATAL ("event not for our window");
    546 
    547 		if (num == FBUI_EVENT_EXPOSE) {
    548 			need_redraw = 1;
    549 		}
    550 		else if (num == FBUI_EVENT_WINCHANGE) {
    551 			need_redraw = 1;
    552 			need_list = 1;
    553 		}
    554 		else if (num == FBUI_EVENT_ENTER) {
    555 			printf ("fbpm got Enter (it shouldnt)\n");
    556 			continue;
    557 		}
    558 		else if (num == FBUI_EVENT_LEAVE) {
    559 			printf ("fbpm got Leave (it shouldnt)\n");
    560 			continue;
    561 		}
    562 		else if (num == FBUI_EVENT_ACCEL) {
    563 			short key = ev.key;
    564 
    565 printf ("ACCEL key %d\n", key);
    566 
    567 			switch (key) {
    568 			case '\b':
    569 				goto finit;
    570 
    571 			case '\t':
    572 				flip_to_next (dpy, self);
    573 				continue;
    574 
    575 			case '1':
    576 			case '2':
    577 			case '3':
    578 			case '4':
    579 			case '5':
    580 			case '6':
    581 			case '7':
    582 			case '8':
    583 			case '9':
    584 				flip (dpy, self, key - '1');
    585 				continue;
    586 
    587 			case FBUI_ACCEL_PRTSC:
    588 				printf ("Dumping screen image to dump.jpg\n");
    589 				system ("fbdump");
    590 				continue;
    591 			}
    592 		}
    593 
    594 getlist:
    595 		if (need_list) {
    596 			int i;
    597 			short new_x0[MAXWINS];
    598 			short new_y0[MAXWINS];
    599 			short new_x1[MAXWINS];
    600 			short new_y1[MAXWINS];
    601 			short zone[MAXWINS];
    602 
    603 			short new_application_window = -1;
    604 
    605 			int total_existing_application_windows = 0;
    606 			short existing_application_windows[MAXWINS];
    607 
    608 			for (i=0; i<MAXWINS; i++)
    609 				existing_application_windows[i] = -1;
    610 
    611 			char foreground_is_in_foreground = 0;
    612 			char foreground_found = 0;
    613 
    614 			/* Get a list of existing application windows,
    615 			 * since we need to bring any new app window
    616 			 * to the fore.	
    617 			 */
    618 			for (i=0; i<window_count; i++) {
    619 				if (info[i].program_type == FBUI_PROGTYPE_APP) {
    620 					existing_application_windows [total_existing_application_windows++] = info[i].id;
    621 
    622 					if (info[i].id == foreground_id) {
    623 						if (!info[i].hidden)
    624 							foreground_is_in_foreground = 1;
    625 					}
    626 				}
    627 			}
    628 
    629 printf ("----------------------------------------------\n");
    630 printf ("fbpm: Getting window list...");
    631 			window_count = fbui_window_info (dpy, self, &info[0], MAXWINS);
    632 printf ("%d total\n", window_count);
    633 
    634 			/* Perform a window census...
    635 			 */
    636 			int total_bottom = 0;
    637 			int total_right = 0;
    638 			int total_main = 0;
    639 			for (i=0; i<window_count; i++) {
    640 				int id = info[i].id;
    641 
    642 				switch (info[i].program_type) {
    643 				case FBUI_PROGTYPE_WM:
    644 printf ("  %d wm %s id=%d pid=%d %s\n", i, info[i].name, id,info[i].hidden?"hidden":"");
    645 					break;
    646 				case FBUI_PROGTYPE_APP:
    647 					total_main++; 
    648 printf ("  %d app %s id=%d pid=%d %s\n", i, info[i].name, id,info[i].pid,info[i].hidden?"hidden":"");
    649 					j=0;
    650 					char got_it_already = 0;
    651 					while (j < total_existing_application_windows) {
    652 						if (id == existing_application_windows[j]) {
    653 							got_it_already = 1;
    654 							break;
    655 						}
    656 						j++;
    657 					}
    658 
    659 					if (!got_it_already)
    660 						new_application_window = id;
    661 
    662 					if (foreground_id == id)
    663 						foreground_found = 1;
    664 
    665 					break;
    666 				case FBUI_PROGTYPE_LAUNCHER:
    667 					total_bottom++; 
    668 printf ("  %d launcher %s id=%d pid=%d %s\n", i, info[i].name, id,info[i].pid,info[i].hidden?"hidden":"");
    669 					break;
    670 				case FBUI_PROGTYPE_TOOL:
    671 					total_right++; 
    672 printf ("  %d tool %s id=%d pid=%d %s\n", i, info[i].name, id,info[i].pid,info[i].hidden?"hidden":"");
    673 					break;
    674 				case FBUI_PROGTYPE_EPHEMERAL:
    675 					total_main++; 
    676 printf ("  %d ephemeral %s id=%d pid=%d %s\n", i, info[i].name, id,info[i].pid,info[i].hidden?"hidden":"");
    677 					break;
    678 				case FBUI_PROGTYPE_NONE:
    679 					total_main++; 
    680 printf ("  %d (no type) %s id=%d pid=%d %s\n", i, info[i].name, id,info[i].pid,info[i].hidden?"hidden":"");
    681 					break;
    682 				default:
    683 					total_main++; 
    684 printf ("  %d (unknown type) %s id=%d pid=%d %s\n", i, info[i].name, id,info[i].pid,info[i].hidden?"hidden":"");
    685 					break;
    686 				}
    687 			}
    688 
    689 			/* Determine what the new positions of all of 
    690 			 * the windows will be.
    691 			 */
    692 			int bottom_ration = total_bottom ? bottomarea_width / total_bottom : 0;
    693 			int right_ration = total_right ? rightarea_height / total_right : 0;
    694 			int bottom_x = 0;
    695 			int right_y = 0;
    696 
    697 			if (!foreground_found)
    698 				foreground_id = -1;
    699 
    700 			for (i=0; i<window_count; i++) {
    701 				char whichzone=0;  /* 1=main, 2=bottom, 3=right */
    702 				int x0=-1,y0,x1,y1;
    703 				short x = info[i].x;
    704 				short y = info[i].y;
    705 				short w = info[i].width;
    706 				short h = info[i].height;
    707 				short max_w = info[i].max_width;
    708 				short max_h = info[i].max_height;
    709 //printf ("from info[%d] x %d y %d w %d h %d\n",(int)i,(int)x,(int)y,(int)w,(int)h);
    710 
    711 				switch (info[i].program_type) {
    712 				case FBUI_PROGTYPE_WM:
    713 					break;
    714 
    715 				case FBUI_PROGTYPE_APP:
    716 				case FBUI_PROGTYPE_EPHEMERAL:
    717 				default:
    718 					whichzone=1;
    719 					x0 = 0;
    720 					y0 = line_height; // leave space for title
    721 					x1 = mainarea_width - 1 - separator_size;
    722 					y1 = mainarea_height - 1 - separator_size;
    723 
    724 					if (new_application_window < 0 && foreground_id == -1)
    725 						foreground_id = info[i].id;
    726 
    727 					break;
    728 
    729 				case FBUI_PROGTYPE_LAUNCHER:
    730 					whichzone=2;
    731 					x0 = bottom_x;
    732 					if (w < bottom_ration)
    733 						bottom_x += (w + separator_size);
    734 					else if (max_w > 1 && max_w < bottom_ration) 
    735 						bottom_x += max_w;
    736 					else
    737 						bottom_x += bottom_ration;
    738 					x1 = bottom_x - 1 - separator_size;
    739 					y0 = mainarea_height;
    740 					y1 = win_h - 1;
    741 					break;
    742 
    743 				case FBUI_PROGTYPE_TOOL:
    744 					whichzone=3;
    745 					x0 = mainarea_width;
    746 					x1 = win_w - 1;
    747 					y0 = right_y;
    748 					if (h < right_ration)
    749 						right_y += (h + separator_size);
    750 					else if (max_h > 1 && max_h < right_ration)
    751 						right_y += max_h;
    752 					else
    753 						right_y += right_ration;
    754 					y1 = right_y - 1 - separator_size;
    755 					break;
    756 				}
    757 
    758 				new_x0 [i] = x0;
    759 				new_y0 [i] = y0;
    760 				new_x1 [i] = x1;
    761 				new_y1 [i] = y1;
    762 				zone [i] = whichzone;
    763 printf ("  new pos '%s' = %d %d, %d %d\n", info[i].name,x0,y0,x1,y1);
    764 			}
    765 
    766 			/* Determine which zones changed.
    767 			 */
    768 			char bottom_changed=0;
    769 			char right_changed=0;
    770 			char main_changed=0;
    771 			for (i=0; i<window_count; i++) {
    772 				if (info[i].need_placement ||
    773 				    new_x0[i] != info[i].x || 
    774 				    new_y0[i] != info[i].y || 
    775 				    new_x1[i] != info[i].x+info[i].width-1 ||
    776 				    new_y1[i] != info[i].y+info[i].height-1)
    777 				{
    778 					switch (zone[i]) {
    779 					case 1:
    780 						main_changed=1;
    781 						break;
    782 					case 2:
    783 						bottom_changed=1;
    784 						break;
    785 					case 3:
    786 						right_changed=1;
    787 						break;
    788 					}
    789 				}
    790 			}
    791 
    792 			if (!foreground_found)
    793 				main_changed = 1;
    794 			if (new_application_window >= 0)
    795 				main_changed = 1;
    796 
    797 			if (main_changed)
    798 				printf ("-main changed-\n");
    799 			if (bottom_changed)
    800 				printf ("-bottom changed-\n");
    801 			if (right_changed)
    802 				printf ("-right changed-\n");
    803 
    804 			/* For each zone that changed, hide all
    805 			 * windows.
    806 			 */
    807 			if (main_changed) {
    808 				for (i=0; i<window_count; i++) {
    809 					if (zone[i]==1)
    810 						fbui_hide (dpy, self, info[i].id);
    811 				}
    812 			}
    813 			if (bottom_changed) {
    814 				for (i=0; i<window_count; i++) {
    815 					if (zone[i]==2)
    816 						fbui_hide (dpy, self, info[i].id);
    817 				}
    818 			}
    819 			if (right_changed) {
    820 				for (i=0; i<window_count; i++) {
    821 					if (zone[i]==3)
    822 						fbui_hide (dpy, self, info[i].id);
    823 				}
    824 			}
    825 
    826 			/* Now make the size/position changes,
    827 			 * while windows are hidden.
    828 			 */
    829 			for (i=0; i<window_count; i++) 
    830 			{
    831 				int domove=0;
    832 				if ((zone[i]==1 && main_changed) ||
    833 				    (zone[i]==2 && bottom_changed) ||
    834 				    (zone[i]==3 && right_changed))
    835 					domove=1;
    836 
    837 				if (info[i].need_placement)
    838 					domove=1;
    839 
    840 				if (domove)
    841 					fbui_move_resize (dpy, self, info[i].id,
    842 						new_x0[i], 
    843 						new_y0[i], 
    844 						new_x1[i],
    845 						new_y1[i]);
    846 			}
    847 
    848 			/* Unhide windows that need it.
    849 			 */
    850 			for (i=0; i<window_count; i++) 
    851 			{
    852 				if ((zone[i]==2 && bottom_changed) ||
    853 				    (zone[i]==3 && right_changed))
    854 				{
    855 					int retval;
    856 					if (retval = fbui_unhide (dpy, self, info[i].id))
    857 						printf ("fbpm: unhide failed %d\n", retval);
    858 				}
    859 			}
    860 
    861 			/* Only one main window gets focus
    862 			 */
    863 			if (new_application_window != -1) {
    864 				int retval;
    865 				if (retval = fbui_unhide (dpy, self, new_application_window))
    866 					printf ("fbpm: unhide failed %d\n", retval);
    867 				fbui_assign_keyfocus (dpy, self, new_application_window);
    868 				foreground_id = new_application_window;
    869 printf ("unhid new app %d\n", new_application_window);
    870 			}
    871 			else if (foreground_id != -1) {
    872 				int retval;
    873 printf ("unhid fg win %d\n", foreground_id);
    874 				if (retval = fbui_unhide (dpy, self, foreground_id))
    875 					printf ("fbpm: unhide failed %d\n", retval);
    876 				fbui_assign_keyfocus (dpy, self, foreground_id);
    877 			}
    878 
    879 printf ("After moves...\n");
    880 			window_count = fbui_window_info (dpy, self, &info[0], MAXWINS);
    881 			for (i=0; i<window_count; i++) {
    882 printf ("   program %s.... %s\n", info[i].name,info[i].hidden?"hidden":"");
    883 			}
    884 
    885 			need_list=0;
    886 
    887 			need_redraw = 1;
    888 		} 
    889 		
    890 		if (need_redraw) {
    891 			int i;
    892 
    893 			need_redraw = 0;
    894 
    895 			draw_background (dpy,self);
    896 			draw_window_list (dpy, self);
    897 
    898 			i=0; 
    899 			while (i < window_count) {
    900 				struct fbui_wininfo *wi = &info[i];
    901 				int x,y;
    902 
    903 				if (wi->id == foreground_id) {
    904 					draw_titlebar (dpy,self,wi->width, wi->name,wi->subtitle);
    905 					break;
    906 				}
    907 
    908 				i++;
    909 			}
    910 		}
    911 	}
    912 finit:
    913 	;
    914 
    915 	int mypid = getpid();
    916 	for (i=0; i < window_count; i++) {
    917 		if (info[i].pid != mypid)
    918 			kill (info[i].pid, SIGTERM);
    919 	}
    920 
    921 	for (i=0; i < window_count; i++) {
    922 #if 0
    923 		draw_background (dpy, self,
    924 		  info[i].x,
    925 		  info[i].y - line_height,
    926 		  info[i].x + info[i].width - 1,
    927 		  info[i].y - 1);
    928 		fbui_flush (dpy, self);
    929 #endif
    930 	}
    931 
    932 	fbui_window_close (dpy, self);
    933 	fbui_display_close (dpy);
    934 
    935 	return 0;
    936 }

This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.