git.y1.nz

fbui

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

libfbui/Scribble/main.c

      1 
      2 /*=========================================================================
      3  *
      4  * fbscribble, a simple drawing program
      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 typedef unsigned long u32;
     28 
     29 
     30 #include <stdio.h>
     31 #include <sys/types.h>
     32 #include <sys/stat.h>
     33 #include <sys/ioctl.h>
     34 #include <linux/fb.h>
     35 #include <linux/input.h>
     36 #include <string.h>
     37 
     38 #include <linux/vt.h>
     39 #include <linux/input.h>
     40 
     41 #include "libfbui.h"
     42 
     43 
     44 typedef struct {
     45 	short width, height;
     46 	short depth; // allowed: 24 or 48
     47 	char *path;
     48 	char *title;
     49 	char *creator;
     50 	char *comment;
     51 
     52 	unsigned char *pixels;
     53 } Canvas;
     54 
     55 
     56 Canvas *Canvas_create (short w, short h, short d)
     57 {
     58 	Canvas *nu;
     59 	unsigned char *pixels;
     60 
     61 	if (w<0 || h<0)
     62 		return NULL;
     63 	if (d!=24 && d!=48)
     64 		return NULL;
     65 
     66 	int size = w * h * (d==24 ? 3 : 6);
     67 	pixels = (unsigned char*) malloc(size);
     68 	if (!pixels)
     69 		FATAL ("out of memory");
     70 	memset ((void*)pixels, 0xffffff, size);
     71 
     72 	nu = (Canvas*) malloc(sizeof(Canvas));
     73 	if (!nu)
     74 		FATAL ("out of memory");
     75 
     76 	memset ((void*)nu, 0, sizeof(Canvas));
     77 	nu->width = w;
     78 	nu->height = w;
     79 	nu->depth = d;
     80 	nu->pixels = pixels;
     81 	return nu;
     82 }
     83 
     84 void Canvas_put_pixel (Canvas *canvas, short x, short y, unsigned long pixel)
     85 {
     86 	if (!canvas)
     87 		return;
     88 	if (canvas->depth != 24)
     89 		return;
     90 	if (x < 0 || y < 0 || x>=canvas->width || y>=canvas->height)
     91 		return;
     92 	if (!canvas->pixels)
     93 		FATAL ("Canvas lacks pixmap");
     94 	/*----------------*/
     95 
     96 	unsigned long ix = (x + y*canvas->width) * (canvas->depth/8);
     97 	canvas->pixels [ix++] = pixel >> 16;
     98 	canvas->pixels [ix++] = pixel >> 8;
     99 	canvas->pixels [ix] = pixel;
    100 }
    101 
    102 void Canvas_clear (Canvas *canvas)
    103 {
    104 	if (!canvas)
    105 		return;
    106 	if (!canvas->pixels)
    107 		return;
    108 	/*----------------*/
    109 
    110 	int size = canvas->width * canvas->height * (canvas->depth==24 ? 3 : 6);
    111 	memset ((void*)canvas->pixels, 0xffffff, size);
    112 }
    113 
    114 void Canvas_draw (Canvas *canvas, Display* dpy, Window *win, int zoom)
    115 {
    116 	if (!canvas || !dpy || !win)
    117 		return;
    118 
    119 	if (zoom != 1)
    120 		return;
    121 
    122 	fbui_fill_area (dpy, win, 0,0, win->width-1, win->height-1, 0xB0B0B0);
    123 
    124 	int x,y;
    125 	int bytes_per_pixel = canvas->depth / 8;
    126 
    127 	int x0 = (win->width - canvas->width) >> 1;
    128 	int y0 = (win->height - canvas->height) >> 1;
    129 
    130 	for (y=0; y<canvas->height; y++) {
    131 		for (x=0; x<canvas->width; x++) {
    132 			unsigned long ix = (x + y*canvas->width) * bytes_per_pixel;
    133 			unsigned long pixel;
    134 			pixel = canvas->pixels [ix++];
    135 			pixel <<= 8;
    136 			pixel |= canvas->pixels [ix++];
    137 			pixel <<= 8;
    138 			pixel |= canvas->pixels [ix];
    139 
    140 			fbui_draw_point (dpy, win, x0 + x, y0 + y, pixel);
    141 		}
    142 	}
    143 }
    144 
    145 int Canvas_deserialize (Canvas *canvas, char *path)
    146 {
    147 	FILE *f;
    148 
    149 	if (!canvas || !path)
    150 		FATAL ("null ptr param");
    151 	/*----------------*/
    152 
    153 	f = fopen (path, "r");
    154 	if (!f)
    155 		return false;
    156 
    157 	int a,b,c;
    158 	if (3 != fscanf (f, "%d %d %d\n", &a,&b,&c)) {
    159 		fclose (f);
    160 		return false;
    161 	}
    162 
    163 	if (a < 0 || b < 0 || (c != 24 && c != 48))
    164 		return false;
    165 
    166 	if (canvas->pixels)
    167 		free (canvas->pixels);
    168 
    169 	int bytes_per_pixel = c/8;
    170 
    171 	int size = a * b * bytes_per_pixel;
    172 	unsigned char *pixels = (unsigned char*) malloc(size);
    173 	if (!pixels)
    174 		FATAL ("out of memory");
    175 	memset ((void*)pixels, 0xffffff, size);
    176 
    177 	canvas->pixels = pixels;
    178 	canvas->width = a;
    179 	canvas->height = b;
    180 	canvas->depth = c;
    181 
    182 	int x,y;
    183 	for (y=0; y<canvas->height; y++) {
    184 		for (x=0; x<canvas->width; x++) {
    185 			unsigned long value;
    186 
    187 			if (1 != fscanf (f, "%06lx", &value)) {
    188 				fclose(f);
    189 				return false;
    190 			}
    191 
    192 			unsigned long r,b,g;
    193 			r = 0xff & (value >> 16);
    194 			g = 0xff & (value >> 8);
    195 			b = 0xff & value;
    196 
    197 			unsigned long ix = (x + y*canvas->width) * bytes_per_pixel;
    198 			pixels [ix++] = r;
    199 			pixels [ix++] = g;
    200 			pixels [ix] = b;
    201 		}
    202 	}
    203 
    204 	fclose(f);
    205 	return true;
    206 }
    207 
    208 int Canvas_serialize (Canvas *canvas, char *path)
    209 {
    210 	FILE *f;
    211 
    212 	if (!canvas || !path)
    213 		FATAL ("null ptr param");
    214 	/*----------------*/
    215 
    216 	f = fopen (path, "w");
    217 	if (!f)
    218 		return false;
    219 
    220 	fprintf (f, "%d %d %d\n", canvas->width, canvas->height, canvas->depth);
    221 
    222 	int x,y;
    223 	int bytes_per_pixel = canvas->depth / 8;
    224 
    225 	for (y=0; y<canvas->height; y++) {
    226 		for (x=0; x<canvas->width; x++) {
    227 			unsigned long ix = (x + y*canvas->width) * bytes_per_pixel;
    228 			unsigned long pixel;
    229 			pixel = canvas->pixels [ix++];
    230 			pixel <<= 8;
    231 			pixel |= canvas->pixels [ix++];
    232 			pixel <<= 8;
    233 			pixel |= canvas->pixels [ix];
    234 
    235 			fprintf (f, "%06lx ", pixel);
    236 		}
    237 		fprintf (f,"\n");
    238 	}
    239 	fclose(f);
    240 }
    241 
    242 int
    243 main(int argc, char** argv)
    244 {
    245 	Display *dpy;
    246 	Window *win;
    247 	u32 fg,bg;
    248 	int i;
    249 	int vc=-1;
    250 	char button_down = 0;
    251 
    252 	short canvas_w, canvas_h;
    253 
    254 	Canvas *canvas = Canvas_create (240,240,24);
    255 
    256 	if (Canvas_deserialize (canvas, "image"))
    257 		printf ("fbscribble: successfully read image\n");
    258 	else {
    259 		printf ("fbscribble: failed to read image\n");
    260 		Canvas_clear (canvas);
    261 	}
    262 
    263 	fg = RGB_BLACK;
    264 	bg = RGB_WHITE;
    265 
    266 	short win_w, win_h;
    267 	dpy = fbui_display_open ();
    268 	if (!dpy) 
    269 		FATAL ("cannot open display");
    270 
    271 	win_w = 320;
    272 	win_h = 320;
    273 
    274 	canvas_w = win_w;
    275 	canvas_h = win_h;
    276 
    277 	win = fbui_window_open (dpy, win_w, win_h, 
    278 		&win_w, &win_h, 999,999,
    279 		0, 0,
    280 		&fg, &bg, 
    281 		"fbscribble", "", 
    282 		FBUI_PROGTYPE_APP, 
    283 		false,false, 
    284 		vc,
    285 		true,  // need keys
    286 		false, // all motion
    287 		false, // not hidden
    288 		argc, argv);
    289 
    290 	int x0 = (win->width - canvas->width) >> 1;
    291 	int y0 = (win->height - canvas->height) >> 1;
    292 
    293 	while (1) {
    294 		int total;
    295 		int need=0;
    296 		Event ev;
    297 		Window *win;
    298 		int x=0, y=0;
    299 		int type;
    300 		int err;
    301 
    302 		if (err = fbui_wait_event (dpy, &ev, FBUI_EVENTMASK_ALL)) {
    303 			fbui_print_error (err);
    304 			continue;
    305 		}
    306 
    307 printf ("%s got event %s\n", argv[0], fbui_get_event_name (ev.type));
    308 
    309 		win = ev.win;
    310 		if (!win)
    311 			FATAL("null window");
    312 
    313 		type = ev.type;
    314 
    315 		switch (type) {
    316 		case FBUI_EVENT_EXPOSE:
    317 			Canvas_draw (canvas, dpy, win, 1);
    318 			continue;
    319 
    320 		case FBUI_EVENT_KEY: {
    321 			short key = ev.key >> 2;
    322 			short state = ev.key & 3;
    323 printf ("key=%d\n", key);
    324 
    325 			if (state && key == KEY_Q)
    326 				goto finit;
    327 
    328 			if (state && key == KEY_S)
    329 				Canvas_serialize (canvas, "image");
    330 
    331 			if (state && key == KEY_L)
    332 				Canvas_deserialize (canvas, "image");
    333 			break;
    334 		 }
    335 
    336 		case FBUI_EVENT_BUTTON:
    337 printf ("got button event, value=%d\n", ev.key);
    338 			if (ev.key & FBUI_BUTTON_LEFT)
    339 				button_down = ev.key & 1;
    340 			break;
    341 		
    342 		case FBUI_EVENT_MOTION: {
    343 			short x= ev.x - x0;
    344 			short y= ev.y - y0;
    345 
    346 			if (button_down && x >= 0 && y >= 0 && 
    347 			    x < canvas->width && y < canvas->height) 
    348 			{
    349 				Canvas_put_pixel (canvas, x, y, RGB_RED);
    350 				fbui_draw_point (dpy, win, ev.x, ev.y, RGB_RED);
    351 				fbui_flush (dpy, win);
    352 			}
    353 			break;
    354 		 }
    355 		
    356 		case FBUI_MOVE_RESIZE:
    357 			x0 = (ev.width - canvas->width) >> 1;
    358 			y0 = (ev.height - canvas->height) >> 1;
    359 			break;
    360 		}
    361 	}
    362 finit:
    363 
    364 	fbui_display_close (dpy);
    365 }

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