source: mainline/console/gcons.c@ 70178b74

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 70178b74 was 70178b74, checked in by Ondrej Palkovsky <ondrap@…>, 19 years ago

Turn off animation on kconsole.

  • Property mode set to 100644
File size: 11.1 KB
Line 
1/*
2 * Copyright (C) 2006 Ondrej Palkovsky
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <ipc/fb.h>
30#include <ipc/ipc.h>
31#include <async.h>
32#include <stdio.h>
33#include <sys/mman.h>
34#include <string.h>
35#include <align.h>
36
37#include "console.h"
38#include "gcons.h"
39
40#define CONSOLE_TOP 65
41#define CONSOLE_MARGIN 6
42
43#define STATUS_START 110
44#define STATUS_TOP 8
45#define STATUS_SPACE 3
46#define STATUS_WIDTH 48
47#define STATUS_HEIGHT 48
48
49#define MAIN_COLOR 0xffffff
50
51static int use_gcons = 0;
52static ipcarg_t xres,yres;
53
54enum butstate {
55 CONS_DISCONNECTED = 0,
56 CONS_SELECTED,
57 CONS_IDLE,
58 CONS_HAS_DATA,
59 CONS_KERNEL,
60 CONS_DISCONNECTED_SEL,
61 CONS_LAST
62};
63
64static int console_vp;
65static int cstatus_vp[CONSOLE_COUNT];
66static int cstat_row, cstat_col; /* Size of cstatus buttons */
67static enum butstate console_state[CONSOLE_COUNT];
68
69static int fbphone;
70
71/** List of pixmaps identifying these icons */
72static int ic_pixmaps[CONS_LAST] = {-1,-1,-1,-1,-1,-1};
73static int animation = -1;
74
75static int active_console = 0;
76
77static void vp_switch(int vp)
78{
79 async_msg(fbphone,FB_VIEWPORT_SWITCH, vp);
80}
81
82/** Create view port */
83static int vp_create(unsigned int x, unsigned int y,
84 unsigned int width, unsigned int height)
85{
86 /* Init function, use ipc_call_sync */
87 return ipc_call_sync_2(fbphone, FB_VIEWPORT_CREATE,
88 (x << 16) | y, (width << 16) | height,
89 NULL, NULL);
90}
91
92static void clear(void)
93{
94 async_msg(fbphone, FB_CLEAR, 0);
95
96}
97
98static void set_style(int fgcolor, int bgcolor)
99{
100 async_msg_2(fbphone, FB_SET_STYLE, fgcolor, bgcolor);
101}
102
103/** Transparent putchar */
104static void tran_putch(char c, int row, int col)
105{
106 async_msg_3(fbphone, FB_TRANS_PUTCHAR, c, row, col);
107}
108
109/** Redraw the button showing state of a given console */
110static void redraw_state(int consnum)
111{
112 char data[5];
113 int i;
114 enum butstate state = console_state[consnum];
115
116 vp_switch(cstatus_vp[consnum]);
117 if (ic_pixmaps[state] != -1)
118 async_msg_2(fbphone, FB_VP_DRAW_PIXMAP, cstatus_vp[consnum], ic_pixmaps[state]);
119
120 if (state != CONS_DISCONNECTED && state != CONS_KERNEL && state != CONS_DISCONNECTED_SEL) {
121 snprintf(data, 5, "%d", consnum+1);
122 for (i=0;data[i];i++)
123 tran_putch(data[i], 1, 2+i);
124 }
125}
126
127/** Notification run on changing console (except kernel console) */
128void gcons_change_console(int consnum)
129{
130 int i;
131
132 if (!use_gcons)
133 return;
134
135 if (active_console == KERNEL_CONSOLE) {
136 for (i=0; i < CONSOLE_COUNT; i++)
137 redraw_state(i);
138 if (animation != -1)
139 async_msg(fbphone, FB_ANIM_START, animation);
140 } else {
141 if (console_state[active_console] == CONS_DISCONNECTED_SEL)
142 console_state[active_console] = CONS_DISCONNECTED;
143 else
144 console_state[active_console] = CONS_IDLE;
145 redraw_state(active_console);
146 }
147 active_console = consnum;
148
149 if (console_state[consnum] == CONS_DISCONNECTED) {
150 console_state[consnum] = CONS_DISCONNECTED_SEL;
151 redraw_state(consnum);
152 } else
153 console_state[consnum] = CONS_SELECTED;
154 redraw_state(consnum);
155
156 vp_switch(console_vp);
157}
158
159/** Notification function that gets called on new output to virtual console */
160void gcons_notify_char(int consnum)
161{
162 if (!use_gcons)
163 return;
164
165 if (consnum == active_console || console_state[consnum] == CONS_HAS_DATA)
166 return;
167
168 console_state[consnum] = CONS_HAS_DATA;
169
170 if (active_console == KERNEL_CONSOLE)
171 return;
172
173 redraw_state(consnum);
174
175 vp_switch(console_vp);
176}
177
178/** Notification function called on service disconnect from console */
179void gcons_notify_disconnect(int consnum)
180{
181 if (!use_gcons)
182 return;
183 if (active_console == consnum)
184 console_state[consnum] = CONS_DISCONNECTED_SEL;
185 else
186 console_state[consnum] = CONS_DISCONNECTED;
187
188 if (active_console == KERNEL_CONSOLE)
189 return;
190
191 redraw_state(consnum);
192 vp_switch(console_vp);
193}
194
195/** Notification function called on console connect */
196void gcons_notify_connect(int consnum)
197{
198 if (!use_gcons)
199 return;
200 if (active_console == consnum)
201 console_state[consnum] = CONS_SELECTED;
202 else
203 console_state[consnum] = CONS_IDLE;
204
205 if (active_console == KERNEL_CONSOLE)
206 return;
207
208 redraw_state(consnum);
209 vp_switch(console_vp);
210}
211
212/** Change to kernel console */
213void gcons_in_kernel(void)
214{
215 if (console_state[active_console] == CONS_DISCONNECTED_SEL)
216 console_state[active_console] = CONS_DISCONNECTED;
217 else
218 console_state[active_console] = CONS_IDLE;
219 redraw_state(active_console);
220
221 if (animation != -1)
222 async_msg(fbphone, FB_ANIM_STOP, animation);
223
224 active_console = KERNEL_CONSOLE; /* Set to kernel console */
225 vp_switch(0);
226}
227
228/** Draw a PPM pixmap to framebuffer
229 *
230 * @param logo Pointer to PPM data
231 * @param size Size of PPM data
232 * @param x Coordinate of upper left corner
233 * @param y Coordinate of upper left corner
234 */
235static void draw_pixmap(char *logo, size_t size, int x, int y)
236{
237 char *shm;
238 int rc;
239
240 /* Create area */
241 shm = mmap(NULL, size, PROTO_READ | PROTO_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
242 if (shm == MAP_FAILED)
243 return;
244
245 memcpy(shm, logo, size);
246 /* Send area */
247 rc = async_req_2(fbphone, FB_PREPARE_SHM, (ipcarg_t)shm, 0, NULL, NULL);
248 if (rc)
249 goto exit;
250 rc = async_req_3(fbphone, IPC_M_AS_AREA_SEND, (ipcarg_t)shm, 0, PROTO_READ, NULL, NULL, NULL);
251 if (rc)
252 goto drop;
253 /* Draw logo */
254 async_msg_2(fbphone, FB_DRAW_PPM, x, y);
255drop:
256 /* Drop area */
257 async_msg(fbphone, FB_DROP_SHM, 0);
258exit:
259 /* Remove area */
260 munmap(shm, size);
261}
262
263extern char _binary_helenos_ppm_start[0];
264extern int _binary_helenos_ppm_size;
265extern char _binary_nameic_ppm_start[0];
266extern int _binary_nameic_ppm_size;
267/** Redraws console graphics */
268static void gcons_redraw_console(void)
269{
270 int i;
271 size_t hsize = (size_t)&_binary_helenos_ppm_size;
272
273 if (!use_gcons)
274 return;
275
276 vp_switch(0);
277 set_style(MAIN_COLOR, MAIN_COLOR);
278 clear();
279 draw_pixmap(_binary_helenos_ppm_start, (size_t)&_binary_helenos_ppm_size, xres-66, 2);
280 draw_pixmap(_binary_nameic_ppm_start, (size_t)&_binary_nameic_ppm_size, 5, 17);
281
282 for (i=0;i < CONSOLE_COUNT; i++)
283 redraw_state(i);
284 vp_switch(console_vp);
285}
286
287/** Creates a pixmap on framebuffer
288 *
289 * @param data PPM data
290 * @param size PPM data size
291 * @return Pixmap identification
292 */
293static int make_pixmap(char *data, int size)
294{
295 char *shm;
296 int rc;
297 int pxid = -1;
298
299 /* Create area */
300 shm = mmap(NULL, size, PROTO_READ | PROTO_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
301 if (shm == MAP_FAILED)
302 return -1;
303
304 memcpy(shm, data, size);
305 /* Send area */
306 rc = async_req_2(fbphone, FB_PREPARE_SHM, (ipcarg_t)shm, 0, NULL, NULL);
307 if (rc)
308 goto exit;
309 rc = async_req_3(fbphone, IPC_M_AS_AREA_SEND, (ipcarg_t)shm, 0, PROTO_READ, NULL, NULL, NULL);
310 if (rc)
311 goto drop;
312
313 /* Obtain pixmap */
314 rc = async_req(fbphone, FB_SHM2PIXMAP, 0, NULL);
315 if (rc < 0)
316 goto drop;
317 pxid = rc;
318drop:
319 /* Drop area */
320 async_msg(fbphone, FB_DROP_SHM, 0);
321exit:
322 /* Remove area */
323 munmap(shm, size);
324
325 return pxid;
326}
327
328extern char _binary_anim_1_ppm_start[0];
329extern int _binary_anim_1_ppm_size;
330extern char _binary_anim_2_ppm_start[0];
331extern int _binary_anim_2_ppm_size;
332extern char _binary_anim_3_ppm_start[0];
333extern int _binary_anim_3_ppm_size;
334extern char _binary_anim_4_ppm_start[0];
335extern int _binary_anim_4_ppm_size;
336static void make_anim(void)
337{
338 int an;
339 int pm;
340
341 an = async_req(fbphone, FB_ANIM_CREATE, cstatus_vp[KERNEL_CONSOLE], NULL);
342 if (an < 0)
343 return;
344
345 pm = make_pixmap(_binary_anim_1_ppm_start, (int)&_binary_anim_1_ppm_size);
346 async_msg_2(fbphone, FB_ANIM_ADDPIXMAP, an, pm);
347
348 pm = make_pixmap(_binary_anim_2_ppm_start, (int)&_binary_anim_2_ppm_size);
349 async_msg_2(fbphone, FB_ANIM_ADDPIXMAP, an, pm);
350
351 pm = make_pixmap(_binary_anim_3_ppm_start, (int)&_binary_anim_3_ppm_size);
352 async_msg_2(fbphone, FB_ANIM_ADDPIXMAP, an, pm);
353
354 pm = make_pixmap(_binary_anim_4_ppm_start, (int)&_binary_anim_4_ppm_size);
355 async_msg_2(fbphone, FB_ANIM_ADDPIXMAP, an, pm);
356
357 async_msg(fbphone, FB_ANIM_START, an);
358
359 animation = an;
360}
361
362extern char _binary_cons_selected_ppm_start[0];
363extern int _binary_cons_selected_ppm_size;
364extern char _binary_cons_idle_ppm_start[0];
365extern int _binary_cons_idle_ppm_size;
366extern char _binary_cons_has_data_ppm_start[0];
367extern int _binary_cons_has_data_ppm_size;
368extern char _binary_cons_kernel_ppm_start[0];
369extern int _binary_cons_kernel_ppm_size;
370/** Initialize nice graphical console environment */
371void gcons_init(int phone)
372{
373 int rc;
374 int i;
375 int status_start = STATUS_START;
376
377 fbphone = phone;
378
379 rc = ipc_call_sync_2(phone, FB_GET_RESOLUTION, 0, 0, &xres, &yres);
380 if (rc)
381 return;
382
383 if (xres < 800 || yres < 600)
384 return;
385
386 /* create console viewport */
387 /* Align width & height to character size */
388 console_vp = vp_create(CONSOLE_MARGIN, CONSOLE_TOP,
389 ALIGN_DOWN(xres-2*CONSOLE_MARGIN, 8),
390 ALIGN_DOWN(yres-(CONSOLE_TOP+CONSOLE_MARGIN),16));
391 if (console_vp < 0)
392 return;
393
394 /* Create status buttons */
395 status_start += (xres-800) / 2;
396 for (i=0; i < CONSOLE_COUNT; i++) {
397 cstatus_vp[i] = vp_create(status_start+CONSOLE_MARGIN+i*(STATUS_WIDTH+STATUS_SPACE),
398 STATUS_TOP, STATUS_WIDTH, STATUS_HEIGHT);
399 if (cstatus_vp[i] < 0)
400 return;
401 vp_switch(cstatus_vp[i]);
402 set_style(0x202020, 0xffffff);
403 }
404
405 /* Initialize icons */
406 ic_pixmaps[CONS_SELECTED] = make_pixmap(_binary_cons_selected_ppm_start,
407 (int)&_binary_cons_selected_ppm_size);
408 ic_pixmaps[CONS_IDLE] = make_pixmap(_binary_cons_idle_ppm_start,
409 (int)&_binary_cons_idle_ppm_size);
410 ic_pixmaps[CONS_HAS_DATA] = make_pixmap(_binary_cons_has_data_ppm_start,
411 (int)&_binary_cons_has_data_ppm_size);
412 ic_pixmaps[CONS_DISCONNECTED] = make_pixmap(_binary_cons_idle_ppm_start,
413 (int)&_binary_cons_idle_ppm_size);
414 ic_pixmaps[CONS_KERNEL] = make_pixmap(_binary_cons_kernel_ppm_start,
415 (int)&_binary_cons_kernel_ppm_size);
416 ic_pixmaps[CONS_DISCONNECTED_SEL] = ic_pixmaps[CONS_SELECTED];
417
418 make_anim();
419
420 use_gcons = 1;
421 console_state[0] = CONS_DISCONNECTED_SEL;
422 console_state[KERNEL_CONSOLE] = CONS_KERNEL;
423 gcons_redraw_console();
424}
Note: See TracBrowser for help on using the repository browser.