]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/examples/fb/spectrum/spectrum.cc
update
[l4.git] / l4 / pkg / examples / fb / spectrum / spectrum.cc
1 /**
2  * \file
3  * \brief       fb usage demo, with C and C++
4  * \author      Adam Lackorzynski <adam@os.inf.tu-dresden.de>
5  **/
6
7 /* (c) 2010, Adam Lackorzynski
8  *     economic rights: Technische Universität Dresden (Germany)
9  * This file is part of the con package, which is distributed under
10  * the terms of the GNU General Public License 2. Please see the
11  * COPYING file for details. */
12
13 /*
14  * Event handling in C mode has not been done.
15  */
16
17 #define DO_CPP 1
18
19 #ifdef DO_CPP
20 #include <l4/re/util/video/goos_fb>
21 #include <l4/re/util/event>
22 #include <l4/event/event>
23 #else
24 #include <l4/re/c/util/video/goos_fb.h>
25 #endif
26
27 #include <l4/re/event_enums.h>
28 #include <l4/util/keymap.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <unistd.h>
32 #include <string.h>
33
34 #ifdef DO_CPP
35 static L4Re::Util::Video::Goos_fb gfb;
36 static L4Re::Video::View::Info fbi;
37 static L4Re::Util::Event event;
38 #else
39 static l4re_util_video_goos_fb_t gfb;
40 static l4re_video_view_info_t fbi;
41 #endif
42
43 static void *fbmem_vaddr;
44 static unsigned bpp;
45
46 static void put_pixel(int x, int y, int fullval)
47 {
48   unsigned v = 0;
49 #ifdef DO_CPP
50   unsigned long offset = (unsigned long)fbmem_vaddr + y * fbi.bytes_per_line + x * fbi.pixel_info.bytes_per_pixel();
51   v  = ((fullval >> (8  - fbi.pixel_info.r().size())) & ((1 << fbi.pixel_info.r().size()) - 1)) << fbi.pixel_info.r().shift();
52   v |= ((fullval >> (16 - fbi.pixel_info.g().size())) & ((1 << fbi.pixel_info.g().size()) - 1)) << fbi.pixel_info.g().shift();
53   v |= ((fullval >> (24 - fbi.pixel_info.b().size())) & ((1 << fbi.pixel_info.b().size()) - 1)) << fbi.pixel_info.b().shift();
54 #else
55   unsigned bpp = l4re_video_bits_per_pixel(&fbi.pixel_info);
56   unsigned long offset = (unsigned long)fbmem_vaddr + y * fbi.bytes_per_line + x * fbi.pixel_info.bytes_per_pixel;
57   v  = ((fullval >> (8  - fbi.pixel_info.r.size)) & ((1 << fbi.pixel_info.r.size) - 1)) << fbi.pixel_info.r.shift;
58   v |= ((fullval >> (16 - fbi.pixel_info.g.size)) & ((1 << fbi.pixel_info.g.size) - 1)) << fbi.pixel_info.g.shift;
59   v |= ((fullval >> (24 - fbi.pixel_info.b.size)) & ((1 << fbi.pixel_info.b.size) - 1)) << fbi.pixel_info.b.shift;
60 #endif
61
62   switch (bpp)
63     {
64     case 8: *(unsigned char  *)offset = v; break;
65     case 14: case 15: case 16: *(unsigned short *)offset = v; break;
66     case 24: case 32: *(unsigned int   *)offset = v; break;
67     default:
68       printf("unhandled bitsperpixel %d\n", bpp);
69     };
70 }
71
72 static void update_rect(int x, int y, int w, int h)
73 {
74 #ifdef DO_CPP
75   gfb.refresh(x, y, w, h);
76 #else
77   l4re_util_video_goos_fb_refresh(&gfb, x, y, w, h);
78 #endif
79 }
80
81 static inline unsigned color_val(unsigned w, unsigned peak_point, unsigned val)
82 {
83   unsigned third = w / 3;
84
85   unsigned a = abs(val - peak_point);
86   if (a > third * 2)
87     a = peak_point + w - val;
88   if (a > third)
89     return 0;
90
91   return ((third - a) * 255) / third;
92 }
93
94 #ifdef DO_CPP
95 static void ev_hdl_func(void *data)
96 {
97   (void)data;
98   while (L4Re::Event_buffer::Event *e = event.buffer().next())
99     {
100       int k;
101       printf("Event: %16lld: %d %d %d\n",
102              e->time, e->payload.type, e->payload.code, e->payload.value);
103       if (e->payload.type == L4RE_EV_KEY
104           && ((k = l4util_map_event_to_keymap(e->payload.code, 0)) >= 32))
105         printf("   key: %c\n", k);
106       // proper mouse and keyboard handling code comes here
107       e->free();
108     }
109 }
110 #endif
111
112 int main(void)
113 {
114 #ifdef DO_CPP
115   try { gfb.setup("fb"); } catch (...) { return 1; }
116   if (gfb.view_info(&fbi))
117     return 2;
118
119   if (!(fbmem_vaddr = gfb.attach_buffer()))
120     return 3;
121
122    bpp = fbi.pixel_info.bits_per_pixel();
123
124    if (event.init(L4::cap_dynamic_cast<L4Re::Event>(gfb.goos())))
125      return 4;
126
127    Event::Event event_hdl(event.irq(), ev_hdl_func, NULL, 4);
128    if (!event_hdl.attached())
129      return 5;
130 #else
131   if (l4re_util_video_goos_fb_setup_name(&gfb, "fb"))
132     return 1;
133
134   if (l4re_util_video_goos_fb_view_info(&gfb, &fbi))
135     return 2;
136
137   if (!(fbmem_vaddr = l4re_util_video_goos_fb_attach_buffer(&gfb)))
138     return 3;
139
140    bpp = l4re_video_bits_per_pixel(&fbi.pixel_info);
141 #endif
142
143   printf("x:%ld y:%ld bit/pixel:%d bytes/line:%ld\n",
144          fbi.width, fbi.width, bpp, fbi.bytes_per_line);
145
146   // now some fancy stuff
147   unsigned w = fbi.width;
148   unsigned h = fbi.height;
149   unsigned t = w / 3;
150
151   for (unsigned cnt = 0; ; cnt += 2)
152     {
153       for (unsigned y = 0; y < h; ++y)
154         for (unsigned x = 0; x < w; ++x)
155           {
156             unsigned r = color_val(w, 0 * t, (x + cnt) % w);
157             unsigned g = color_val(h, 1 * t, (y + (cnt >> 1)) % h);
158             unsigned b = color_val(w, 2 * t, (w - x + cnt) % w);
159
160             //printf("%3d: %3d:%3d:%3d\n", x, r, g, b);
161             put_pixel(x, y, (r << 0) | (g << 8) | (b << 16));
162           }
163
164       update_rect(0, 0, fbi.width, fbi.height);
165       usleep(100000);
166     }
167
168   return 0;
169 }