fbui | Framebuffer-based graphical environment |
| download: https://git.y1.nz/archives/fbui.tar.gz | |
| README | Files | Log | Refs |
libfbui/PanelManager/rect.c
1
2 /*=========================================================================
3 *
4 * fbpm, a panel-based 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 #include <stdio.h>
27 #include <linux/fb.h>
28 #include <libfbui.h>
29 #include <jpeglib.h>
30
31 extern int window_count;
32 extern struct fbui_wininfo info[];
33
34 JSAMPLE * image_buffer;
35 int image_height;
36 int image_width;
37 int image_ncomponents;
38
39 extern short win_w, win_h;
40
41 char grayscale=0; /* 1 forces bg image to grayscale */
42
43
44
45
46 /* -----------------Rectangle subtraction code----------------- */
47
48 typedef struct rect {
49 short x0,y0,x1,y1;
50 struct rect *next;
51 } Rect;
52
53 static Rect* Rect_new(short x0, short y0, short x1, short y1)
54 {
55 Rect *nu = (Rect*) malloc (sizeof(Rect));
56 if (!nu) return NULL;
57
58 nu->x0 = x0;
59 nu->y0 = y0;
60 nu->x1 = x1;
61 nu->y1 = y1;
62 nu->next = NULL;
63
64 return nu;
65 }
66
67 static void Rect_sort (Rect *r)
68 {
69 if (!r) return;
70 if (r->x0 > r->x1) {
71 short tmp = r->x0;
72 r->x0 = r->x1;
73 r->x1 = tmp;
74 }
75 if (r->y0 > r->y1) {
76 short tmp = r->y0;
77 r->y0 = r->y1;
78 r->y1 = tmp;
79 }
80 }
81
82 static Rect* Rect_dup (Rect *r)
83 {
84 if (!r) return NULL;
85 return Rect_new (r->x0,r->y0,r->x1,r->y1);
86 }
87
88 static int Rect_subtract (Rect *a, Rect *b, Rect *rects[])
89 {
90 int count=0;
91 if (!a || !b || !rects) return;
92
93 if (a->x0==b->x0 && a->x1==b->x1 && a->y0==b->y0 && a->y1==b->y1)
94 return 0;
95
96 Rect_sort(a);
97 Rect_sort(b);
98
99 #define between(N,M,O) (N>=M && N<=O)
100
101 int i=-1, j=-1;
102 if (b->x1 < a->x0)
103 i=0;
104 else if (b->x0 <= a->x0 && between(b->x1,a->x0,a->x1))
105 i=1;
106 else if (between(b->x0,a->x0,a->x1) && b->x1 >= a->x1)
107 i=3;
108 else if (between(b->x0,a->x0,a->x1) && between(b->x1,a->x0,a->x1))
109 i=2;
110 else
111 i=4;
112
113 if (b->y1 < a->y0)
114 j=0;
115 else if (b->y0 <= a->y0 && between(b->y1,a->y0,a->y1))
116 j=1;
117 else if (between(b->y0,a->y0,a->y1) && b->y1 >= a->y1)
118 j=3;
119 else if (between(b->y0,a->y0,a->y1) && between(b->y1,a->y0,a->y1))
120 j=2;
121 else
122 j=4;
123
124 /*
125 j values
126 +-------+
127 | 0 |
128 +-------+
129 +-------+
130 +--------------+ | |
131 | | | 1 | +-------+
132 | | | | | |
133 | a | +-------+ | 2 |
134 | | | |
135 | | +-------+
136 | | +-------+
137 +--------------+ | 3 |
138 +-------+ +-------+
139 i values: | 4 |
140 +-------+ +--------+ +-------+ +-------+
141 | 0 | | 2 | | 4 |
142 +-------+ +--------+ +-------+
143 +---------+ +--------+
144 | 1 | | 3 |
145 +---------+ +--------+
146 */
147 // totally outside
148 if (i==0 || i==4 || j==0 || j==4) {
149 rects[count++] = Rect_dup(a);
150 return count;
151 }
152 else
153 // totally inside
154 if (i==2 && j==2) {
155 if (a->x0 != b->x0)
156 rects[count++] = Rect_new (a->x0,a->y0,b->x0-1,a->y1); //left
157 if (a->y0 != b->y0)
158 rects[count++] = Rect_new (b->x0,a->y0,b->x1,b->y0-1); //top
159 if (a->y1 != b->y1)
160 rects[count++] = Rect_new (b->x0,b->y1+1,b->x1,a->y1); //bottom
161 if (a->x1 != b->x1)
162 rects[count++] = Rect_new (b->x0+1,a->y0,a->x1,a->y1); //right
163 return count;
164 }
165 else
166 if (i==1 && j==2) {
167 if (a->y0 != b->y0)
168 rects[count++] = Rect_new (a->x0,a->y0,b->x1,b->y0-1); // topleft
169 if (a->y1 != b->y1)
170 rects[count++] = Rect_new (a->x0,b->y1+1,b->x1,a->y1); // bottomleft
171 if (a->x1 != b->x1)
172 rects[count++] = Rect_new (b->x1+1,a->y0,a->x1,a->y1); // right
173 return count;
174 }
175 else
176 if (i==3 && j==2) {
177 if (a->y0 != b->y0)
178 rects[count++] = Rect_new (a->x0,a->y0,a->x1,b->y0-1); // top
179 if (a->x0 != b->x0)
180 rects[count++] = Rect_new (a->x0,b->y0,b->x0-1,b->y1); // middle
181 if (a->y1 != b->y1)
182 rects[count++] = Rect_new (a->x0,b->y1+1,a->x1,a->y1); // bottom
183 return count;
184 }
185 else
186 if (i==2 && j==1) {
187 if (a->x0 != b->x0)
188 rects[count++] = Rect_new (a->x0,a->y0,b->x0-1,b->y1); // topleft
189 if (a->x1 != b->x1)
190 rects[count++] = Rect_new (b->x1+1,a->y0,a->x1,b->y1); // topright
191 if (a->y1 != b->y1)
192 rects[count++] = Rect_new (a->x0,b->y1+1,a->x1,a->y1); //bottom
193 return count;
194 }
195 else
196 if (i==2 && j==3) {
197 if (a->y0 != b->y0)
198 rects[count++] = Rect_new (a->x0,a->y0,a->x1,b->y0-1); // top
199 if (a->x0 != b->x0)
200 rects[count++] = Rect_new (a->x0,b->y0,b->x0-1,a->y1); // bottomleft
201 if (a->x1 != b->x1)
202 rects[count++] = Rect_new (b->x1+1,b->y0,a->x1,a->y1); // bottomright
203 return count;
204 }
205 else
206 if (i==3 && j==1) {
207 if (a->x0 != b->x0)
208 rects[count++] = Rect_new (a->x0,a->y0,b->x0-1,a->y1); // left
209 if (a->y1 > b->y1)
210 rects[count++] = Rect_new (b->x0,b->y1+1,a->x1,a->y1); // bottomright
211 return count;
212 }
213 else
214 if (i==3 && j==3) {
215 if (a->x0 != b->x0)
216 rects[count++] = Rect_new (a->x0,a->y0,b->x0-1,a->y1); // left
217 if (a->y0 < b->y0)
218 rects[count++] = Rect_new (b->x0,a->y0,a->x1,b->y0-1); //topright
219 return count;
220 }
221 else
222 if (i==1 && j==1) {
223 if (a->x1 != b->x1)
224 rects[count++] = Rect_new (b->x1+1,a->y0,a->x1,a->y1); // right
225 if (a->y1 != b->y1)
226 rects[count++] = Rect_new (a->x0,b->y1+1,b->x1,a->y1); // bottomleft
227 return count;
228 }
229 else
230 if (i==1 && j==3) {
231 if (a->x1 != b->x1)
232 rects[count++] = Rect_new (b->x1+1,a->y0,a->x1,a->y1); // right
233 if (a->y0 < b->y0)
234 rects[count++] = Rect_new (a->x0,a->y0,b->x1,b->y0-1); // topleft
235 return count;
236 }
237 else
238 printf ("combo %d %d\n",i,j);
239 }
240
241 static void Rect_delete(Rect *r)
242 {
243 if (r)
244 free((void*)r);
245 }
246
247
248 /* Draws a portion of the background
249 * If an image has been loaded, it draws that.
250 * Otherwise, a green gradient.
251 */
252 void
253 draw_image (Display *dpy, Window *win, short x0, short y0, short x1, short y1)
254 {
255 int i,j;
256 if (x0 > x1) {
257 short tmp=x0;x0=x1;x1=tmp;
258 }
259 if (y0 > y1) {
260 short tmp=y0;y0=y1;y1=tmp;
261 }
262 if (x1<0) return;
263 if (y1<0) return;
264 if (x0<0) x0=0;
265 if (y0<0) y0=0;
266
267 /* If we have no background image, don't sweat it, just draw
268 * a gradient
269 */
270 if (!image_buffer) {
271 for (i=x0; i<=x1; i++) {
272 unsigned long k = (191 * i) / win_w;
273 unsigned long color = (35 + k) + (90 << 8);
274 fbui_draw_vline (dpy, win, i,y0,y1, color);
275 }
276 fbui_flush (dpy, win);
277 return;
278 }
279
280 if (x0>=image_width) return;
281 if (y0>=image_height) return;
282 if (x1>=image_width) x1=image_width-1;
283 if (y1>=image_height) y1=image_height-1;
284
285 for (j=y0; j<=y1; j++) {
286 if (image_ncomponents == 1 || grayscale) {
287 for(i=x0; i<x1; i++) {
288 unsigned long pix=0;
289 unsigned char *p = image_buffer +
290 image_ncomponents*(i + j*image_width);
291
292 /* pixels are grayscale */
293 if (image_ncomponents == 1) {
294 pix = *p;
295 pix <<= 8;
296 pix |= *p;
297 pix <<= 8;
298 pix |= *p;
299 } else {
300 pix = *p++;
301 pix += *p++;
302 pix += *p;
303 pix /= 3;
304 pix |= (pix<<8) | (pix<<16);
305 }
306
307 fbui_draw_point (dpy, win, i, j, pix);
308 }
309 }
310 else
311 {
312 fbui_put_rgb3 (dpy, win, x0, j, x1-x0+1,
313 image_buffer + 3*(j*image_width+x0));
314 }
315 }
316
317 fbui_flush(dpy,win);
318 }
319
320
321 void
322 draw_background (Display *dpy, Window *win)
323 {
324 Rect *list1 = Rect_new (0,0,win_w-1,win_h-1);
325 Rect *list2 = NULL;
326 Rect *ptr;
327 int mypid = getpid();
328 int i;
329
330 for (i=0; i<window_count; i++) {
331 Rect *r0,*r1,*r2,*r3;
332 struct fbui_wininfo *wi = &info[i];
333 Rect *windowrect = Rect_new(wi->x,wi->y,
334 wi->x+wi->width-1,wi->y+wi->height-1);
335 //printf ("subtracting %s\n", wi->name);
336 if (wi->pid != mypid) {
337 ptr = list1;
338 while(ptr) {
339 Rect *rects[4];
340 int count = Rect_subtract (ptr,windowrect,rects);
341 int j=0;
342 while (j < count) {
343 rects[j]->next = list2;
344 list2 = rects[j];
345 j++;
346 }
347 ptr = ptr->next;
348 }
349 ptr = list1;
350 Rect *next;
351 while (ptr) {
352 next = ptr->next;
353 Rect_delete(ptr);
354 ptr=next;
355 }
356 list1 = list2;
357 list2 = NULL;
358
359 #if 0
360 int k=0;
361 Rect *n = list1;
362 while(n) { k++;
363 printf (" rect: %d %d - %d %d\n", n->x0,n->y0,n->x1,n->y1);
364 n=n->next;
365 }
366 printf ("result list now has %d rectangles\n", k);
367 #endif
368 }
369
370 Rect_delete (windowrect);
371 }
372
373 /* draw the background */
374 ptr=list1;
375 while(ptr) {
376 draw_image (dpy,win, ptr->x0,ptr->y0,ptr->x1,ptr->y1);
377 ptr=ptr->next;
378 }
379 fbui_flush (dpy, win);
380
381 /* remove the rectangle list */
382 ptr = list1;
383 while (ptr) {
384 Rect *next = ptr->next;
385 Rect_delete(ptr);
386 ptr=next;
387 }
388 }
389
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.