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
RevLine 
[b1f51f0]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>
[e1c4849]31#include <async.h>
32#include <stdio.h>
[90f5d64]33#include <sys/mman.h>
34#include <string.h>
[a7d2d78]35#include <align.h>
[b1f51f0]36
37#include "console.h"
[e1c4849]38#include "gcons.h"
[b1f51f0]39
[90f5d64]40#define CONSOLE_TOP 65
[a7d2d78]41#define CONSOLE_MARGIN 6
[b1f51f0]42
[a7d2d78]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
[b1f51f0]48
[90f5d64]49#define MAIN_COLOR 0xffffff
[e1c4849]50
[b1f51f0]51static int use_gcons = 0;
52static ipcarg_t xres,yres;
53
[a7d2d78]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
[b1f51f0]64static int console_vp;
65static int cstatus_vp[CONSOLE_COUNT];
[e1c4849]66static int cstat_row, cstat_col; /* Size of cstatus buttons */
[a7d2d78]67static enum butstate console_state[CONSOLE_COUNT];
[b1f51f0]68
69static int fbphone;
70
[a7d2d78]71/** List of pixmaps identifying these icons */
72static int ic_pixmaps[CONS_LAST] = {-1,-1,-1,-1,-1,-1};
[1fd7700]73static int animation = -1;
[e1c4849]74
75static int active_console = 0;
76
[b1f51f0]77static void vp_switch(int vp)
78{
[085bd54]79 async_msg(fbphone,FB_VIEWPORT_SWITCH, vp);
[b1f51f0]80}
81
[e1c4849]82/** Create view port */
[b1f51f0]83static int vp_create(unsigned int x, unsigned int y,
[e1c4849]84 unsigned int width, unsigned int height)
[b1f51f0]85{
[e1c4849]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);
[b1f51f0]90}
91
[e1c4849]92static void clear(void)
[b1f51f0]93{
[085bd54]94 async_msg(fbphone, FB_CLEAR, 0);
[b1f51f0]95
96}
97
[e1c4849]98static void set_style(int fgcolor, int bgcolor)
99{
[085bd54]100 async_msg_2(fbphone, FB_SET_STYLE, fgcolor, bgcolor);
[e1c4849]101}
102
[d530237a]103/** Transparent putchar */
104static void tran_putch(char c, int row, int col)
[e1c4849]105{
[085bd54]106 async_msg_3(fbphone, FB_TRANS_PUTCHAR, c, row, col);
[e1c4849]107}
108
[d530237a]109/** Redraw the button showing state of a given console */
[a7d2d78]110static void redraw_state(int consnum)
[b1f51f0]111{
[e1c4849]112 char data[5];
113 int i;
[a7d2d78]114 enum butstate state = console_state[consnum];
115
[e1c4849]116 vp_switch(cstatus_vp[consnum]);
[a7d2d78]117 if (ic_pixmaps[state] != -1)
[085bd54]118 async_msg_2(fbphone, FB_VP_DRAW_PIXMAP, cstatus_vp[consnum], ic_pixmaps[state]);
[a7d2d78]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++)
[d530237a]123 tran_putch(data[i], 1, 2+i);
[a7d2d78]124 }
[b1f51f0]125}
126
[a7d2d78]127/** Notification run on changing console (except kernel console) */
[b1f51f0]128void gcons_change_console(int consnum)
129{
[a7d2d78]130 int i;
131
[b1f51f0]132 if (!use_gcons)
133 return;
[429acb9]134
[a7d2d78]135 if (active_console == KERNEL_CONSOLE) {
136 for (i=0; i < CONSOLE_COUNT; i++)
137 redraw_state(i);
[70178b74]138 if (animation != -1)
139 async_msg(fbphone, FB_ANIM_START, animation);
[a7d2d78]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 }
[e1c4849]147 active_console = consnum;
[a7d2d78]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);
[d6cc453]155
[b1f51f0]156 vp_switch(console_vp);
157}
158
[429acb9]159/** Notification function that gets called on new output to virtual console */
[b1f51f0]160void gcons_notify_char(int consnum)
161{
162 if (!use_gcons)
163 return;
164
[a7d2d78]165 if (consnum == active_console || console_state[consnum] == CONS_HAS_DATA)
[d6cc453]166 return;
167
[a7d2d78]168 console_state[consnum] = CONS_HAS_DATA;
[429acb9]169
[a7d2d78]170 if (active_console == KERNEL_CONSOLE)
[429acb9]171 return;
172
[a7d2d78]173 redraw_state(consnum);
[d6cc453]174
[b1f51f0]175 vp_switch(console_vp);
[a7d2d78]176}
[429acb9]177
[e9073f2]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
[d530237a]195/** Notification function called on console connect */
[a7d2d78]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);
[b1f51f0]210}
211
[429acb9]212/** Change to kernel console */
213void gcons_in_kernel(void)
214{
[a78e273]215 if (console_state[active_console] == CONS_DISCONNECTED_SEL)
[a7d2d78]216 console_state[active_console] = CONS_DISCONNECTED;
217 else
218 console_state[active_console] = CONS_IDLE;
219 redraw_state(active_console);
220
[70178b74]221 if (animation != -1)
222 async_msg(fbphone, FB_ANIM_STOP, animation);
223
[a7d2d78]224 active_console = KERNEL_CONSOLE; /* Set to kernel console */
[429acb9]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 */
[90f5d64]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 */
[085bd54]247 rc = async_req_2(fbphone, FB_PREPARE_SHM, (ipcarg_t)shm, 0, NULL, NULL);
[90f5d64]248 if (rc)
249 goto exit;
[085bd54]250 rc = async_req_3(fbphone, IPC_M_AS_AREA_SEND, (ipcarg_t)shm, 0, PROTO_READ, NULL, NULL, NULL);
[90f5d64]251 if (rc)
252 goto drop;
253 /* Draw logo */
[085bd54]254 async_msg_2(fbphone, FB_DRAW_PPM, x, y);
[90f5d64]255drop:
256 /* Drop area */
[085bd54]257 async_msg(fbphone, FB_DROP_SHM, 0);
[90f5d64]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;
[d530237a]267/** Redraws console graphics */
[a7d2d78]268static void gcons_redraw_console(void)
[b1f51f0]269{
[e1c4849]270 int i;
[90f5d64]271 size_t hsize = (size_t)&_binary_helenos_ppm_size;
[e1c4849]272
[b1f51f0]273 if (!use_gcons)
274 return;
275
276 vp_switch(0);
[e1c4849]277 set_style(MAIN_COLOR, MAIN_COLOR);
278 clear();
[a7d2d78]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);
[90f5d64]281
[e1c4849]282 for (i=0;i < CONSOLE_COUNT; i++)
[a7d2d78]283 redraw_state(i);
[b1f51f0]284 vp_switch(console_vp);
285}
286
[d530237a]287/** Creates a pixmap on framebuffer
288 *
289 * @param data PPM data
290 * @param size PPM data size
291 * @return Pixmap identification
292 */
[a7d2d78]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 */
[085bd54]306 rc = async_req_2(fbphone, FB_PREPARE_SHM, (ipcarg_t)shm, 0, NULL, NULL);
[a7d2d78]307 if (rc)
308 goto exit;
[085bd54]309 rc = async_req_3(fbphone, IPC_M_AS_AREA_SEND, (ipcarg_t)shm, 0, PROTO_READ, NULL, NULL, NULL);
[a7d2d78]310 if (rc)
311 goto drop;
312
313 /* Obtain pixmap */
[085bd54]314 rc = async_req(fbphone, FB_SHM2PIXMAP, 0, NULL);
[a7d2d78]315 if (rc < 0)
316 goto drop;
317 pxid = rc;
318drop:
319 /* Drop area */
[085bd54]320 async_msg(fbphone, FB_DROP_SHM, 0);
[a7d2d78]321exit:
322 /* Remove area */
323 munmap(shm, size);
324
325 return pxid;
326}
327
[1fd7700]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
[a7d2d78]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;
[b1f51f0]370/** Initialize nice graphical console environment */
371void gcons_init(int phone)
372{
373 int rc;
374 int i;
[1fd7700]375 int status_start = STATUS_START;
[b1f51f0]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 */
[a7d2d78]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));
[b1f51f0]391 if (console_vp < 0)
392 return;
393
394 /* Create status buttons */
[1fd7700]395 status_start += (xres-800) / 2;
[b1f51f0]396 for (i=0; i < CONSOLE_COUNT; i++) {
[1fd7700]397 cstatus_vp[i] = vp_create(status_start+CONSOLE_MARGIN+i*(STATUS_WIDTH+STATUS_SPACE),
[a7d2d78]398 STATUS_TOP, STATUS_WIDTH, STATUS_HEIGHT);
[b1f51f0]399 if (cstatus_vp[i] < 0)
400 return;
[a7d2d78]401 vp_switch(cstatus_vp[i]);
402 set_style(0x202020, 0xffffff);
[b1f51f0]403 }
404
[a7d2d78]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];
[1fd7700]417
418 make_anim();
[a7d2d78]419
[b1f51f0]420 use_gcons = 1;
[a7d2d78]421 console_state[0] = CONS_DISCONNECTED_SEL;
422 console_state[KERNEL_CONSOLE] = CONS_KERNEL;
[e1c4849]423 gcons_redraw_console();
[b1f51f0]424}
Note: See TracBrowser for help on using the repository browser.