aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/evas/src/modules/engines/fb/evas_fb_main.c
diff options
context:
space:
mode:
authorDavid Walter Seikel2012-01-04 18:41:13 +1000
committerDavid Walter Seikel2012-01-04 18:41:13 +1000
commitdd7595a3475407a7fa96a97393bae8c5220e8762 (patch)
treee341e911d7eb911a51684a7412ef7f7c7605d28e /libraries/evas/src/modules/engines/fb/evas_fb_main.c
parentAdd the skeleton. (diff)
downloadSledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.zip
SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.gz
SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.bz2
SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.xz
Add the base Enlightenment Foundation Libraries - eina, eet, evas, ecore, embryo, and edje.
Note that embryo wont be used, but I'm not sure yet if you can build edje without it.
Diffstat (limited to 'libraries/evas/src/modules/engines/fb/evas_fb_main.c')
-rw-r--r--libraries/evas/src/modules/engines/fb/evas_fb_main.c600
1 files changed, 600 insertions, 0 deletions
diff --git a/libraries/evas/src/modules/engines/fb/evas_fb_main.c b/libraries/evas/src/modules/engines/fb/evas_fb_main.c
new file mode 100644
index 0000000..1d61f1a
--- /dev/null
+++ b/libraries/evas/src/modules/engines/fb/evas_fb_main.c
@@ -0,0 +1,600 @@
1/* -------------------------------------------------------------------- */
2/* LINUX FBCON FRAMEBUFFER UTILITY CODE */
3/* makes setting up the framebuffer easy. Also makes it eays to port to */
4/* some other system if needed. */
5/* Copyright (c) 1999 - Carsten Haitzler (The Rasterman) */
6/* -------------------------------------------------------------------- */
7#include "evas_common.h"
8#include "evas_fb.h"
9
10#include <sys/ioctl.h>
11#include <sys/wait.h>
12#include <linux/kd.h>
13#include <linux/vt.h>
14#include <sys/user.h>
15
16#define FB_ACTIVE 0
17#define FB_REL_REQ 1
18#define FB_INACTIVE 2
19#define FB_ACQ_REQ 3
20
21/* -------------------------------------------------------------------- */
22/* internal variables */
23
24static struct fb_fix_screeninfo fb_fix;
25static int fb, tty;
26static int bpp, depth;
27//static int orig_vt_no = 0;
28static int kd_mode;
29static struct vt_mode vt_omode;
30static struct fb_var_screeninfo fb_ovar;
31static unsigned short ored[256], ogreen[256], oblue[256];
32static unsigned short red[256], green[256], blue[256];
33static struct fb_cmap ocmap = { 0, 256, ored, ogreen, oblue, NULL };
34static struct fb_cmap cmap = { 0, 256, red, green, blue, NULL };
35
36/* -------------------------------------------------------------------- */
37/* internal function prototypes */
38
39static void fb_cleanup(void);
40//static void fb_cleanup_fork(void);
41//static void fb_setvt(int vtno);
42static void fb_init_palette_332(FB_Mode *mode);
43static void fb_init_palette_linear(FB_Mode *mode);
44
45/* -------------------------------------------------------------------- */
46/* palette setting */
47
48static void
49fb_init_palette_332(FB_Mode *mode)
50{
51 int r, g, b, i;
52
53 if (mode->fb_var.bits_per_pixel != 8)
54 return;
55 i = 0;
56
57 if (ioctl(fb, FBIOGETCMAP, &cmap) == -1)
58 perror("ioctl FBIOGETCMAP");
59
60 /* generate the palette */
61 for (r = 0; r < 8; r++)
62 {
63 for (g = 0; g < 8; g++)
64 {
65 for (b = 0; b < 4; b++)
66 {
67 int val;
68
69 val = (r << 5) | (r << 2) | (r >> 1);
70 red[i] = (val << 8) | val;
71 val = (g << 5) | (g << 2) | (g >> 1);
72 green[i] = (val << 8) | val;
73 val = (b << 6) | (b << 4) | (b << 2) | (b);
74 blue[i] = (val << 8) | val;
75 i++;
76 }
77 }
78 }
79
80 /* set colormap */
81 if (ioctl(fb, FBIOPUTCMAP, &cmap) == -1)
82 perror("ioctl FBIOPUTCMAP");
83}
84
85static void
86fb_init_palette_linear(FB_Mode *mode)
87{
88 int i;
89
90 if (mode->fb_var.bits_per_pixel != 8)
91 return;
92
93 if (ioctl(fb, FBIOGETCMAP, &cmap) == -1)
94 perror("ioctl FBIOGETCMAP");
95
96 /* generate the palette */
97 for (i = 0; i < 256; i++)
98 red[i] = (i << 8) | i;
99 for (i = 0; i < 256; i++)
100 green[i] = (i << 8) | i;
101 for (i = 0; i < 256; i++)
102 blue[i] = (i << 8) | i;
103
104 /* set colormap */
105 if (ioctl(fb, FBIOPUTCMAP, &cmap) == -1)
106 perror("ioctl FBIOPUTCMAP");
107}
108
109/* -------------------------------------------------------------------- */
110/* initialisation & cleanup */
111
112FB_Mode *
113fb_list_modes(unsigned int *num_return)
114{
115 FILE *f;
116 char line[256], label[256], value[256];
117 FB_Mode *modes = NULL;
118 int num;
119
120 num = 0;
121 f = fopen("/etc/fb.modes","r");
122 if (!f)
123 {
124 *num_return = 0;
125 return NULL;
126 }
127 while (fgets(line, sizeof(line) - 1, f))
128 {
129 if (sscanf(line, "mode \"%250[^\"]\"", label) == 1)
130 {
131 char f1[32], f2[32], f3[32], f4[32];
132
133 f1[0] = 0; f2[0] = 0; f3[0] = 0; f4[0] = 0;
134 sscanf(label, "%30[^x]x%30[^-]-%30[^-]-%30s", f1, f2, f3, f4);
135 if ((f1[0]) && (f2[0]))
136 {
137 int geometry = 0;
138 int timings = 0;
139
140 num++;
141 modes = realloc(modes, num * sizeof(FB_Mode));
142 modes[num - 1].width = atoi(f1);
143 modes[num - 1].height = atoi(f2);
144 if (f3[0])
145 modes[num - 1].refresh = atoi(f3);
146 else
147 modes[num - 1].refresh = 0;
148 modes[num - 1].fb_var.sync = 0;
149 while ((fgets(line, sizeof(line) - 1, f)) &&
150 (!strstr(line, "endmode")))
151 {
152
153 if (sscanf(line," geometry %i %i %i %i %i",
154 &modes[num - 1].fb_var.xres,
155 &modes[num - 1].fb_var.yres,
156 &modes[num - 1].fb_var.xres_virtual,
157 &modes[num - 1].fb_var.yres_virtual,
158 &modes[num - 1].fb_var.bits_per_pixel) == 5)
159 geometry = 1;
160 if (sscanf(line," timings %i %i %i %i %i %i %i",
161 &modes[num - 1].fb_var.pixclock,
162 &modes[num - 1].fb_var.left_margin,
163 &modes[num - 1].fb_var.right_margin,
164 &modes[num - 1].fb_var.upper_margin,
165 &modes[num - 1].fb_var.lower_margin,
166 &modes[num - 1].fb_var.hsync_len,
167 &modes[num - 1].fb_var.vsync_len) == 7)
168 timings = 1;
169 if ((sscanf(line, " hsync %15s", value) == 1) &&
170 (!strcmp(value,"high")))
171 modes[num - 1].fb_var.sync |= FB_SYNC_HOR_HIGH_ACT;
172 if ((sscanf(line, " vsync %15s", value) == 1) &&
173 (!strcmp(value,"high")))
174 modes[num - 1].fb_var.sync |= FB_SYNC_VERT_HIGH_ACT;
175 if ((sscanf(line, " csync %15s", value) == 1) &&
176 (!strcmp(value,"high")))
177 modes[num - 1].fb_var.sync |= FB_SYNC_COMP_HIGH_ACT;
178 if ((sscanf(line, " extsync %15s", value) == 1) &&
179 (!strcmp(value,"true")))
180 modes[num - 1].fb_var.sync |= FB_SYNC_EXT;
181 if ((sscanf(line, " laced %15s", value) == 1) &&
182 (!strcmp(value,"true")))
183 modes[num - 1].fb_var.vmode |= FB_VMODE_INTERLACED;
184 if ((sscanf(line, " double %15s",value) == 1) &&
185 (!strcmp(value,"true")))
186 modes[num - 1].fb_var.vmode |= FB_VMODE_DOUBLE;
187 }
188 if ((!geometry) || (!timings))
189 {
190 num--;
191 if (num == 0)
192 {
193 free(modes);
194 modes = NULL;
195 }
196 }
197 else
198 {
199 modes[num - 1].fb_var.xoffset = 0;
200 modes[num - 1].fb_var.yoffset = 0;
201 }
202 }
203 }
204 }
205 fclose(f);
206 *num_return = num;
207 return modes;
208}
209
210FB_Mode *
211fb_setmode(unsigned int width, unsigned int height, unsigned int pdepth, unsigned int refresh)
212{
213 FB_Mode *modes, *mode = NULL;
214 unsigned int i, num_modes;
215
216 modes = fb_list_modes(&num_modes);
217 if (modes)
218 {
219 for (i = 0; i < num_modes; i++)
220 {
221 if ((modes[i].width == width) &&
222 (modes[i].height == height) &&
223 (!pdepth || modes[i].fb_var.bits_per_pixel == pdepth) &&
224 (modes[i].refresh == refresh))
225 {
226 if (pdepth) modes[i].fb_var.bits_per_pixel = pdepth;
227
228 if (ioctl(fb, FBIOPUT_VSCREENINFO, &modes[i].fb_var) == -1)
229 perror("ioctl FBIOPUT_VSCREENINFO");
230
231 free(modes);
232 return fb_getmode();
233 }
234 }
235 free(modes);
236 }
237 return mode;
238}
239
240FB_Mode *
241fb_changedepth(FB_Mode *cur_mode, unsigned int pdepth)
242{
243 cur_mode->fb_var.bits_per_pixel = pdepth;
244
245 if (ioctl(fb, FBIOPUT_VSCREENINFO, &cur_mode->fb_var) == -1)
246 perror("ioctl FBIOPUT_VSCREENINFO");
247
248 free(cur_mode);
249 return fb_getmode();
250}
251
252FB_Mode *
253fb_changeres(FB_Mode *cur_mode, unsigned int width, unsigned int height, unsigned int refresh)
254{
255 FB_Mode *modes;
256 unsigned int i, num_modes;
257
258 modes = fb_list_modes(&num_modes);
259 if (modes)
260 {
261 for (i = 0; i < num_modes; i++)
262 {
263 if ((modes[i].width == width) &&
264 (modes[i].height == height) &&
265 (modes[i].refresh == refresh))
266 {
267 modes[i].fb_var.bits_per_pixel = cur_mode->depth;
268
269 if (ioctl(fb, FBIOPUT_VSCREENINFO, &modes[i].fb_var) == -1)
270 perror("ioctl FBIOPUT_VSCREENINFO");
271
272 free(modes);
273 free(cur_mode);
274 return fb_getmode();
275 }
276 }
277 free(modes);
278 }
279 return cur_mode;
280}
281
282FB_Mode *
283fb_changemode(FB_Mode *cur_mode, unsigned int width, unsigned int height, unsigned int pdepth, unsigned int refresh)
284{
285 FB_Mode *modes;
286 unsigned int i, num_modes;
287
288 modes = fb_list_modes(&num_modes);
289 if (modes)
290 {
291 for (i = 0; i < num_modes; i++)
292 {
293 if ((modes[i].width == width) &&
294 (modes[i].height == height) &&
295 (!pdepth || modes[i].fb_var.bits_per_pixel == pdepth) &&
296 (modes[i].refresh == refresh))
297 {
298 if (pdepth) modes[i].fb_var.bits_per_pixel = pdepth;
299
300 if (ioctl(fb, FBIOPUT_VSCREENINFO, &modes[i].fb_var) == -1)
301 perror("ioctl FBIOPUT_VSCREENINFO");
302
303 free(modes);
304 free(cur_mode);
305 return fb_getmode();
306 }
307 }
308 free(modes);
309 }
310 return cur_mode;
311}
312
313FB_Mode *
314fb_getmode(void)
315{
316 FB_Mode *mode = NULL;
317 int hpix, lines, clockrate;
318
319 mode = malloc(sizeof(FB_Mode));
320 /* look what we have now ... */
321
322 if (ioctl(fb, FBIOGET_VSCREENINFO, &mode->fb_var) == -1)
323 {
324 perror("ioctl FBIOGET_VSCREENINFO");
325 return NULL;
326 }
327
328 mode->width = mode->fb_var.xres_virtual;
329 mode->height = mode->fb_var.yres_virtual;
330 hpix =
331 mode->fb_var.left_margin +
332 mode->fb_var.xres +
333 mode->fb_var.right_margin +
334 mode->fb_var.hsync_len;
335 lines =
336 mode->fb_var.upper_margin +
337 mode->fb_var.yres +
338 mode->fb_var.lower_margin +
339 mode->fb_var.vsync_len;
340 if (mode->fb_var.pixclock > 0)
341 clockrate = 1000000 / mode->fb_var.pixclock;
342 else
343 clockrate = 0;
344 if ((lines > 0) && (hpix > 0))
345 mode->refresh = clockrate * 1000000 / (lines * hpix);
346 switch (mode->fb_var.bits_per_pixel)
347 {
348 case 1:
349 bpp = 1;
350 depth = 1;
351 break;
352 case 4:
353 bpp = 1;
354 depth = 4;
355 break;
356 case 8:
357 bpp = 1;
358 depth = 8;
359 break;
360 case 15:
361 case 16:
362 if (mode->fb_var.green.length == 6)
363 depth = 16;
364 else
365 depth = 15;
366 bpp = 2;
367 break;
368 case 24:
369 depth = 24;
370 bpp = mode->fb_var.bits_per_pixel / 8;
371 break;
372 case 32:
373 depth = 32;
374 bpp = mode->fb_var.bits_per_pixel / 8;
375 break;
376 default:
377 ERR("Cannot handle framebuffer of depth %i",
378 mode->fb_var.bits_per_pixel);
379 fb_cleanup();
380 free(mode);
381 return NULL;
382 }
383 mode->depth = depth;
384 mode->bpp = bpp;
385 if (mode->depth == 8) fb_init_palette_332(mode);
386 else fb_init_palette_linear(mode);
387 return mode;
388}
389
390/* XXX: unused
391static void
392fb_setvt(int vtno)
393{
394 struct vt_stat vts;
395 char vtname[32];
396 int vtfd;
397
398 if (vtno < 0)
399 {
400 if ((ioctl(tty,VT_OPENQRY, &vtno) == -1))
401 {
402 perror("ioctl VT_OPENQRY");
403 return;
404 }
405 if (vtno <= 0 )
406 {
407 perror("ioctl VT_OPENQRY vtno <= 0");
408 return;
409 }
410 }
411 vtno &= 0xff;
412 sprintf(vtname, "/dev/tty%i", vtno);
413 if (chown(vtname, getuid(), getgid()) != 0)
414 {
415 vtfd = 0; // do nothing - don't worry about chown
416 }
417 if (access(vtname,R_OK | W_OK) == -1)
418 {
419 CRIT("Access %s: %s",vtname,strerror(errno));
420 return;
421 }
422 vtfd = open(vtname,O_RDWR);
423
424 if (ioctl(tty, VT_GETSTATE, &vts) == -1)
425 {
426 perror("ioctl VT_GETSTATE");
427 close(vtfd);
428 return;
429 }
430
431 orig_vt_no = vts.v_active;
432 close(vtfd);
433#if 0
434 if (ioctl(tty, VT_ACTIVATE, vtno) == -1)
435 {
436 perror("ioctl VT_ACTIVATE");
437 exit(1);
438 }
439 if (ioctl(tty, VT_WAITACTIVE, vtno) == -1)
440 {
441 perror("ioctl VT_WAITACTIVE");
442 exit(1);
443 }
444#endif
445}
446*/
447
448void
449fb_init(int vt __UNUSED__, int device)
450{
451 char dev[32];
452
453 tty = 0;
454#if 0
455 if (vt != 0) fb_setvt(vt);
456#endif
457
458 if ( getenv("EVAS_FB_DEV") )
459 {
460 fb = open(getenv("EVAS_FB_DEV"), O_RDWR);
461 }
462 else
463 {
464 sprintf(dev, "/dev/fb/%i", device);
465 fb = open(dev, O_RDWR);
466 if ( fb == -1 )
467 {
468 sprintf(dev, "/dev/fb%i", device);
469 fb = open(dev, O_RDWR);
470 }
471 }
472 if (fb == -1)
473 {
474 CRIT("open %s: %s", dev, strerror(errno));
475 fb_cleanup();
476 return;
477 }
478
479 if (ioctl(fb, FBIOGET_VSCREENINFO, &fb_ovar) == -1)
480 {
481 perror("ioctl FBIOGET_VSCREENINFO");
482 return;
483 }
484 if (ioctl(fb, FBIOGET_FSCREENINFO, &fb_fix) == -1)
485 {
486 perror("ioctl FBIOGET_FSCREENINFO");
487 return;
488 }
489
490 if ((fb_ovar.bits_per_pixel == 8) ||
491 (fb_fix.visual == FB_VISUAL_DIRECTCOLOR))
492 {
493 if (ioctl(fb,FBIOGETCMAP , &ocmap) == -1)
494 {
495 perror("ioctl FBIOGETCMAP");
496 return;
497 }
498 }
499#if 0
500 if (isatty(0))
501 tty = 0;
502 else if ((tty = open("/dev/tty",O_RDWR)) == -1)
503 {
504 CITICAL("open %s: %s", "/dev/tty", strerror(errno));
505 return;
506 }
507 if (tty)
508 {
509 if (ioctl(tty, KDGETMODE, &kd_mode) == -1)
510 {
511 perror("ioctl KDGETMODE");
512 return;
513 }
514 if (ioctl(tty, VT_GETMODE, &vt_omode) == -1)
515 {
516 perror("ioctl VT_GETMODE");
517 return;
518 }
519 }
520#endif
521}
522
523int
524fb_postinit(FB_Mode *mode)
525{
526 if (ioctl(fb,FBIOGET_FSCREENINFO, &fb_fix) == -1)
527 {
528 perror("ioctl FBIOGET_FSCREENINFO");
529 fb_cleanup();
530 return 0;
531 }
532
533 if (fb_fix.type != FB_TYPE_PACKED_PIXELS)
534 {
535 CRIT("can handle only packed pixel frame buffers");
536 fb_cleanup();
537 return 0;
538 }
539 mode->mem_offset = (unsigned)(fb_fix.smem_start) & (getpagesize()-1);
540 mode->mem = (unsigned char *)mmap(NULL, fb_fix.smem_len + mode->mem_offset,
541 PROT_WRITE | PROT_READ, MAP_SHARED, fb, 0);
542 if (mode->mem == MAP_FAILED)
543 {
544 perror("mmap");
545 fb_cleanup();
546 }
547 /* move viewport to upper left corner */
548 if ((mode->fb_var.xoffset != 0) || (mode->fb_var.yoffset != 0))
549 {
550 mode->fb_var.xoffset = 0;
551 mode->fb_var.yoffset = 0;
552
553 if (ioctl(fb, FBIOPAN_DISPLAY, &(mode->fb_var)) == -1)
554 {
555 perror("ioctl FBIOPAN_DISPLAY");
556 fb_cleanup();
557 }
558 }
559#if 0
560 if (tty)
561 {
562 if (ioctl(tty,KDSETMODE, KD_GRAPHICS) == -1)
563 {
564 perror("ioctl KDSETMODE");
565 fb_cleanup();
566 }
567 }
568#endif
569 mode->fb_fd = fb;
570 return fb;
571}
572
573static void
574fb_cleanup(void)
575{
576 /* restore console */
577 if (ioctl(fb, FBIOPUT_VSCREENINFO, &fb_ovar) == -1)
578 perror("ioctl FBIOPUT_VSCREENINFO");
579 if (ioctl(fb, FBIOGET_FSCREENINFO, &fb_fix) == -1)
580 perror("ioctl FBIOGET_FSCREENINFO");
581 if ((fb_ovar.bits_per_pixel == 8) ||
582 (fb_fix.visual == FB_VISUAL_DIRECTCOLOR))
583 {
584 if (ioctl(fb, FBIOPUTCMAP, &ocmap) == -1)
585 perror("ioctl FBIOPUTCMAP");
586 }
587 close(fb);
588 if (tty)
589 {
590 if (ioctl(tty, KDSETMODE, kd_mode) == -1)
591 perror("ioctl KDSETMODE");
592 if (ioctl(tty, VT_SETMODE, &vt_omode) == -1)
593 perror("ioctl VT_SETMODE");
594#if 0
595 if ((ioctl(tty, VT_ACTIVATE, orig_vt_no) == -1) && (orig_vt_no))
596 perror("ioctl VT_ACTIVATE");
597#endif
598 }
599 close(tty);
600}