fbui | Framebuffer-based graphical environment |
| download: https://git.y1.nz/archives/fbui.tar.gz | |
| README | Files | Log | Refs |
libfbui/libfbui.c
1
2 /*=========================================================================
3 *
4 * libfbui, a library for accessing FBUI (in-kernel framebuffer GUI).
5 * Copyright (C) 2003-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 #include <stdio.h>
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <fcntl.h>
30 #include <sys/ioctl.h>
31 #include <linux/fb.h>
32 #include <sys/mman.h>
33 #include <unistd.h>
34 #include <linux/vt.h>
35 #include <signal.h>
36 #include <errno.h>
37 #include <linux/input.h>
38 #include <string.h>
39 #include <stdlib.h>
40 #include <ctype.h>
41 #include <time.h>
42 #include <sys/param.h>
43
44
45
46 #include "libfbui.h"
47
48
49 static struct fb_fix_screeninfo fi;
50 static struct fb_var_screeninfo vi;
51 static struct fbui_openparams oi;
52
53 #define ERRLOG "/tmp/fbui.log"
54
55
56 static int dpi = 75;
57
58
59 /*-----------------------------------------------------------------------------
60 * Changes:
61 *
62 * Sep 23, ZS: added SIGTERM handler
63 * Sep 24, ZS: added commandline processing of console# (-c)
64 * Sep 25, ZS: added read_point
65 * Sep 25, ZS: added errlog
66 * Sep 26, ZS: added commandline processing of geometry (-geo)
67 * Sep 26, ZS: more signals supported
68 * Oct 01, ZS: updated for new use of control ioctl
69 * Oct 14, ZS: added support for fbui-input events
70 * Oct 14, ZS: added keycode->char conversion
71 * Oct 22, ZS: fbui_open now ensures dims are available
72 * Oct 26, ZS: added -fg and -bg
73 *
74 *----------------------------------------------------------------------------*/
75
76
77 Display *my_dpy = NULL;
78 int display_fd;
79
80
81 static void
82 errlog (char *s, char *s2)
83 {
84 FILE *f=fopen(ERRLOG,"a");
85 if (!f)
86 return;
87 fprintf(f, "%s(): %s\n", s,s2);
88 fprintf(f, "\tsystem error(%d): %s\n", errno,strerror(errno));
89 fclose(f);
90 }
91
92
93 int
94 fbui_flush (Display *dpy, Window *win)
95 {
96 int result=0;
97
98 if (!dpy || !win) return -1;
99 /*---------------*/
100
101 if (win->command_ix <= 2)
102 return 0;
103
104 win->command[0] = win->id;
105 win->command[1] = win->command_ix-2;
106 if (win->command[1])
107 result = ioctl (dpy->fd, FBIO_UI_EXEC, (void*) win->command);
108 win->command[0] = win->id;
109 win->command[1] = 0;
110 win->command_ix = 2;
111 return result;
112 }
113
114 static int
115 check_flush (Display *dpy, Window *win, int need)
116 {
117 unsigned short nwords;
118 int result=0;
119
120 if (!dpy || !win) return -1;
121 /*---------------*/
122 nwords = win->command_ix-2;
123 if (nwords + need >= LIBFBUI_COMMANDBUFLEN) {
124 result = fbui_flush (dpy,win);
125 }
126 return result;
127 }
128
129
130
131 /* called only by wm */
132 int
133 fbui_window_info (Display* dpy, Window *wm, struct fbui_wininfo* info, int ninfo)
134 {
135 int result=0;
136
137 if (!dpy || !info || ninfo<=0) return -1011;
138 /*---------------*/
139
140 static struct fbui_ctrlparams ctl;
141 memset (&ctl, 0, sizeof (struct fbui_ctrlparams));
142 ctl.op = FBUI_WININFO;
143 ctl.id = wm->id;
144 ctl.info = info;
145 ctl.ninfo = ninfo;
146
147 return ioctl (dpy->fd, FBIO_UI_CONTROL, (unsigned long) &ctl);
148 }
149
150 int
151 fbui_accelerator (Display* dpy, Window *wm, short key, short op)
152 {
153 int result=0;
154
155 if (!dpy) return -1;
156 /*---------------*/
157
158 struct fbui_ctrlparams ctl;
159 memset (&ctl, 0, sizeof (struct fbui_ctrlparams));
160 ctl.op = FBUI_ACCEL;
161 ctl.id = wm->id;
162 ctl.x = key;
163 ctl.y = op;
164
165 return ioctl (dpy->fd, FBIO_UI_CONTROL, (unsigned long) &ctl) < 0 ? -errno : 0;
166 }
167
168
169 int
170 fbui_cut (Display* dpy, Window *win, unsigned char *data, unsigned long length)
171 {
172 if (!dpy || !win || !data || !length)
173 return -1;
174 /*---------------*/
175
176 struct fbui_ctrlparams ctl;
177 memset (&ctl, 0, sizeof (struct fbui_ctrlparams));
178 ctl.op = FBUI_CUT;
179 ctl.id = win->id;
180 ctl.pointer = data;
181 ctl.cutpaste_length = length;
182
183 return ioctl (dpy->fd, FBIO_UI_CONTROL, (unsigned long) &ctl) < 0 ? -errno : 0;
184 }
185
186 int
187 fbui_paste (Display* dpy, Window *win, unsigned char *data, unsigned long max)
188 {
189 if (!dpy || !win || !data || !max)
190 return -1;
191 /*---------------*/
192
193 struct fbui_ctrlparams ctl;
194 memset (&ctl, 0, sizeof (struct fbui_ctrlparams));
195 ctl.op = FBUI_PASTE;
196 ctl.id = win->id;
197 ctl.pointer = data;
198 ctl.cutpaste_length = max;
199
200 return ioctl (dpy->fd, FBIO_UI_CONTROL, (unsigned long) &ctl) < 0 ? -errno : 0;
201 }
202
203
204 long
205 fbui_cut_length (Display* dpy, Window *win)
206 {
207 if (!dpy || !win)
208 return -1;
209 /*---------------*/
210
211 struct fbui_ctrlparams ctl;
212 memset (&ctl, 0, sizeof (struct fbui_ctrlparams));
213 ctl.op = FBUI_CUTLENGTH;
214 ctl.id = win->id;
215
216 return ioctl (dpy->fd, FBIO_UI_CONTROL, (unsigned long) &ctl) < 0 ? -errno : 0;
217 }
218
219
220 /* 1 => force all windows to be auto placed
221 */
222 /* called only by wm */
223 int
224 fbui_placement (Display* dpy, Window *wm, int yes)
225 {
226 int result=0;
227
228 if (!dpy) return -1;
229 /*---------------*/
230
231 struct fbui_ctrlparams ctl;
232 memset (&ctl, 0, sizeof (struct fbui_ctrlparams));
233 ctl.op = FBUI_PLACEMENT;
234 ctl.id = wm->id;
235 ctl.x = yes;
236
237 return ioctl (dpy->fd, FBIO_UI_CONTROL, (unsigned long) &ctl) < 0 ? -errno : 0;
238 }
239
240
241 /* called only by wm */
242 int
243 fbui_redraw (Display *dpy, Window *wm, short win)
244 {
245 int result=0;
246
247 if (!dpy) return -1;
248 /*---------------*/
249
250 struct fbui_ctrlparams ctl;
251 memset (&ctl, 0, sizeof (struct fbui_ctrlparams));
252 ctl.op = FBUI_REDRAW;
253 ctl.id = wm->id;
254 ctl.id2 = win;
255
256 return ioctl (dpy->fd, FBIO_UI_CONTROL, (unsigned long)&ctl) < 0 ? -errno : 0;
257 }
258
259
260
261 /* called only by wm */
262 int
263 fbui_move_resize (Display *dpy, Window *wm, short id, short x0, short y0, short x1, short y1)
264 {
265 int result=0;
266
267 if (!dpy) return -1;
268 /*---------------*/
269
270 if (x0>x1) { short tmp=x0;x0=x1;x1=tmp; }
271 if (y0>y1) { short tmp=y0;y0=y1;y1=tmp; }
272
273 struct fbui_ctrlparams ctl;
274 memset (&ctl, 0, sizeof (struct fbui_ctrlparams));
275 ctl.op = FBUI_MOVE_RESIZE;
276 ctl.id = wm->id;
277 ctl.id2 = id;
278 ctl.x = x0;
279 ctl.y = y0;
280 ctl.width = x1-x0+1;
281 ctl.height = y1-y0+1;
282
283 return ioctl (dpy->fd, FBIO_UI_CONTROL, (unsigned long)&ctl) < 0 ? -errno : 0;
284 }
285
286 /* called only by wm */
287 int
288 fbui_delete (Display *dpy, Window *wm, short id)
289 {
290 int result=0;
291
292 if (!dpy) return -1;
293 /*---------------*/
294
295 struct fbui_ctrlparams ctl;
296 memset (&ctl, 0, sizeof (struct fbui_ctrlparams));
297 ctl.op = FBUI_DELETE;
298 ctl.id = wm->id;
299 ctl.id2 = id;
300
301 int rv=1;
302 do {
303 rv = ioctl (dpy->fd, FBIO_UI_CONTROL, (unsigned long)&ctl);
304 if (rv < 0 && -errno != FBUI_ERR_DRAWING)
305 FATAL ("error when deleting window");
306 }
307 while (rv);
308
309 return 0;
310 }
311
312 /* called only by wm */
313 int
314 fbui_assign_keyfocus (Display *dpy, Window *wm, short id)
315 {
316 int result=0;
317
318 if (!dpy) return -1;
319 /*---------------*/
320
321 struct fbui_ctrlparams ctl;
322 memset (&ctl, 0, sizeof (struct fbui_ctrlparams));
323 ctl.op = FBUI_ASSIGN_KEYFOCUS;
324 ctl.id = wm->id;
325 ctl.id2 = id;
326
327 return ioctl (dpy->fd, FBIO_UI_CONTROL, (unsigned long)&ctl) < 0 ? -errno : 0;
328 }
329
330 /* called only by wm */
331 int
332 fbui_assign_pointerfocus (Display *dpy, Window *wm, short id)
333 {
334 int result=0;
335
336 if (!dpy) return -1;
337 /*---------------*/
338
339 struct fbui_ctrlparams ctl;
340 memset (&ctl, 0, sizeof (struct fbui_ctrlparams));
341 ctl.op = FBUI_ASSIGN_PTRFOCUS;
342 ctl.id = wm->id;
343 ctl.id2 = id;
344
345 return ioctl (dpy->fd, FBIO_UI_CONTROL, (unsigned long)&ctl) < 0 ? -errno : 0;
346 }
347
348 /* called only by wm */
349 int
350 fbui_hide (Display *dpy, Window *wm, short id)
351 {
352 int result=0;
353
354 if (!dpy) return -1;
355 /*---------------*/
356
357 struct fbui_ctrlparams ctl;
358 memset (&ctl, 0, sizeof (struct fbui_ctrlparams));
359 ctl.op = FBUI_HIDE;
360 ctl.id = wm->id;
361 ctl.id2 = id;
362
363 return ioctl (dpy->fd, FBIO_UI_CONTROL, (unsigned long)&ctl) < 0 ? -errno : 0;
364 }
365
366 /* called only by wm */
367 int
368 fbui_unhide (Display *dpy, Window *wm, short id)
369 {
370 int result=0;
371
372 if (!dpy) return -1;
373 /*---------------*/
374
375 struct fbui_ctrlparams ctl;
376 memset (&ctl, 0, sizeof (struct fbui_ctrlparams));
377 ctl.op = FBUI_UNHIDE;
378 ctl.id = wm->id;
379 ctl.id2 = id;
380
381 result = ioctl (dpy->fd, FBIO_UI_CONTROL, (unsigned long)&ctl);
382 if (result < 0)
383 result = -errno;
384 return result;
385 }
386
387 int
388 fbui_draw_point (Display *dpy, Window *win, short x, short y, unsigned long color)
389 {
390 int result=0;
391
392 if (!dpy || !win) return -1;
393 /*---------------*/
394 if (result = check_flush (dpy, win,5))
395 return result;
396
397 win->command [win->command_ix++] = FBUI_POINT;
398 win->command [win->command_ix++] = x;
399 win->command [win->command_ix++] = y;
400 win->command [win->command_ix++] = color;
401 win->command [win->command_ix++] = color>>16;
402
403 return 0;
404 }
405
406 unsigned long
407 fbui_read_point (Display *dpy, Window *win, short x, short y)
408 {
409 int result=0;
410
411 if (!dpy || !win) return -1;
412 /*---------------*/
413 if (result = check_flush (dpy, win,3))
414 return result;
415
416 win->command [win->command_ix++] = FBUI_READPOINT;
417 win->command [win->command_ix++] = x;
418 win->command [win->command_ix++] = y;
419
420 return fbui_flush (dpy, win);
421 }
422
423 int
424 fbui_draw_vline (Display *dpy, Window *win, short x, short y0, short y1, unsigned long color)
425 {
426 int result=0;
427
428 if (!dpy || !win) return -1;
429 /*---------------*/
430 if (result = check_flush (dpy, win,6))
431 return result;
432
433 win->command [win->command_ix++] = FBUI_VLINE;
434 win->command [win->command_ix++] = y0;
435 win->command [win->command_ix++] = y1;
436 win->command [win->command_ix++] = color;
437 win->command [win->command_ix++] = color>>16;
438 win->command [win->command_ix++] = x;
439
440 return 0;
441 }
442
443 int
444 fbui_tinyblit (Display *dpy, Window *win, short x, short y,
445 unsigned long color,
446 unsigned long bgcolor,
447 short width,
448 unsigned long bits)
449 {
450 int result=0;
451
452 if (!dpy || !win) return -1;
453 /*---------------*/
454 if (result = check_flush (dpy, win,10))
455 return result;
456
457 win->command [win->command_ix++] = FBUI_TINYBLIT;
458 win->command [win->command_ix++] = x;
459 win->command [win->command_ix++] = y;
460 win->command [win->command_ix++] = color;
461 win->command [win->command_ix++] = color>>16;
462 win->command [win->command_ix++] = bgcolor;
463 win->command [win->command_ix++] = bgcolor>>16;
464 win->command [win->command_ix++] = width;
465 win->command [win->command_ix++] = bits;
466 win->command [win->command_ix++] = bits>>16;
467
468 fbui_flush(dpy,win);
469
470 return 0;
471 }
472
473 int
474 fbui_draw_hline (Display *dpy, Window *win, short x0, short x1, short y, unsigned long color)
475 {
476 int result=0;
477
478 if (!dpy || !win) return -1;
479 /*---------------*/
480 if (result = check_flush (dpy, win,6))
481 return result;
482
483 win->command [win->command_ix++] = FBUI_HLINE;
484 win->command [win->command_ix++] = x0;
485 win->command [win->command_ix++] = x1;
486 win->command [win->command_ix++] = color;
487 win->command [win->command_ix++] = color>>16;
488 win->command [win->command_ix++] = y;
489
490 return 0;
491 }
492
493 int
494 fbui_draw_line (Display *dpy, Window *win, short x0, short y0, short x1, short y1, unsigned long color)
495 {
496 int result=0;
497
498 if (!dpy || !win) return -1;
499 /*---------------*/
500 if (result = check_flush (dpy, win,7))
501 return result;
502 win->command [win->command_ix++] = FBUI_LINE;
503 win->command [win->command_ix++] = x0;
504 win->command [win->command_ix++] = y0;
505 win->command [win->command_ix++] = x1;
506 win->command [win->command_ix++] = y1;
507 win->command [win->command_ix++] = color;
508 win->command [win->command_ix++] = color>>16;
509
510 return 0;
511 }
512
513
514 int
515 fbui_invert_line (Display *dpy, Window *win, short x0, short y0, short x1, short y1)
516 {
517 int result=0;
518
519 if (!dpy || !win) return -1;
520 /*---------------*/
521 if (result = check_flush (dpy, win,5))
522 return result;
523
524 win->command [win->command_ix++] = FBUI_INVERTLINE;
525 win->command [win->command_ix++] = x0;
526 win->command [win->command_ix++] = y0;
527 win->command [win->command_ix++] = x1;
528 win->command [win->command_ix++] = y1;
529
530 return 0;
531 }
532
533
534 int
535 fbui_draw_string (Display *dpy, Window *win, struct fbui_font *font,
536 short x0, short y0, char *str_,
537 unsigned long color)
538 {
539 int result=0;
540 unsigned long n;
541 unsigned long n2;
542 unsigned char *str = (unsigned char*) str_;
543
544 if (!dpy || !win || !str)
545 return -1;
546 /*---------------*/
547
548 if (result = check_flush (dpy, win,10))
549 return result;
550
551 if (!str) FATAL("null param3");
552
553 n = (unsigned long) str;
554 n2 = (unsigned long)font;
555
556 win->command [win->command_ix++] = FBUI_STRING;
557 win->command [win->command_ix++] = x0;
558 win->command [win->command_ix++] = y0;
559 win->command [win->command_ix++] = n2;
560 win->command [win->command_ix++] = n2>>16;
561 win->command [win->command_ix++] = strlen (str);
562 win->command [win->command_ix++] = n;
563 win->command [win->command_ix++] = n>>16;
564 win->command [win->command_ix++] = color;
565 win->command [win->command_ix++] = color>>16;
566
567 /* gotta flush, string may not last */
568 return fbui_flush (dpy, win);
569 }
570
571 int
572 fbui_set_subtitle (Display *dpy, Window *win, char *str)
573 {
574 struct fbui_ctrlparams ctl;
575
576 if (!dpy || !win || !str)
577 return FBUI_ERR_NULLPTR;
578
579 memset (&ctl, 0, sizeof (struct fbui_ctrlparams));
580 ctl.op = FBUI_SUBTITLE;
581 ctl.id = win->id;
582 strncpy (ctl.string, str, FBUI_NAMELEN);
583
584 return ioctl (dpy->fd, FBIO_UI_CONTROL, &ctl) < 0 ? -errno : 0;
585 }
586
587 int
588 fbui_set_font (Display *dpy, Window *win, struct fbui_font *font)
589 {
590 if (!dpy || !win || !font)
591 return -1;
592
593 struct fbui_ctrlparams ctl;
594 memset (&ctl, 0, sizeof (struct fbui_ctrlparams));
595 ctl.op = FBUI_SETFONT;
596 ctl.id = win->id;
597 ctl.pointer = (unsigned char*) font;
598
599 return ioctl (dpy->fd, FBIO_UI_CONTROL, (unsigned long) &ctl) < 0 ? -errno : 0;
600 }
601
602
603 int
604 fbui_clear (Display *dpy, Window *win)
605 {
606 int result=0;
607
608 if (!dpy || !win) return -1;
609 /*---------------*/
610 if (result = check_flush (dpy, win,1))
611 return result;
612
613 win->command [win->command_ix++] = FBUI_CLEAR;
614
615 return 0;
616 }
617
618 int
619 fbui_draw_rect (Display *dpy, Window *win, short x0, short y0, short x1, short y1, unsigned long color)
620 {
621 int result=0;
622
623 if (!dpy || !win) return -1;
624 /*---------------*/
625 if (result = check_flush (dpy, win,7))
626 return result;
627
628 win->command [win->command_ix++] = FBUI_RECT;
629 win->command [win->command_ix++] = x0;
630 win->command [win->command_ix++] = y0;
631 win->command [win->command_ix++] = x1;
632 win->command [win->command_ix++] = y1;
633 win->command [win->command_ix++] = color;
634 win->command [win->command_ix++] = color>>16;
635
636 return 0;
637 }
638
639 int
640 fbui_fill_area (Display *dpy, Window *win, short x0, short y0, short x1, short y1, unsigned long color)
641 {
642 int result=0;
643
644 if (!dpy || !win) return -1;
645 /*---------------*/
646 if (result = check_flush (dpy, win,7))
647 return result;
648
649 win->command [win->command_ix++] = FBUI_FILLAREA;
650 win->command [win->command_ix++] = x0;
651 win->command [win->command_ix++] = y0;
652 win->command [win->command_ix++] = x1;
653 win->command [win->command_ix++] = y1;
654 win->command [win->command_ix++] = color;
655 win->command [win->command_ix++] = color>>16;
656
657 return 0;
658 }
659
660 int
661 fbui_clear_area (Display *dpy, Window *win, short x0, short y0, short x1, short y1)
662 {
663 int result=0;
664
665 if (!dpy || !win) return -1;
666 /*---------------*/
667 if (result = check_flush (dpy, win,5))
668 return result;
669
670 win->command [win->command_ix++] = FBUI_CLEARAREA;
671 win->command [win->command_ix++] = x0;
672 win->command [win->command_ix++] = y0;
673 win->command [win->command_ix++] = x1;
674 win->command [win->command_ix++] = y1;
675
676 return 0;
677 }
678
679 int
680 fbui_copy_area (Display *dpy, Window *win, short xsrc, short ysrc, short xdest, short ydest, short w, short h)
681 {
682 int result=0;
683
684 if (!dpy || !win) return -1;
685 /*---------------*/
686 if (result = check_flush (dpy, win,7))
687 return result;
688
689 win->command [win->command_ix++] = FBUI_COPYAREA;
690 win->command [win->command_ix++] = xsrc;
691 win->command [win->command_ix++] = ysrc;
692 win->command [win->command_ix++] = xdest;
693 win->command [win->command_ix++] = ydest;
694 win->command [win->command_ix++] = w;
695 win->command [win->command_ix++] = h;
696
697 return 0;
698 }
699
700 int
701 fbui_put (Display *dpy, Window *win, short x, short y, short n, unsigned char *p)
702 {
703 int result=0;
704
705 if (!dpy || !win || !p) return -1;
706 /*---------------*/
707 if (result = check_flush (dpy, win,6))
708 return result;
709
710 win->command [win->command_ix++] = FBUI_PUT;
711 win->command [win->command_ix++] = x;
712 win->command [win->command_ix++] = y;
713 win->command [win->command_ix++] = (unsigned long)p;
714 win->command [win->command_ix++] = ((unsigned long)p)>>16;
715 win->command [win->command_ix++] = n;
716
717 return 0;
718 }
719
720 int
721 fbui_put_rgb (Display *dpy, Window *win, short x, short y, short n, unsigned long *p)
722 {
723 int result=0;
724
725 if (!dpy || !win || !p) return -1;
726 /*---------------*/
727 if (result = check_flush (dpy, win,6))
728 return result;
729
730 win->command [win->command_ix++] = FBUI_PUTRGB;
731 win->command [win->command_ix++] = x;
732 win->command [win->command_ix++] = y;
733 win->command [win->command_ix++] = (unsigned long) p;
734 win->command [win->command_ix++] = ((unsigned long) p) >>16;
735 win->command [win->command_ix++] = n;
736
737 return 0;
738 }
739
740 int
741 fbui_put_rgb3 (Display *dpy, Window *win, short x, short y, short n, unsigned char *p)
742 {
743 int result=0;
744
745 if (!dpy || !win || !p) return -1;
746 /*---------------*/
747 if (result = check_flush (dpy, win,6))
748 return result;
749
750 win->command [win->command_ix++] = FBUI_PUTRGB3;
751 win->command [win->command_ix++] = x;
752 win->command [win->command_ix++] = y;
753 win->command [win->command_ix++] = (unsigned long) p;
754 win->command [win->command_ix++] = ((unsigned long) p) >>16;
755 win->command [win->command_ix++] = n;
756
757 return 0;
758 }
759
760
761 int
762 fbui_window_close (Display *dpy, Window *win)
763 {
764 int r;
765
766 if (!dpy || !win) return -1;
767 /*---------------*/
768 // fbui_flush (dpy, win);
769
770 r = ioctl (dpy->fd, FBIO_UI_CLOSE, win->id);
771
772 Window *prev = NULL;
773 Window *ptr = dpy->list;
774 while (ptr) {
775 if (win == ptr)
776 break;
777 prev = ptr;
778 ptr = ptr->next;
779 }
780 if (ptr) {
781 if (!prev)
782 dpy->list = win->next;
783 else
784 prev->next = win->next;
785 }
786
787 free (win);
788 return r;
789 }
790
791
792
793 // key info that comes from FBUI : bits 0-1= state 2-15=keycode
794 int
795 fbui_convert_key (Display *dpy, long keyinfo)
796 {
797 int key,state;
798 unsigned short ch=0;
799
800 if (!dpy) return -1;
801 /*---------------*/
802
803 state = 3 & keyinfo;
804 key = keyinfo >> 2;
805
806 switch (key) {
807 case KEY_RIGHTSHIFT:
808 case KEY_LEFTSHIFT:
809 dpy->shift = state>0;
810 return 0;
811
812 case KEY_RIGHTCTRL:
813 case KEY_LEFTCTRL:
814 dpy->ctrl = state>0;
815 return 0;
816
817 case KEY_RIGHTALT:
818 case KEY_LEFTALT:
819 dpy->alt = state>0;
820 return 0;
821 }
822
823 if (state==0)
824 return 0;
825
826 switch (key) {
827 case KEY_ENTER: ch = '\n'; break;
828 case KEY_ESC: ch = 27; break;
829 case KEY_SPACE: ch = ' '; break;
830 case KEY_MINUS: ch = !dpy->shift ? '-' : '_'; break;
831 case KEY_EQUAL: ch = !dpy->shift ? '=' : '+'; break;
832 case KEY_BACKSPACE: ch = 8; break;
833 case KEY_SEMICOLON: ch = !dpy->shift ? ';' : ':'; break;
834 case KEY_COMMA: ch = !dpy->shift ? ',' : '<'; break;
835 case KEY_DOT: ch = !dpy->shift ? '.' : '>'; break;
836 case KEY_GRAVE: ch = !dpy->shift ? '`' : '~'; break;
837 case KEY_BACKSLASH: ch = !dpy->shift ? '\\' : '|'; break;
838 case KEY_LEFTBRACE: ch = !dpy->shift ? '[' : '{'; break;
839 case KEY_RIGHTBRACE: ch = !dpy->shift ? ']' : '}'; break;
840 case KEY_APOSTROPHE: ch = !dpy->shift ? '\'' : '"'; break;
841 case KEY_SLASH: ch = !dpy->shift ? '/' : '?'; break;
842 case KEY_TAB: ch = !dpy->shift ? '\t' : FBUI_LEFTTAB; break;
843 case KEY_A: ch = 'a'; break;
844 case KEY_B: ch = 'b'; break;
845 case KEY_C: ch = 'c'; break;
846 case KEY_D: ch = 'd'; break;
847 case KEY_E: ch = 'e'; break;
848 case KEY_F: ch = 'f'; break;
849 case KEY_G: ch = 'g'; break;
850 case KEY_H: ch = 'h'; break;
851 case KEY_I: ch = 'i'; break;
852 case KEY_J: ch = 'j'; break;
853 case KEY_K: ch = 'k'; break;
854 case KEY_L: ch = 'l'; break;
855 case KEY_M: ch = 'm'; break;
856 case KEY_N: ch = 'n'; break;
857 case KEY_O: ch = 'o'; break;
858 case KEY_P: ch = 'p'; break;
859 case KEY_Q: ch = 'q'; break;
860 case KEY_R: ch = 'r'; break;
861 case KEY_S: ch = 's'; break;
862 case KEY_T: ch = 't'; break;
863 case KEY_U: ch = 'u'; break;
864 case KEY_V: ch = 'v'; break;
865 case KEY_W: ch = 'w'; break;
866 case KEY_X: ch = 'x'; break;
867 case KEY_Y: ch = 'y'; break;
868 case KEY_Z: ch = 'z'; break;
869 case KEY_0: ch = '0'; break;
870 case KEY_1: ch = '1'; break;
871 case KEY_2: ch = '2'; break;
872 case KEY_3: ch = '3'; break;
873 case KEY_4: ch = '4'; break;
874 case KEY_5: ch = '5'; break;
875 case KEY_6: ch = '6'; break;
876 case KEY_7: ch = '7'; break;
877 case KEY_8: ch = '8'; break;
878 case KEY_9: ch = '9'; break;
879
880 /* special chars section */
881 case KEY_UP: ch = FBUI_UP; break;
882 case KEY_DOWN: ch = FBUI_DOWN; break;
883 case KEY_LEFT: ch = FBUI_LEFT; break;
884 case KEY_RIGHT: ch = FBUI_RIGHT; break;
885
886 case KEY_INSERT: ch = FBUI_INS; break;
887 case KEY_DELETE: ch = FBUI_DEL; break;
888 case KEY_HOME: ch = FBUI_HOME; break;
889 case KEY_END: ch = FBUI_END; break;
890 case KEY_PAGEUP: ch = FBUI_PGUP; break;
891 case KEY_PAGEDOWN: ch = FBUI_PGDN; break;
892 case KEY_SCROLLLOCK: ch = FBUI_SCRLK; break;
893 case KEY_NUMLOCK: ch = FBUI_NUMLK; break;
894 case KEY_CAPSLOCK: ch = FBUI_CAPSLK; break;
895
896 case KEY_PRINT: ch = FBUI_PRTSC; break;
897
898 case KEY_F1: ch = FBUI_F1; break;
899 case KEY_F2: ch = FBUI_F2; break;
900 case KEY_F3: ch = FBUI_F3; break;
901 case KEY_F4: ch = FBUI_F4; break;
902 case KEY_F5: ch = FBUI_F5; break;
903 case KEY_F6: ch = FBUI_F6; break;
904 case KEY_F7: ch = FBUI_F7; break;
905 case KEY_F8: ch = FBUI_F8; break;
906 case KEY_F9: ch = FBUI_F9; break;
907 case KEY_F10: ch = FBUI_F10; break;
908 case KEY_F11: ch = FBUI_F11; break;
909 case KEY_F12: ch = FBUI_F12; break;
910
911 /* mouse buttons */
912 case BTN_LEFT: ch = FBUI_BUTTON_LEFT; break;
913 case BTN_RIGHT: ch = FBUI_BUTTON_RIGHT; break;
914 case BTN_MIDDLE: ch = FBUI_BUTTON_MIDDLE; break;
915 }
916
917 if (dpy->ctrl && isalpha(ch))
918 ch &= 31;
919 else
920 if (dpy->shift && isalpha(ch))
921 ch = toupper(ch);
922
923 if (dpy->shift && isdigit(ch)) {
924 switch (ch) {
925 case '0': ch = ')'; break;
926 case '1': ch = '!'; break;
927 case '2': ch = '@'; break;
928 case '3': ch = '#'; break;
929 case '4': ch = '$'; break;
930 case '5': ch = '%'; break;
931 case '6': ch = '^'; break;
932 case '7': ch = '&'; break;
933 case '8': ch = '*'; break;
934 case '9': ch = '('; break;
935 }
936 }
937
938 return ch;
939 }
940
941
942 int
943 fbui_poll_event (Display *dpy, Event *e, unsigned short mask)
944 {
945 Window *win;
946 short win_id;
947 long retval;
948
949 if (!dpy || !e)
950 return -1;
951 /*---------------*/
952 win = dpy->list;
953 while (win) {
954 fbui_flush (dpy, win);
955 win = win->next;
956 }
957
958 memset (e, 0, sizeof(Event));
959
960 struct fbui_event event;
961 struct fbui_ctrlparams ctl;
962 memset (&ctl, 0, sizeof (struct fbui_ctrlparams));
963 ctl.op = FBUI_POLLEVENT;
964 ctl.id = dpy->list ? dpy->list->id : -1; /* window id not required but faster */
965 ctl.x = (short)mask;
966 ctl.event = &event;
967 retval = ioctl (dpy->fd, FBIO_UI_CONTROL, &ctl);
968
969 if (retval < 0)
970 return -errno;
971
972 e->type = event.type;
973 e->id = win_id = event.id;
974 e->key = event.key;
975 e->x = event.x;
976 e->y = event.y;
977 e->width = event.width;
978 e->height = event.height;
979
980 win = dpy->list;
981 while (win) {
982 if (win->id == win_id)
983 break;
984 win = win->next;
985 }
986 e->win = win;
987
988 if (!win)
989 fprintf(stderr, "libfbui: cannot identify window for id %d\n", win_id);
990 else
991 if (event.type == FBUI_MOVE_RESIZE) {
992 win->width = event.width;
993 win->height = event.height;
994 }
995
996 return 0;
997 }
998
999 int
1000 fbui_wait_event (Display *dpy, Event *e, unsigned short mask)
1001 {
1002 Window *win;
1003
1004 if (!dpy || !e)
1005 return -1;
1006 /*---------------*/
1007
1008 win = dpy->list;
1009 while (win) {
1010 fbui_flush (dpy, win);
1011 win = win->next;
1012 }
1013
1014 memset (e, 0, sizeof(Event));
1015
1016 struct fbui_event event;
1017 struct fbui_ctrlparams ctl;
1018 memset (&ctl, 0, sizeof (struct fbui_ctrlparams));
1019 ctl.op = FBUI_WAITEVENT;
1020 ctl.id = dpy->list ? dpy->list->id : -1; /* window id not required but faster */
1021 ctl.x = (short)mask;
1022 ctl.event = &event;
1023 int retval = ioctl (dpy->fd, FBIO_UI_CONTROL, &ctl);
1024
1025 if (retval < 0)
1026 return -errno;
1027
1028 e->type = event.type;
1029 short win_id = event.id;
1030 e->id = win_id;
1031 e->key = event.key;
1032 e->x = event.x;
1033 e->y = event.y;
1034 e->width = event.width;
1035 e->height = event.height;
1036
1037 win = dpy->list;
1038 while (win) {
1039 if (win->id == win_id)
1040 break;
1041 win = win->next;
1042 }
1043 e->win = win;
1044
1045 if (!win)
1046 fprintf(stderr, "libfbui: cannot identify window for id %d\n", win_id);
1047 else
1048 if (event.type == FBUI_MOVE_RESIZE) {
1049 win->width = event.width;
1050 win->height = event.height;
1051 }
1052
1053
1054 return 0;
1055 }
1056
1057 int
1058 fbui_get_dims (Display *dpy, Window *win, short *width, short *height)
1059 {
1060 long result;
1061
1062 if (!dpy || !win || !width || !height)
1063 return -1;
1064 /*---------------*/
1065
1066 fbui_flush (dpy, win);
1067
1068 *width = 0;
1069 *height = 0;
1070
1071 struct fbui_ctrlparams ctl;
1072 memset (&ctl, 0, sizeof (struct fbui_ctrlparams));
1073 ctl.op = FBUI_GETDIMS;
1074 ctl.id = win->id;
1075
1076 result = ioctl (dpy->fd, FBIO_UI_CONTROL, &ctl);
1077 //printf ("getdims retval %d (%d)\n",result,-errno);
1078 if (result < 0)
1079 return -errno;
1080
1081 *width = result >> 16;
1082 *height = result & 0xffff;
1083
1084 win->width = *width;
1085 win->height = *height;
1086
1087 return 0;
1088 }
1089
1090
1091 /* note: mouse buttons appear as keystrokes */
1092 int
1093 fbui_read_mouse (Display *dpy, Window *win, short *x, short *y)
1094 {
1095 long result;
1096
1097 if (!dpy || !win || !x || !y)
1098 return -1;
1099 /*---------------*/
1100
1101 fbui_flush (dpy, win);
1102
1103 *x = 0;
1104 *y = 0;
1105
1106 struct fbui_ctrlparams ctl;
1107 memset (&ctl, 0, sizeof (struct fbui_ctrlparams));
1108 ctl.op = FBUI_READMOUSE;
1109 ctl.id = win->id;
1110
1111 result = ioctl (dpy->fd, FBIO_UI_CONTROL, &ctl);
1112 if (result < 0)
1113 return result;
1114
1115 *x = result >> 16;
1116 *y = result & 0xffff;
1117
1118 return 0;
1119 }
1120
1121
1122 int
1123 fbui_get_position (Display *dpy, Window *win, short *x, short *y)
1124 {
1125 unsigned long result;
1126
1127 if (!dpy || !win || !x || !y)
1128 return -1;
1129 /*---------------*/
1130
1131 fbui_flush (dpy, win);
1132
1133 *x = -1;
1134 *y = -1;
1135
1136 struct fbui_ctrlparams ctl;
1137 memset (&ctl, 0, sizeof (struct fbui_ctrlparams));
1138 ctl.op = FBUI_GETPOSN;
1139
1140 result = ioctl (dpy->fd, FBIO_UI_CONTROL, &ctl);
1141 if (result < 0)
1142 return 0;
1143
1144 *x = result >> 16;
1145 *y = result & 0xffff;
1146
1147 return 1;
1148 }
1149
1150 static void kill_handler (int foo)
1151 {
1152 if (my_dpy) {
1153 Window *win = my_dpy->list;
1154 while (win) {
1155 Window *next = win->next;
1156 fbui_window_close (my_dpy, win);
1157 win = next;
1158 }
1159 my_dpy->list = NULL;
1160 fbui_display_close (my_dpy);
1161 }
1162 exit(-1);
1163 }
1164
1165 static int hex_to_int (char h)
1166 {
1167 h = tolower(h);
1168 if (h >= '0' && h <= '9')
1169 return h - '0';
1170 else
1171 if (h >= 'a' && h <= 'f')
1172 return 10 + h - 'a';
1173 else
1174 return 0;
1175 }
1176
1177 static long parse_rgb (char *s)
1178 {
1179 int len;
1180 long c;
1181 if (!s) return -1;
1182 len = strlen (s);
1183 if (len == 3) {
1184 c = hex_to_int (*s++);
1185 c <<= 8;
1186 c |= hex_to_int (*s++);
1187 c <<= 8;
1188 c |= hex_to_int (*s++);
1189 c <<= 4;
1190 return c;
1191 }
1192 if (len == 6) {
1193 c = hex_to_int (*s++);
1194 c <<= 4;
1195 c |= hex_to_int (*s++);
1196 c <<= 4;
1197 c |= hex_to_int (*s++);
1198 c <<= 4;
1199 c |= hex_to_int (*s++);
1200 c <<= 4;
1201 c |= hex_to_int (*s++);
1202 c <<= 4;
1203 c |= hex_to_int (*s++);
1204 return c;
1205 }
1206 return -1;
1207 }
1208
1209
1210 static int
1211 getline (FILE *f, char *buf, int buflen)
1212 {
1213 int got;
1214 char ch;
1215 int ix=0;
1216
1217 buf[0] = 0;
1218
1219 while (ix < (buflen-1)) {
1220 got = fread (&ch, 1, 1, f);
1221
1222 if (!got)
1223 break;
1224
1225 if (ch == '\n')
1226 break;
1227 if (ch == '\r')
1228 continue;
1229
1230 buf [ix++] = ch;
1231 }
1232
1233 buf [ix] = 0;
1234 return ix;
1235 }
1236
1237 long
1238 parse_colorname (char *s)
1239 {
1240 if (!strcmp(s, "red"))
1241 return RGB_RED;
1242 if (!strcmp(s, "green"))
1243 return RGB_GREEN;
1244 if (!strcmp(s, "blue"))
1245 return RGB_BLUE;
1246 if (!strcmp(s, "black"))
1247 return 0;
1248 if (!strcmp(s, "white"))
1249 return 0xffffff;
1250 if (!strcmp(s, "steelblue"))
1251 return RGB_STEELBLUE;
1252 if (!strcmp(s, "sienna"))
1253 return RGB_SIENNA;
1254 if (!strcmp(s, "cyan"))
1255 return RGB_CYAN;
1256 if (!strcmp(s, "orange"))
1257 return RGB_ORANGE;
1258 if (!strcmp(s, "yellow"))
1259 return RGB_YELLOW;
1260 if (!strcmp(s, "magenta"))
1261 return RGB_MAGENTA;
1262 if (!strcmp(s, "purple"))
1263 return RGB_PURPLE;
1264 if (!strcmp(s, "brown"))
1265 return RGB_BROWN;
1266 if (!strcmp(s, "gray"))
1267 return RGB_GRAY;
1268
1269 FILE *f = fopen ("/usr/X11/lib/X11/rgb.txt","r");
1270 char buffer [200];
1271 if (!f) return -1;
1272 while (getline (f, buffer, 199)) {
1273 int r,g,b;
1274 char name[100];
1275 if (4 == sscanf(buffer,"%u %u %u %s", &r, &g, &b, name)) {
1276 if (!strcmp (s, name)) {
1277 long color;
1278 r &= 0xff;
1279 g &= 0xff;
1280 b &= 0xff;
1281 color = r;
1282 color <<= 8;
1283 color |= g;
1284 color <<= 8;
1285 color |= b;
1286 fclose(f);
1287 return color;
1288 }
1289 }
1290 }
1291 fclose(f);
1292
1293 return -1;
1294 }
1295
1296
1297 /* not static since it's used by fbterm */
1298
1299 int fbui_parse_geom (char *s1, short *w, short *h, short *xr, short *yr)
1300 {
1301 short width=0,height=0,xrel=-1,yrel=-1;
1302 char *s2 = NULL;
1303 char *s3 = NULL;
1304 char *s4 = NULL;
1305
1306 if (!s1 || !w || !h || !xr || !yr)
1307 return 0;
1308 /*---------------*/
1309
1310 if (*s1 && isdigit(*s1)) {
1311 char *s2 = strchr (s1, 'x');
1312 if (!s2)
1313 return 0;
1314 *s2++ = 0;
1315
1316 s3 = s2;
1317 while (*s3 && isdigit(*s3))
1318 s3++;
1319
1320 if (*s3) {
1321 xrel = *s3=='-' ? -1 : 1;
1322 *s3++ = 0;
1323
1324 s4 = s3;
1325 while (*s4 && isdigit(*s4))
1326 s4++;
1327
1328 if (s4) {
1329 yrel = *s4=='-' ? -1 : 1;
1330 *s4++ = 0;
1331 }
1332 } else {
1333 xrel = 9999; /* no position given */
1334 s3 = NULL;
1335 }
1336
1337 width = atoi(s1);
1338 height = atoi(s2);
1339
1340 if (s3 && s4) {
1341 int a = atoi(s3);
1342 int b = atoi(s4);
1343 if (xrel == 1) {
1344 xrel = a;
1345 } else {
1346 xrel = -a - 1;
1347 }
1348 if (yrel == 1) {
1349 yrel = b;
1350 } else {
1351 yrel = -b - 1;
1352 }
1353 } else {
1354 xrel = 9999;
1355 }
1356 *w = width;
1357 *h = height;
1358 *xr = xrel;
1359 *yr = yrel;
1360 return 1;
1361 } else
1362 return 0;
1363 }
1364
1365
1366 void
1367 fbui_display_close (Display* dpy)
1368 {
1369 if (dpy) {
1370 Window *win = dpy->list;
1371 while (win) {
1372 fbui_window_close (dpy, win);
1373 win = win->next;
1374 }
1375 close (dpy->fd);
1376 free (dpy);
1377 }
1378 }
1379
1380 Display*
1381 fbui_display_open ()
1382 {
1383 Display *dpy = NULL;
1384 int success=0;
1385 int fd;
1386
1387 if (my_dpy)
1388 FATAL ("attempt to re-init");
1389
1390 fd = open ("/dev/fb0", O_RDWR );
1391 if (fd < 0)
1392 fd = open ("/dev/fb/0", O_RDWR );
1393 display_fd = fd;
1394 if (fd < 0)
1395 {
1396 success= 0;
1397 perror("open");
1398 errlog(__FUNCTION__, "Open failed");
1399 }
1400 else
1401 {
1402 if (ioctl (fd, FBIOGET_FSCREENINFO, &fi))
1403 {
1404 perror("ioctl");
1405 success= 0;
1406 errlog(__FUNCTION__, "ioctl1 failed");
1407 }
1408 else
1409 if (ioctl (fd, FBIOGET_VSCREENINFO, &vi))
1410 {
1411 perror("ioctl");
1412 success= 0;
1413 errlog(__FUNCTION__, "ioctl2 failed");
1414 }
1415 else
1416 {
1417 if (fi.visual != FB_VISUAL_TRUECOLOR &&
1418 fi.visual != FB_VISUAL_DIRECTCOLOR )
1419 {
1420 FATAL ("Oops, we need a direct/truecolor display");
1421 success= 0;
1422 errlog(__FUNCTION__, "wrong visual");
1423 }
1424 else
1425 {
1426 printf ("Framebuffer resolution: %dx%d, %dbpp\n", vi.xres, vi.yres, vi.bits_per_pixel);
1427
1428 success = 1;
1429 }
1430 }
1431 }
1432
1433 if (success) {
1434 dpy = (Display*) malloc (sizeof(Display));
1435 if (!dpy) {
1436 fprintf (stderr, "out of memory\n");
1437 return NULL;
1438 }
1439
1440 my_dpy = dpy;
1441 memset ((void*)dpy, 0, sizeof(Display));
1442 dpy->fd = fd;
1443
1444 dpy->width = vi.xres;
1445 dpy->height = vi.yres;
1446 dpy->depth = vi.bits_per_pixel;
1447
1448 dpy->red_offset = vi.red.offset;
1449 dpy->green_offset = vi.green.offset;
1450 dpy->blue_offset = vi.blue.offset;
1451 dpy->red_length = vi.red.length;
1452 dpy->green_length = vi.green.length;
1453 dpy->blue_length = vi.blue.length;
1454
1455 signal (SIGTERM, kill_handler);
1456 signal (SIGINT, kill_handler);
1457 signal (SIGSEGV, kill_handler);
1458 }
1459 return dpy;
1460 }
1461
1462 Window*
1463 fbui_window_open (Display *dpy,
1464 short width, short height,
1465 short *width_return, short *height_return,
1466 short max_width, short max_height,
1467 short xrel, short yrel,
1468 unsigned long *fgcolor_inout,
1469 unsigned long *bgcolor_inout,
1470 char *name, char *subtitle,
1471 char program_type,
1472 char request_control,
1473 char doing_autopositioning,
1474 char vc_,
1475 char need_keys,
1476 char receive_all_motion,
1477 char initially_hidden,
1478 int argc, char **argv)
1479 {
1480 int i;
1481 char vc=-1;
1482 long fgcolor;
1483 long bgcolor;
1484 Window *win = NULL;
1485 char force_type = -1;
1486
1487 if (!dpy || !name || !width_return || !height_return ||
1488 !fgcolor_inout || !bgcolor_inout)
1489 {
1490 WARNING ("null param");
1491 return NULL;
1492 }
1493 /*---------------*/
1494 fgcolor = *fgcolor_inout;
1495 bgcolor = *bgcolor_inout;
1496
1497 i=1;
1498 if (argv)
1499 while(i < argc) {
1500 char *str = argv[i];
1501 if (!strncmp(str, "-type=",6)) {
1502 char *tstr = str+6;
1503 if (!strcmp (tstr, "app"))
1504 force_type = FBUI_PROGTYPE_APP;
1505 else if (strcmp (tstr, "launcher"))
1506 force_type = FBUI_PROGTYPE_LAUNCHER;
1507 else if (strcmp (tstr, "tool"))
1508 force_type = FBUI_PROGTYPE_TOOL;
1509 else if (strcmp (tstr, "emphemeral"))
1510 force_type = FBUI_PROGTYPE_EPHEMERAL;
1511 else if (strcmp (tstr, "none"))
1512 force_type = FBUI_PROGTYPE_NONE;
1513 }
1514 else if (!strncmp(str, "-geo",4)) {
1515 int ch = str[4];
1516 char *values=NULL;
1517 *str = 0;
1518 if (ch && isdigit(ch)) {
1519 values = str+4;
1520 } else {
1521 if (i != (argc-1)) {
1522 values = argv[++i];
1523 argv[i][0] = 0;
1524 }
1525 }
1526
1527 if (values) {
1528 short w,h,xr,yr;
1529 if (fbui_parse_geom (values,&w,&h,&xr,&yr)) {
1530 width = w;
1531 height = h;
1532 if (xr != 9999) {
1533 xrel = xr;
1534 yrel = yr;
1535 }
1536 }
1537 }
1538 }
1539 else
1540 if (!strncmp (str, "-bg", 3) || !strncmp(str, "-fg",3)) {
1541 char *s = 3 + str;
1542 char which = str[1];
1543 char ch = *s;
1544 long color = -1;
1545 *str = 0;
1546 if (ch == '=')
1547 ch = *++s;
1548 if (!ch) {
1549 s = argv[++i];
1550 ch = s ? *s : 0;
1551 }
1552 if (ch == '#') {
1553 color = parse_rgb (s+1);
1554 }
1555 else if (ch) {
1556 color = parse_colorname (s);
1557 }
1558 if (color != -1) {
1559 if (which == 'f')
1560 fgcolor = color;
1561 else
1562 bgcolor = color;
1563 }
1564 argv[i][0] = 0;
1565 }
1566 else
1567 if (!strncmp(str, "-c",2)) {
1568 char *s = 2 + str;
1569 if (*s && isdigit(*s)) {
1570 vc = atoi(s);
1571 *str = 0;
1572 } else {
1573 *str = 0;
1574 if (i != (argc-1)) {
1575 vc = atoi(argv[++i]);
1576 *argv[i] = 0;
1577 } else {
1578 fprintf(stderr, "Usage: %s [-cCONSOLE#] [-fgCOLOR] [-bgCOLOR]\n", argv[0]);
1579 }
1580 }
1581 }
1582 i++;
1583 }
1584 if (vc_ != -1 && vc == -1)
1585 vc = vc_;
1586
1587 if (width > max_width)
1588 width = max_width;
1589 if (height > max_height)
1590 height = max_height;
1591
1592 int result;
1593
1594 oi.req_control = request_control ? 1 : 0;
1595 oi.x0 = xrel >= 0 ? xrel : vi.xres + xrel + 1 - width;
1596 oi.y0 = yrel >= 0 ? yrel : vi.yres + yrel + 1 - height;
1597 oi.x1= oi.x0 + width - 1;
1598 oi.y1= oi.y0 + height - 1;
1599 oi.max_width = max_width;
1600 oi.max_height = max_height;
1601 oi.bgcolor = bgcolor;
1602 oi.initially_hidden = initially_hidden;
1603 *fgcolor_inout = fgcolor;
1604 *bgcolor_inout = bgcolor;
1605 printf ("vc=%d\n",vc);
1606 oi.desired_vc = vc;
1607 oi.doing_autoposition = doing_autopositioning ? 1 : 0;
1608 oi.need_keys = need_keys ? 1 : 0;
1609 oi.receive_all_motion = receive_all_motion ? 1 : 0;
1610 oi.program_type = force_type >= 0 ? force_type : program_type;
1611 strncpy (oi.name, name, FBUI_NAMELEN);
1612 strncpy (oi.subtitle, subtitle, FBUI_NAMELEN);
1613 result = ioctl (dpy->fd, FBIO_UI_OPEN, &oi);
1614 if (result < 0)
1615 {
1616 char expr[100];
1617 sprintf (expr, "errcode %d\n",result);
1618 errlog(__FUNCTION__, expr);
1619 return NULL;
1620 }
1621
1622 win = (Window*) malloc (sizeof(Window));
1623 if (!win)
1624 FATAL ("out of memory");
1625 memset (win, 0, sizeof (Window));
1626
1627 win->id = result;
1628 win->command_ix = 2;
1629 win->next = dpy->list;
1630 dpy->list = win;
1631
1632 short w,h;
1633
1634 while (fbui_get_dims (dpy, win, &w, &h)) {
1635 printf ("%s: waiting for window dimensions\n", __FUNCTION__);
1636 sleep (1);
1637 }
1638
1639 *width_return = w;
1640 *height_return = h;
1641
1642 return win;
1643 }
1644
1645
1646 Font *
1647 font_new (void)
1648 {
1649 Font *nu;
1650 nu = (Font*) malloc(sizeof (Font));
1651 if (!nu)
1652 FATAL("out of memory")
1653 else
1654 {
1655 memset ((void*) nu, 0, sizeof (Font));
1656 nu->bitmap_buffer = NULL;
1657 // nu->dpi = 0;
1658 nu->ascent = 0;
1659 nu->descent = 0;
1660 }
1661 return nu;
1662 }
1663
1664 void
1665 font_free (Font* font)
1666 {
1667 int i;
1668 if (!font)
1669 return; // error
1670
1671 if (font->lefts)
1672 free ((void*) font->lefts);
1673 if (font->widths)
1674 free ((void*) font->widths);
1675 if (font->descents)
1676 free ((void*) font->descents);
1677 if (font->widths)
1678 free ((void*) font->widths);
1679 if (font->heights)
1680 free ((void*) font->heights);
1681 if (font->bitmaps)
1682 free ((void*) font->bitmaps);
1683
1684 free ((void*)font);
1685 }
1686
1687
1688 void
1689 font_char_dims (Font *font, uchar ch, short *w, short *asc, short *desc)
1690 {
1691 if (!font || !w || !asc || !desc)
1692 return; // error
1693
1694 ch -= font->first_char;
1695 *w = font->widths[ch];
1696 *asc = font->ascent;
1697 *desc = font->descent;
1698 }
1699
1700
1701 void
1702 font_string_dims (Font *font, unsigned char *str, short *w, short *a, short *d)
1703 {
1704 if (!font || !str || !w || !a || !d)
1705 return; // error
1706
1707 short w0 = 0;
1708 int ch;
1709
1710 while ((ch = *str++)) {
1711 ch -= font->first_char;
1712 if (ch >= 0)
1713 w0 += font->widths [ch];
1714 }
1715
1716 *w = w0;
1717 *a = font->ascent;
1718 *d = font->descent;
1719 }
1720
1721
1722
1723 static uchar bit_reversal_array [256] =
1724 {
1725 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 0x15, 0x95,
1726 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
1727 };
1728
1729
1730 #define ZZ(a,b,c,d) ((((unsigned long)d)<<24)|(((unsigned long)c)<<16)|(((unsigned short)b)<<8)|a)
1731
1732
1733 inline unsigned long ULONG(char endian, unsigned char* pp)
1734 {
1735 if (endian)
1736 return (((unsigned long)pp[0]) << 24) | (((unsigned long)pp[1]) << 16) | (((unsigned short)pp[2]) << 8) | pp[3];
1737 else
1738 return (((unsigned long)pp[3]) << 24) | (((unsigned long)pp[2]) << 16) | (((unsigned short)pp[1]) << 8) | pp[0];
1739 }
1740
1741
1742 inline unsigned short USHORT(char endian, unsigned char* pp)
1743 {
1744 unsigned short i;
1745
1746 if (endian)
1747 i = (((unsigned short)pp[0]) << 8) | pp[1];
1748 else
1749 i = (((unsigned short)pp[1]) << 8) | pp[0];
1750
1751 return i;
1752 }
1753
1754
1755 enum {
1756 PCF_PROPS = 1,
1757 PCF_ACCEL = 2,
1758 PCF_METRICS = 4,
1759 PCF_BITMAPS = 8,
1760 PCF_INK_METRICS = 16,
1761 PCF_BDF_ENCODINGS = 32,
1762 PCF_SWIDTHS = 64,
1763 PCF_GLYPH_NAMES = 128,
1764 PCF_BDF_ACCEL = 256,
1765
1766 };
1767
1768 enum {
1769 PCF_BIG_ENDIAN = (1<<2),
1770 PCF_COMPRESSED = 256,
1771 };
1772
1773 // A pcf that is "compressed" has smaller metrics info
1774 // but the bitmap data is the same.
1775
1776
1777 static unsigned char *read_buffer = NULL;
1778
1779 char
1780 pcf_read_encodings (Font* pcf, unsigned char* orig)
1781 {
1782 unsigned char *ptr = orig;
1783 unsigned long format;
1784 char endian;
1785
1786 format = ULONG(0,ptr); ptr += 4;
1787 endian = (format & PCF_BIG_ENDIAN) ? true : false;
1788
1789 ptr += 2; // skip: first column
1790 ptr += 2; // skip: last column
1791
1792 ptr += 2; // skip: first row
1793 ptr += 2; // skip: last row
1794
1795 // read default char
1796
1797 unsigned short defaultChar = USHORT(endian,ptr); ptr += 2;
1798 unsigned short numChars = USHORT(endian,ptr); ptr += 2;
1799
1800 #if 0
1801 printf ("pcf_read_encodings(): default char = %d, num chars = %d\n",
1802 pcf->first_char, numChars);
1803 #endif
1804
1805 /* kludge */
1806 pcf->first_char = 31;
1807 pcf->last_char = 255;
1808
1809 return true;
1810 }
1811
1812
1813 char
1814 pcf_read_bitmaps (Font* pcf, unsigned char* orig)
1815 {
1816 unsigned char *ptr = orig;
1817 unsigned long format;
1818 char endian;
1819 char compressed;
1820 unsigned long nChars;
1821 int i, j;
1822 unsigned char *offsets;
1823
1824 format = ULONG(0,ptr); ptr += 4;
1825 endian = (format & PCF_BIG_ENDIAN) ? true : false;
1826 compressed = (format & PCF_COMPRESSED) ? true : false;
1827
1828 int storage_unit = (format >> 4) & 3;
1829 int row_unit = format & 3;
1830 int bit_order = format & 8;
1831
1832 nChars = ULONG(endian,ptr); ptr += 4;
1833 if (pcf->nchars)
1834 {
1835 if (pcf->nchars != nChars)
1836 FATAL ("#metrics != #chars");
1837 }
1838 else
1839 {
1840 pcf->nchars = nChars;
1841 }
1842
1843 offsets = ptr;
1844 ptr += 4 * nChars;
1845
1846 unsigned char *ptr2 = ptr + 4 * (3 & format);
1847 unsigned long data_size = ULONG(endian,ptr2);
1848
1849 ptr += 16;
1850
1851 pcf->bitmap_buffer = malloc (data_size);
1852 if (!pcf->widths)
1853 {
1854 pcf->lefts = malloc (nChars);
1855 pcf->widths = malloc (nChars);
1856 pcf->bitwidths = malloc (nChars);
1857 pcf->descents = malloc (nChars);
1858 pcf->heights = malloc (nChars);
1859
1860 if (!pcf->lefts || !pcf->heights)
1861 FATAL ("out of memory");
1862 }
1863
1864 pcf->bitmaps = malloc (nChars * sizeof(char*));
1865
1866 if (!pcf->bitmap_buffer || !pcf->lefts || !pcf->widths || !pcf->heights
1867 || !pcf->bitmaps)
1868 FATAL ("unable to allocate font data");
1869
1870 // Copy over bitmap data.
1871 for (i=0; i < data_size; i++)
1872 {
1873 pcf->bitmap_buffer[i] = ptr[i];
1874 }
1875
1876 // Need to ensure that the leftmost font bit is bit 7.
1877 //
1878 if (!bit_order)
1879 {
1880 unsigned char *p = pcf->bitmap_buffer;
1881 i = data_size;
1882 while (i--) {
1883 *p++ = bit_reversal_array[*p];
1884 }
1885 }
1886
1887 // Need to re-order the bytes to make them
1888 // little-endian, if they were written in big-endian format.
1889 //
1890 unsigned char *p;
1891 switch (row_unit) {
1892 default:
1893 case 0: // row = 1 byte
1894 break;
1895
1896 case 1: // row = 1 short
1897 if (storage_unit == 0 && endian) {
1898 unsigned char *p = pcf->bitmap_buffer;
1899 i = nChars / 2;
1900 while (i)
1901 {
1902 int tmp = *p;
1903 *p = *(p+1);
1904 *++p = tmp;
1905 i--;
1906 }
1907 }
1908 break;
1909
1910 case 2: // row = 1 long
1911 if (endian) {
1912 switch (storage_unit) {
1913 case 0:
1914 p = pcf->bitmap_buffer;
1915 i = nChars / 4;
1916 while (i)
1917 {
1918 int tmp = *p;
1919 *p = *(p+3);
1920 *(p+3) = tmp;
1921
1922 p++;
1923 tmp = *p;
1924 *p = *(p+1);
1925 *(p+1) = tmp;
1926
1927 p += 3;
1928
1929 i--;
1930 }
1931 break;
1932 case 1:
1933 p = pcf->bitmap_buffer;
1934 i = nChars / 4;
1935 while (i)
1936 {
1937 int tmp = *p;
1938 int tmp2 = *(p+1);
1939 *p = *(p+2);
1940 *(p+1) = *(p+3);
1941 *(p+2) = tmp;
1942 *(p+3) = tmp2;
1943
1944 p += 4;
1945
1946 i--;
1947 }
1948 break;
1949 default:
1950 break;
1951 }
1952 }
1953 break;
1954 }
1955
1956 // Now generate pointers for character data.
1957 //
1958 j = 8 << row_unit;
1959
1960 for (i=0; i < nChars; i++)
1961 {
1962 unsigned long offset = ULONG(endian,offsets); offsets += 4;
1963 pcf->bitmaps [i] = pcf->bitmap_buffer + offset;
1964 pcf->bitwidths [i] = j;
1965 }
1966
1967 return true;
1968 }
1969
1970
1971 char
1972 pcf_read_metrics (Font* pcf, unsigned char* orig)
1973 {
1974 unsigned char *ptr = orig;
1975 unsigned long format;
1976 char endian;
1977 char compressed;
1978 unsigned long nMetrics;
1979 int i;
1980
1981 format = ULONG(0,ptr); ptr += 4;
1982 endian = (format & PCF_BIG_ENDIAN) ? true : false;
1983 compressed = (format & PCF_COMPRESSED) ? true : false;
1984
1985 if (compressed)
1986 {
1987 nMetrics = USHORT(endian,ptr);
1988 ptr += 2;
1989 }
1990 else
1991 {
1992 nMetrics = ULONG(endian,ptr);
1993 ptr += 4;
1994 }
1995
1996 if (!pcf->nchars && !pcf->widths)
1997 {
1998 pcf->lefts = malloc (nMetrics);
1999 pcf->widths = malloc (nMetrics);
2000 pcf->bitwidths = malloc (nMetrics);
2001 pcf->descents = malloc (nMetrics);
2002 pcf->heights = malloc (nMetrics);
2003
2004 if (!pcf->lefts || !pcf->heights)
2005 FATAL ("out of memory");
2006 }
2007
2008 if (compressed)
2009 {
2010 for (i=0; i < nMetrics; i++)
2011 {
2012 pcf->lefts[i] = ((short)*ptr++) - 0x80;
2013 ptr++; // skip right-bearing
2014 pcf->widths[i] = ((short)*ptr++) - 0x80;
2015 pcf->heights [i] = ((short)*ptr++) - 0x80; // get ascent
2016 pcf->descents[i] = ((short)*ptr++) - 0x80;
2017 pcf->heights [i] += pcf->descents[i]; // height=ascent+descent
2018 // There is no attr byte in compressed version.
2019
2020 pcf->bitwidths[i] = pcf->widths[i];
2021
2022 #if 0
2023 printf ("char %c(%d): w=%d ht=%d desc=%d\n", i+32,i+32, pcf->widths[i], pcf->heights[i], pcf->descents[i]);
2024 #endif
2025 }
2026 }
2027 else
2028 {
2029 for (i=0; i < nMetrics; i++)
2030 {
2031 pcf->lefts [i] = USHORT (endian,ptr); ptr += 2;
2032 ptr += 2;
2033 pcf->widths[i] = USHORT (endian,ptr); ptr += 2;
2034 pcf->heights [i] = USHORT (endian,ptr); ptr += 2;
2035 pcf->descents[i] = USHORT (endian,ptr); ptr += 2;
2036 ptr += 2; // skip attr word
2037
2038 pcf->bitwidths[i] = pcf->widths[i];
2039 }
2040 }
2041
2042 return true;
2043 }
2044
2045 char
2046 pcf_read_accelerator (Font* pcf, unsigned char* orig)
2047 {
2048 unsigned char *ptr = orig;
2049 unsigned long format;
2050 char endian;
2051 int i;
2052
2053 format = ULONG(0,ptr); ptr += 4;
2054 endian= (format & PCF_BIG_ENDIAN) ? 1 : 0;
2055
2056 ptr += 8;
2057
2058 pcf->ascent = ULONG(endian,ptr); ptr += 4;
2059 pcf->descent = ULONG(endian,ptr); ptr += 4;
2060
2061 // printf ("ascent = %u , descent = %d\n", ascent, descent);
2062
2063 return true;
2064 }
2065
2066
2067
2068 char
2069 pcf_read_properties (Font* pcf, unsigned char* orig)
2070 {
2071 unsigned char *ptr = orig;
2072 unsigned long format, nprops;
2073 char endian;
2074 int i;
2075
2076 format = ULONG(0,ptr); ptr += 4;
2077 endian = (format & PCF_BIG_ENDIAN) ? 1 : 0;
2078 nprops = ULONG(endian,ptr); ptr += 4;
2079
2080 unsigned char* str_buffer = ptr + nprops*9 + 4;
2081
2082 // printf ("format=%08lx\n", format);
2083 // printf ("nprops=%08lx\n", nprops);
2084
2085 i = ((unsigned long)str_buffer) & 3;
2086 if (i) str_buffer += (4-i);
2087
2088 for (i = 0; i < nprops; i++)
2089 {
2090 unsigned long name = ULONG(endian,ptr); ptr += 4;
2091 unsigned char is_string = *ptr++;
2092 unsigned long value = ULONG(endian,ptr); ptr += 4;
2093
2094 char *str = ((char*)str_buffer) + name;
2095 if (is_string)
2096 {
2097 char *str2 = ((char*)str_buffer) + value;
2098
2099 switch (*str) {
2100
2101 case 'F':
2102
2103 if (!strcmp ("FAMILY_NAME", str))
2104 {
2105 //printf ("family-name=%s\n", str2);
2106 #if 0
2107 if (strlen (str2) < 63)
2108 strcpy (pcf->family, str2);
2109 else
2110 strncpy (pcf->family, str2, 63);
2111 #endif
2112 }
2113 else
2114 if (!strcmp ("FULL_NAME", str))
2115 {
2116 //printf ("full-name=%s\n", str2);
2117 #if 0
2118 if (strlen (str2) < 63)
2119 strcpy (pcf->fullname, str2);
2120 else
2121 strncpy (pcf->fullname, str2, 63);
2122 #endif
2123 }
2124 break;
2125
2126 case 'C':
2127
2128 if (!strcmp ("CHARSET_REGISTRY", str))
2129 {
2130 // printf ("charset registry=%s\n", str2);
2131 #if 0
2132 if (strcmp ("ISO8859", str2))
2133 return false;
2134 #endif
2135 }
2136 break;
2137
2138 case 'S':
2139
2140 if (!strcmp ("SLANT", str))
2141 {
2142 //printf ("slant=%s\n", str2);
2143 #if 0
2144 char angle=*str2;
2145 if (angle=='R')
2146 pcf->italic=0;
2147 else
2148 pcf->italic=1;
2149 #endif
2150 }
2151 break;
2152
2153 case 'W':
2154
2155 if (!strcmp ("WEIGHT_NAME", str))
2156 {
2157 //prf ("weight-name=%s\n", str2);
2158 #if 0
2159 if (!strcmp(str2, "Bold")) {
2160 pcf->weight = FONT_WEIGHT_BOLD;
2161 }
2162 else
2163 if (!strcmp(str2, "Medium")) {
2164 pcf->weight = FONT_WEIGHT_MEDIUM;
2165 }
2166 else
2167 pcf->weight = FONT_WEIGHT_MEDIUM;
2168 #endif
2169 }
2170 break;
2171
2172 default:
2173 break;
2174
2175 //printf ("\tunused property name(%ld) %s value(%ld) %s\n",
2176 // name, str, value, str2);
2177 }
2178 }
2179 else
2180 {
2181 switch (*str) {
2182
2183 case 'P':
2184
2185 if (!strcmp ("POINT_SIZE", str))
2186 {
2187 //printf ("point size=%lu\n", value);
2188 #if 0
2189 double sz = value;
2190 pcf->size = sz / 10.0;
2191 #endif
2192 }
2193 break;
2194
2195 case 'R':
2196
2197 if (!strcmp ("RESOLUTION_X", str))
2198 {
2199 //printf ("resolution x=%lu\n", value);
2200 #if 0
2201 pcf->dpi = value;
2202 #endif
2203 }
2204 break;
2205
2206 case 'C':
2207
2208 // We're using only iso8859-1 fonts.
2209 //
2210 if (!strcmp ("CHARSET_ENCODING", str))
2211 {
2212 // printf ("encoding=%d\n", value);
2213 if (value != 1)
2214 return false;
2215 }
2216 default:
2217 break;
2218
2219 // printf ("\tunused property name %s value %lu\n", str, value);
2220 }
2221 }
2222 }
2223 return true;
2224 }
2225
2226
2227 char
2228 pcf_read (Font* pcf, char *path)
2229 {
2230 int i;
2231 FILE *f;
2232 static char *line;
2233 char *param;
2234 char *param_end;
2235 short param_length;
2236 unsigned char *us;
2237 char *s;
2238 char *s2;
2239 char *s3;
2240 int char_num = 0;
2241 static char got_start = false;
2242 static char got_encoding = false;
2243 static char got_end = false;
2244 static char got_bitmap = false;
2245 struct stat statbuf;
2246 char path2[PATH_MAX];
2247
2248 if (*path != '/') {
2249 char *dir = getenv("PCFFONTDIR");
2250 if (dir) {
2251 strcpy (path2, dir);
2252 if ('/' != dir[strlen(dir)-1])
2253 strcat (path2, "/");
2254 } else
2255 sprintf (path2, "/usr/X11R6/lib/fonts/%d%s", dpi, "dpi/");
2256
2257 strcat (path2, path);
2258 }
2259 else
2260 strcpy (path2, path);
2261
2262 // printf ("path='%s'\n", path2);
2263 if (stat (path2, &statbuf))
2264 return false;
2265
2266 unsigned long size = statbuf.st_size;
2267
2268 #if 0
2269 pcf->fullname[0]=0;
2270 pcf->family[0]=0;
2271 #endif
2272
2273 f = fopen (path2, "rb");
2274 if (!f)
2275 return false;
2276
2277 read_buffer = malloc (size);
2278 if (!read_buffer)
2279 FATAL ("unable to allocate font read buffer!");
2280 i = fread (read_buffer,1,size,f);
2281 if (i != size)
2282 FATAL ("cannot read entire font file");
2283 fclose (f);
2284 f = NULL;
2285 uchar *ptr = read_buffer;
2286
2287 // Read the TOC
2288 unsigned long toc_type;
2289 unsigned long toc_total;
2290
2291 toc_type = ULONG(0,ptr); ptr += 4;
2292 toc_total = ULONG(0,ptr); ptr += 4;
2293 if (toc_type != ZZ(1, 'f','c','p'))
2294 FATAL ("pcf file has bad header");
2295
2296 for (i=0; i < toc_total; i++)
2297 {
2298 unsigned long j;
2299 unsigned short type;
2300 unsigned char *table;
2301
2302 // printf ("toc entry %d:\n", i);
2303
2304 type = ULONG(0,ptr); ptr += 4;
2305 // printf (" type=%u, ", type);
2306
2307 j = ULONG(0,ptr); ptr += 4;
2308 // printf (" format=%lu, ", j);
2309
2310 j = ULONG(0,ptr); ptr += 4;
2311 // printf (" size=%lu, ", j);
2312
2313 j = ULONG(0,ptr); ptr += 4;
2314 // printf (" offset=%lu\n", j);
2315
2316 table = read_buffer + j;
2317
2318 switch (type)
2319 {
2320 case PCF_PROPS:
2321 if (!pcf_read_properties (pcf, table))
2322 return false;
2323 break;
2324
2325 case PCF_BDF_ENCODINGS :
2326 if (!pcf_read_encodings (pcf, table))
2327 return false;
2328 break;
2329
2330 case PCF_ACCEL:
2331 if (!pcf_read_accelerator (pcf, table))
2332 return false;
2333 break;
2334
2335 case PCF_METRICS:
2336 if (!pcf_read_metrics (pcf, table))
2337 return false;
2338 break;
2339
2340 case PCF_BITMAPS:
2341 if (!pcf_read_bitmaps (pcf, table))
2342 return false;
2343 break;
2344
2345 default:
2346 ;
2347 }
2348 }
2349
2350 if (read_buffer)
2351 {
2352 free (read_buffer);
2353 read_buffer = NULL;
2354 }
2355
2356 return true;
2357 }
2358
2359
2360 char *fbui_get_event_name (int type)
2361 {
2362 char *s="(unknown)";
2363 switch (type) {
2364 case FBUI_EVENT_NONE: s="(none)"; break;
2365 case FBUI_EVENT_EXPOSE: s="Expose"; break;
2366 case FBUI_EVENT_HIDE: s="Hide"; break;
2367 case FBUI_EVENT_UNHIDE: s="Unhide"; break;
2368 case FBUI_EVENT_ENTER: s="Enter"; break;
2369 case FBUI_EVENT_LEAVE: s="Leave"; break;
2370 case FBUI_EVENT_KEY: s="Key"; break;
2371 case FBUI_EVENT_MOVE_RESIZE: s="MoveResize"; break;
2372 case FBUI_EVENT_ACCEL: s="Accel"; break;
2373 case FBUI_EVENT_WINCHANGE: s="WinChange"; break;
2374 case FBUI_EVENT_MOTION: s="Motion"; break;
2375 case FBUI_EVENT_BUTTON: s="Button"; break;
2376 }
2377 return s;
2378 }
2379
2380
2381 void fbui_print_error (int value)
2382 {
2383 printf ("FBUI error: %s\n", fbui_error_name(value));
2384 }
2385
2386 char *fbui_error_name (int value)
2387 {
2388 char *s = "(none)";
2389
2390 if (value >= 0)
2391 value = -value;
2392
2393 switch (value) {
2394 case FBUI_ERR_BADADDR: s = "bad address"; break;
2395 case FBUI_ERR_NULLPTR: s = "null pointer"; break;
2396 case FBUI_ERR_OFFSCREEN: s = "offscreen"; break;
2397 case FBUI_ERR_NOTRUNNING: s = "not running"; break;
2398 case FBUI_ERR_WRONGVISUAL: s = "wrong visual"; break;
2399 case FBUI_ERR_NOTPLACED: s = "not placed"; break;
2400 case FBUI_ERR_BIGENDIAN: s = "big endian"; break;
2401 case FBUI_ERR_INVALIDCMD: s = "invalid command"; break;
2402 case FBUI_ERR_BADPID: s = "bad process id"; break;
2403 case FBUI_ERR_ACCELBUSY: s = "accelerator key in use"; break;
2404 case FBUI_ERR_NOFONT: s = "no font"; break;
2405 case FBUI_ERR_NOMEM: s = "out of memory"; break;
2406 case FBUI_ERR_NOTOPEN: s = "not open"; break;
2407 case FBUI_ERR_OVERLAP: s = "window overlap"; break;
2408 case FBUI_ERR_ALREADYOPEN: s = "already open"; break;
2409 case FBUI_ERR_MISSINGWIN: s = "missing window"; break;
2410 case FBUI_ERR_NOTWM: s = "not a window manager"; break;
2411 case FBUI_ERR_WRONGWM: s = "wrong window manager"; break;
2412 case FBUI_ERR_HAVEWM: s = "already have window manager"; break;
2413 case FBUI_ERR_KEYFOCUSDENIED: s = "key focus request denied"; break;
2414 case FBUI_ERR_KEYFOCUSERR: s = "key focus error"; break;
2415 case FBUI_ERR_BADPARAM: s = "bad parameter"; break;
2416 case FBUI_ERR_NOMOUSE: s = "no mouse"; break;
2417 case FBUI_ERR_MOUSEREAD: s = "mouse read error"; break;
2418 case FBUI_ERR_OVERLARGECUT: s = "overlarge cut"; break;
2419 case FBUI_ERR_BADWIN: s = "bad window"; break;
2420 case FBUI_ERR_PASTEFAIL: s = "paste failed"; break;
2421 case FBUI_ERR_CUTFAIL: s = "cut failed"; break;
2422 case FBUI_ERR_NOEVENT: s = "no events"; break;
2423 case FBUI_ERR_DRAWING: s = "busy drawing"; break;
2424 case FBUI_ERR_MISSINGPROCENT: s = "missing process entry"; break;
2425 case FBUI_ERR_BADVC: s = "bad virtual console number"; break;
2426 }
2427 return s;
2428 }
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.