Subversion Repositories HelenOS

Rev

Rev 4456 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4456 Rev 4494
1
/*
1
/*
2
 * Copyright (c) 2006 Ondrej Palkovsky
2
 * Copyright (c) 2006 Ondrej Palkovsky
3
 * All rights reserved.
3
 * All rights reserved.
4
 *
4
 *
5
 * Redistribution and use in source and binary forms, with or without
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
6
 * modification, are permitted provided that the following conditions
7
 * are met:
7
 * are met:
8
 *
8
 *
9
 * - Redistributions of source code must retain the above copyright
9
 * - Redistributions of source code must retain the above copyright
10
 *   notice, this list of conditions and the following disclaimer.
10
 *   notice, this list of conditions and the following disclaimer.
11
 * - Redistributions in binary form must reproduce the above copyright
11
 * - Redistributions in binary form must reproduce the above copyright
12
 *   notice, this list of conditions and the following disclaimer in the
12
 *   notice, this list of conditions and the following disclaimer in the
13
 *   documentation and/or other materials provided with the distribution.
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
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.
15
 *   derived from this software without specific prior written permission.
16
 *
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
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
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
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
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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
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.
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 */
27
 */
28
 
28
 
29
/** @addtogroup console
29
/** @addtogroup console
30
 * @{
30
 * @{
31
 */
31
 */
32
/** @file
32
/** @file
33
 */
33
 */
34
 
34
 
35
#include <ipc/fb.h>
35
#include <ipc/fb.h>
36
#include <ipc/ipc.h>
36
#include <ipc/ipc.h>
37
#include <async.h>
37
#include <async.h>
38
#include <stdio.h>
38
#include <stdio.h>
39
#include <sys/mman.h>
39
#include <sys/mman.h>
40
#include <string.h>
40
#include <string.h>
41
#include <align.h>
41
#include <align.h>
42
#include <bool.h>
42
#include <bool.h>
43
 
43
 
44
#include "console.h"
44
#include "console.h"
45
#include "gcons.h"
45
#include "gcons.h"
46
 
46
 
47
#define CONSOLE_TOP     66
47
#define CONSOLE_TOP     66
48
#define CONSOLE_MARGIN  6
48
#define CONSOLE_MARGIN  6
49
 
49
 
50
#define STATUS_START   110
50
#define STATUS_START   110
51
#define STATUS_TOP     8
51
#define STATUS_TOP     8
52
#define STATUS_SPACE   4
52
#define STATUS_SPACE   4
53
#define STATUS_WIDTH   48
53
#define STATUS_WIDTH   48
54
#define STATUS_HEIGHT  48
54
#define STATUS_HEIGHT  48
55
 
55
 
56
#define MAIN_COLOR  0xffffff
56
#define MAIN_COLOR  0xffffff
57
 
57
 
58
static bool use_gcons = false;
58
static bool use_gcons = false;
59
static ipcarg_t xres;
59
static ipcarg_t xres;
60
static ipcarg_t yres;
60
static ipcarg_t yres;
61
 
61
 
62
enum butstate {
62
enum butstate {
63
    CONS_DISCONNECTED = 0,
63
    CONS_DISCONNECTED = 0,
64
    CONS_SELECTED,
64
    CONS_SELECTED,
65
    CONS_IDLE,
65
    CONS_IDLE,
66
    CONS_HAS_DATA,
66
    CONS_HAS_DATA,
67
    CONS_KERNEL,
67
    CONS_KERNEL,
68
    CONS_DISCONNECTED_SEL,
68
    CONS_DISCONNECTED_SEL,
69
    CONS_LAST
69
    CONS_LAST
70
};
70
};
71
 
71
 
72
static int console_vp;
72
static int console_vp;
73
static int cstatus_vp[CONSOLE_COUNT];
73
static int cstatus_vp[CONSOLE_COUNT];
74
static enum butstate console_state[CONSOLE_COUNT];
74
static enum butstate console_state[CONSOLE_COUNT];
75
 
75
 
76
static int fbphone;
76
static int fbphone;
77
 
77
 
78
/** List of pixmaps identifying these icons */
78
/** List of pixmaps identifying these icons */
79
static int ic_pixmaps[CONS_LAST] = {-1, -1, -1, -1, -1, -1};
79
static int ic_pixmaps[CONS_LAST] = {-1, -1, -1, -1, -1, -1};
80
static int animation = -1;
80
static int animation = -1;
81
 
81
 
82
static size_t active_console = 0;
82
static size_t active_console = 0;
83
 
83
 
84
size_t mouse_x;
84
size_t mouse_x;
85
size_t mouse_y;
85
size_t mouse_y;
86
 
86
 
87
bool btn_pressed;
87
bool btn_pressed;
88
size_t btn_x;
88
size_t btn_x;
89
size_t btn_y;
89
size_t btn_y;
90
 
90
 
91
static void vp_switch(int vp)
91
static void vp_switch(int vp)
92
{
92
{
93
    async_msg_1(fbphone, FB_VIEWPORT_SWITCH, vp);
93
    async_msg_1(fbphone, FB_VIEWPORT_SWITCH, vp);
94
}
94
}
95
 
95
 
96
/** Create view port */
96
/** Create view port */
97
static int vp_create(size_t x, size_t y, size_t width, size_t height)
97
static int vp_create(size_t x, size_t y, size_t width, size_t height)
98
{
98
{
99
    return async_req_2_0(fbphone, FB_VIEWPORT_CREATE, (x << 16) | y,
99
    return async_req_2_0(fbphone, FB_VIEWPORT_CREATE, (x << 16) | y,
100
        (width << 16) | height);
100
        (width << 16) | height);
101
}
101
}
102
 
102
 
103
static void clear(void)
103
static void clear(void)
104
{
104
{
105
    async_msg_0(fbphone, FB_CLEAR);
105
    async_msg_0(fbphone, FB_CLEAR);
106
}
106
}
107
 
107
 
108
static void set_rgb_color(uint32_t fgcolor, uint32_t bgcolor)
108
static void set_rgb_color(uint32_t fgcolor, uint32_t bgcolor)
109
{
109
{
110
    async_msg_2(fbphone, FB_SET_RGB_COLOR, fgcolor, bgcolor);
110
    async_msg_2(fbphone, FB_SET_RGB_COLOR, fgcolor, bgcolor);
111
}
111
}
112
 
112
 
113
/** Transparent putchar */
113
/** Transparent putchar */
114
static void tran_putch(wchar_t ch, size_t col, size_t row)
114
static void tran_putch(wchar_t ch, size_t col, size_t row)
115
{
115
{
116
    async_msg_3(fbphone, FB_PUTCHAR, ch, col, row);
116
    async_msg_3(fbphone, FB_PUTCHAR, ch, col, row);
117
}
117
}
118
 
118
 
119
/** Redraw the button showing state of a given console */
119
/** Redraw the button showing state of a given console */
120
static void redraw_state(size_t index)
120
static void redraw_state(size_t index)
121
{
121
{
122
    vp_switch(cstatus_vp[index]);
122
    vp_switch(cstatus_vp[index]);
123
   
123
   
124
    enum butstate state = console_state[index];
124
    enum butstate state = console_state[index];
125
   
125
   
126
    if (ic_pixmaps[state] != -1)
126
    if (ic_pixmaps[state] != -1)
127
        async_msg_2(fbphone, FB_VP_DRAW_PIXMAP, cstatus_vp[index],
127
        async_msg_2(fbphone, FB_VP_DRAW_PIXMAP, cstatus_vp[index],
128
            ic_pixmaps[state]);
128
            ic_pixmaps[state]);
129
   
129
   
130
    if ((state != CONS_DISCONNECTED) && (state != CONS_KERNEL)
130
    if ((state != CONS_DISCONNECTED) && (state != CONS_KERNEL)
131
        && (state != CONS_DISCONNECTED_SEL)) {
131
        && (state != CONS_DISCONNECTED_SEL)) {
132
       
132
       
133
        char data[5];
133
        char data[5];
134
        snprintf(data, 5, "%u", index + 1);
134
        snprintf(data, 5, "%u", index + 1);
135
       
135
       
136
        size_t i;
136
        size_t i;
137
        for (i = 0; data[i] != 0; i++)
137
        for (i = 0; data[i] != 0; i++)
138
            tran_putch(data[i], 2 + i, 1);
138
            tran_putch(data[i], 2 + i, 1);
139
    }
139
    }
140
}
140
}
141
 
141
 
142
/** Notification run on changing console (except kernel console) */
142
/** Notification run on changing console (except kernel console) */
143
void gcons_change_console(size_t index)
143
void gcons_change_console(size_t index)
144
{
144
{
145
    if (!use_gcons)
145
    if (!use_gcons)
146
        return;
146
        return;
147
   
147
   
148
    if (active_console == KERNEL_CONSOLE) {
148
    if (active_console == KERNEL_CONSOLE) {
149
        size_t i;
149
        size_t i;
150
       
150
       
151
        for (i = 0; i < CONSOLE_COUNT; i++)
151
        for (i = 0; i < CONSOLE_COUNT; i++)
152
            redraw_state(i);
152
            redraw_state(i);
153
       
153
       
154
        if (animation != -1)
154
        if (animation != -1)
155
            async_msg_1(fbphone, FB_ANIM_START, animation);
155
            async_msg_1(fbphone, FB_ANIM_START, animation);
156
    } else {
156
    } else {
157
        if (console_state[active_console] == CONS_DISCONNECTED_SEL)
157
        if (console_state[active_console] == CONS_DISCONNECTED_SEL)
158
            console_state[active_console] = CONS_DISCONNECTED;
158
            console_state[active_console] = CONS_DISCONNECTED;
159
        else
159
        else
160
            console_state[active_console] = CONS_IDLE;
160
            console_state[active_console] = CONS_IDLE;
161
       
161
       
162
        redraw_state(active_console);
162
        redraw_state(active_console);
163
    }
163
    }
164
   
164
   
165
    active_console = index;
165
    active_console = index;
166
   
166
   
167
    if ((console_state[index] == CONS_DISCONNECTED)
167
    if ((console_state[index] == CONS_DISCONNECTED)
168
        || (console_state[index] == CONS_DISCONNECTED_SEL))
168
        || (console_state[index] == CONS_DISCONNECTED_SEL))
169
        console_state[index] = CONS_DISCONNECTED_SEL;
169
        console_state[index] = CONS_DISCONNECTED_SEL;
170
    else
170
    else
171
        console_state[index] = CONS_SELECTED;
171
        console_state[index] = CONS_SELECTED;
172
   
172
   
173
    redraw_state(index);
173
    redraw_state(index);
174
    vp_switch(console_vp);
174
    vp_switch(console_vp);
175
}
175
}
176
 
176
 
177
/** Notification function that gets called on new output to virtual console */
177
/** Notification function that gets called on new output to virtual console */
178
void gcons_notify_char(size_t index)
178
void gcons_notify_char(size_t index)
179
{
179
{
180
    if (!use_gcons)
180
    if (!use_gcons)
181
        return;
181
        return;
182
   
182
   
183
    if ((index == active_console)
183
    if ((index == active_console)
184
        || (console_state[index] == CONS_HAS_DATA))
184
        || (console_state[index] == CONS_HAS_DATA))
185
        return;
185
        return;
186
   
186
   
187
    console_state[index] = CONS_HAS_DATA;
187
    console_state[index] = CONS_HAS_DATA;
188
   
188
   
189
    if (active_console == KERNEL_CONSOLE)
189
    if (active_console == KERNEL_CONSOLE)
190
        return;
190
        return;
191
   
191
   
192
    redraw_state(index);
192
    redraw_state(index);
193
    vp_switch(console_vp);
193
    vp_switch(console_vp);
194
}
194
}
195
 
195
 
196
/** Notification function called on service disconnect from console */
196
/** Notification function called on service disconnect from console */
197
void gcons_notify_disconnect(size_t index)
197
void gcons_notify_disconnect(size_t index)
198
{
198
{
199
    if (!use_gcons)
199
    if (!use_gcons)
200
        return;
200
        return;
201
   
201
   
202
    if (index == active_console)
202
    if (index == active_console)
203
        console_state[index] = CONS_DISCONNECTED_SEL;
203
        console_state[index] = CONS_DISCONNECTED_SEL;
204
    else
204
    else
205
        console_state[index] = CONS_DISCONNECTED;
205
        console_state[index] = CONS_DISCONNECTED;
206
   
206
   
207
    if (active_console == KERNEL_CONSOLE)
207
    if (active_console == KERNEL_CONSOLE)
208
        return;
208
        return;
209
   
209
   
210
    redraw_state(index);
210
    redraw_state(index);
211
    vp_switch(console_vp);
211
    vp_switch(console_vp);
212
}
212
}
213
 
213
 
214
/** Notification function called on console connect */
214
/** Notification function called on console connect */
215
void gcons_notify_connect(size_t index)
215
void gcons_notify_connect(size_t index)
216
{
216
{
217
    if (!use_gcons)
217
    if (!use_gcons)
218
        return;
218
        return;
219
   
219
   
220
    if (index == active_console)
220
    if (index == active_console)
221
        console_state[index] = CONS_SELECTED;
221
        console_state[index] = CONS_SELECTED;
222
    else
222
    else
223
        console_state[index] = CONS_IDLE;
223
        console_state[index] = CONS_IDLE;
224
   
224
   
225
    if (active_console == KERNEL_CONSOLE)
225
    if (active_console == KERNEL_CONSOLE)
226
        return;
226
        return;
227
   
227
   
228
    redraw_state(index);
228
    redraw_state(index);
229
    vp_switch(console_vp);
229
    vp_switch(console_vp);
230
}
230
}
231
 
231
 
232
/** Change to kernel console */
232
/** Change to kernel console */
233
void gcons_in_kernel(void)
233
void gcons_in_kernel(void)
234
{
234
{
235
    if (animation != -1)
235
    if (animation != -1)
236
        async_msg_1(fbphone, FB_ANIM_STOP, animation);
236
        async_msg_1(fbphone, FB_ANIM_STOP, animation);
237
   
237
   
238
    active_console = KERNEL_CONSOLE;
238
    active_console = KERNEL_CONSOLE;
239
    vp_switch(0);
239
    vp_switch(0);
240
}
240
}
241
 
241
 
242
/** Return x, where left <= x <= right && |a-x| == min(|a-x|) is smallest */
242
/** Return x, where left <= x <= right && |a-x| == min(|a-x|) is smallest */
243
static inline int limit(size_t a, size_t left, size_t right)
243
static inline int limit(size_t a, size_t left, size_t right)
244
{
244
{
245
    if (a < left)
245
    if (a < left)
246
        a = left;
246
        a = left;
247
   
247
   
248
    if (a >= right)
248
    if (a >= right)
249
        a = right - 1;
249
        a = right - 1;
250
   
250
   
251
    return a;
251
    return a;
252
}
252
}
253
 
253
 
254
/** Handle mouse move
254
/** Handle mouse move
255
 *
255
 *
256
 * @param dx Delta X of mouse move
256
 * @param dx Delta X of mouse move
257
 * @param dy Delta Y of mouse move
257
 * @param dy Delta Y of mouse move
258
 */
258
 */
259
void gcons_mouse_move(ssize_t dx, ssize_t dy)
259
void gcons_mouse_move(ssize_t dx, ssize_t dy)
260
{
260
{
261
    mouse_x = limit(mouse_x + dx, 0, xres);
261
    mouse_x = limit(mouse_x + dx, 0, xres);
262
    mouse_y = limit(mouse_y + dy, 0, yres);
262
    mouse_y = limit(mouse_y + dy, 0, yres);
263
   
263
   
264
    async_msg_2(fbphone, FB_POINTER_MOVE, mouse_x, mouse_y);
264
    async_msg_2(fbphone, FB_POINTER_MOVE, mouse_x, mouse_y);
265
}
265
}
266
 
266
 
267
static int gcons_find_conbut(int x, int y)
267
static int gcons_find_conbut(int x, int y)
268
{
268
{
269
    int status_start = STATUS_START + (xres - 800) / 2;
269
    int status_start = STATUS_START + (xres - 800) / 2;
270
   
270
   
271
    if ((y < STATUS_TOP) || (y >= STATUS_TOP + STATUS_HEIGHT))
271
    if ((y < STATUS_TOP) || (y >= STATUS_TOP + STATUS_HEIGHT))
272
        return -1;
272
        return -1;
273
   
273
   
274
    if (x < status_start)
274
    if (x < status_start)
275
        return -1;
275
        return -1;
276
   
276
   
277
    if (x >= status_start + (STATUS_WIDTH + STATUS_SPACE) * CONSOLE_COUNT)
277
    if (x >= status_start + (STATUS_WIDTH + STATUS_SPACE) * CONSOLE_COUNT)
278
        return -1;
278
        return -1;
279
    if (((x - status_start) % (STATUS_WIDTH + STATUS_SPACE)) < STATUS_SPACE)
279
    if (((x - status_start) % (STATUS_WIDTH + STATUS_SPACE)) < STATUS_SPACE)
280
        return -1;
280
        return -1;
281
   
281
   
282
    return (x - status_start) / (STATUS_WIDTH + STATUS_SPACE);
282
    return (x - status_start) / (STATUS_WIDTH + STATUS_SPACE);
283
}
283
}
284
 
284
 
285
/** Handle mouse click
285
/** Handle mouse click
286
 *
286
 *
287
 * @param state New state (true - pressed, false - depressed)
287
 * @param state New state (true - pressed, false - depressed)
288
 */
288
 */
289
int gcons_mouse_btn(bool state)
289
int gcons_mouse_btn(bool state)
290
{
290
{
291
    int conbut;
291
    int conbut;
292
   
292
   
293
    if (state) {
293
    if (state) {
294
        conbut = gcons_find_conbut(mouse_x, mouse_y);
294
        conbut = gcons_find_conbut(mouse_x, mouse_y);
295
        if (conbut != -1) {
295
        if (conbut != -1) {
296
            btn_pressed = true;
296
            btn_pressed = true;
297
            btn_x = mouse_x;
297
            btn_x = mouse_x;
298
            btn_y = mouse_y;
298
            btn_y = mouse_y;
299
        }
299
        }
300
        return -1;
300
        return -1;
301
    }
301
    }
302
   
302
   
303
    if ((!state) && (!btn_pressed))
303
    if ((!state) && (!btn_pressed))
304
        return -1;
304
        return -1;
305
   
305
   
306
    btn_pressed = false;
306
    btn_pressed = false;
307
   
307
   
308
    conbut = gcons_find_conbut(mouse_x, mouse_y);
308
    conbut = gcons_find_conbut(mouse_x, mouse_y);
309
    if (conbut == gcons_find_conbut(btn_x, btn_y))
309
    if (conbut == gcons_find_conbut(btn_x, btn_y))
310
        return conbut;
310
        return conbut;
311
   
311
   
312
    return -1;
312
    return -1;
313
}
313
}
314
 
314
 
315
 
315
 
316
/** Draw a PPM pixmap to framebuffer
316
/** Draw a PPM pixmap to framebuffer
317
 *
317
 *
318
 * @param logo Pointer to PPM data
318
 * @param logo Pointer to PPM data
319
 * @param size Size of PPM data
319
 * @param size Size of PPM data
320
 * @param x Coordinate of upper left corner
320
 * @param x Coordinate of upper left corner
321
 * @param y Coordinate of upper left corner
321
 * @param y Coordinate of upper left corner
322
 */
322
 */
323
static void draw_pixmap(char *logo, size_t size, int x, int y)
323
static void draw_pixmap(char *logo, size_t size, int x, int y)
324
{
324
{
325
    char *shm;
325
    char *shm;
326
    int rc;
326
    int rc;
327
   
327
   
328
    /* Create area */
328
    /* Create area */
329
    shm = mmap(NULL, size, PROTO_READ | PROTO_WRITE, MAP_SHARED |
329
    shm = mmap(NULL, size, PROTO_READ | PROTO_WRITE, MAP_SHARED |
330
        MAP_ANONYMOUS, 0, 0);
330
        MAP_ANONYMOUS, 0, 0);
331
    if (shm == MAP_FAILED)
331
    if (shm == MAP_FAILED)
332
        return;
332
        return;
333
   
333
   
334
    memcpy(shm, logo, size);
334
    memcpy(shm, logo, size);
335
   
335
   
336
    /* Send area */
336
    /* Send area */
337
    rc = async_req_1_0(fbphone, FB_PREPARE_SHM, (ipcarg_t) shm);
337
    rc = async_req_1_0(fbphone, FB_PREPARE_SHM, (ipcarg_t) shm);
338
    if (rc)
338
    if (rc)
339
        goto exit;
339
        goto exit;
340
   
340
   
341
    rc = ipc_share_out_start(fbphone, shm, PROTO_READ);
341
    rc = ipc_share_out_start(fbphone, shm, PROTO_READ);
342
    if (rc)
342
    if (rc)
343
        goto drop;
343
        goto drop;
344
   
344
   
345
    /* Draw logo */
345
    /* Draw logo */
346
    async_msg_2(fbphone, FB_DRAW_PPM, x, y);
346
    async_msg_2(fbphone, FB_DRAW_PPM, x, y);
347
   
347
   
348
drop:
348
drop:
349
    /* Drop area */
349
    /* Drop area */
350
    async_msg_0(fbphone, FB_DROP_SHM);
350
    async_msg_0(fbphone, FB_DROP_SHM);
351
   
351
   
352
exit:
352
exit:
353
    /* Remove area */
353
    /* Remove area */
354
    munmap(shm, size);
354
    munmap(shm, size);
355
}
355
}
356
 
356
 
357
extern char _binary_gfx_helenos_ppm_start[0];
357
extern char _binary_gfx_helenos_ppm_start[0];
358
extern int _binary_gfx_helenos_ppm_size;
358
extern int _binary_gfx_helenos_ppm_size;
359
extern char _binary_gfx_nameic_ppm_start[0];
359
extern char _binary_gfx_nameic_ppm_start[0];
360
extern int _binary_gfx_nameic_ppm_size;
360
extern int _binary_gfx_nameic_ppm_size;
361
 
361
 
362
/** Redraws console graphics */
362
/** Redraws console graphics */
363
void gcons_redraw_console(void)
363
void gcons_redraw_console(void)
364
{
364
{
365
    int i;
365
    int i;
366
   
366
   
367
    if (!use_gcons)
367
    if (!use_gcons)
368
        return;
368
        return;
369
   
369
   
370
    vp_switch(0);
370
    vp_switch(0);
371
    set_rgb_color(MAIN_COLOR, MAIN_COLOR);
371
    set_rgb_color(MAIN_COLOR, MAIN_COLOR);
372
    clear();
372
    clear();
373
    draw_pixmap(_binary_gfx_helenos_ppm_start,
373
    draw_pixmap(_binary_gfx_helenos_ppm_start,
374
        (size_t) &_binary_gfx_helenos_ppm_size, xres - 66, 2);
374
        (size_t) &_binary_gfx_helenos_ppm_size, xres - 66, 2);
375
    draw_pixmap(_binary_gfx_nameic_ppm_start,
375
    draw_pixmap(_binary_gfx_nameic_ppm_start,
376
        (size_t) &_binary_gfx_nameic_ppm_size, 5, 17);
376
        (size_t) &_binary_gfx_nameic_ppm_size, 5, 17);
377
   
377
   
378
    for (i = 0; i < CONSOLE_COUNT; i++)
378
    for (i = 0; i < CONSOLE_COUNT; i++)
379
        redraw_state(i);
379
        redraw_state(i);
380
   
380
   
381
    vp_switch(console_vp);
381
    vp_switch(console_vp);
382
}
382
}
383
 
383
 
384
/** Creates a pixmap on framebuffer
384
/** Creates a pixmap on framebuffer
385
 *
385
 *
386
 * @param data PPM data
386
 * @param data PPM data
387
 * @param size PPM data size
387
 * @param size PPM data size
388
 *
388
 *
389
 * @return Pixmap identification
389
 * @return Pixmap identification
390
 *
390
 *
391
 */
391
 */
392
static int make_pixmap(char *data, size_t size)
392
static int make_pixmap(char *data, size_t size)
393
{
393
{
394
    char *shm;
394
    char *shm;
395
    int rc;
395
    int rc;
396
    int pxid = -1;
396
    int pxid = -1;
397
   
397
   
398
    /* Create area */
398
    /* Create area */
399
    shm = mmap(NULL, size, PROTO_READ | PROTO_WRITE, MAP_SHARED |
399
    shm = mmap(NULL, size, PROTO_READ | PROTO_WRITE, MAP_SHARED |
400
        MAP_ANONYMOUS, 0, 0);
400
        MAP_ANONYMOUS, 0, 0);
401
    if (shm == MAP_FAILED)
401
    if (shm == MAP_FAILED)
402
        return -1;
402
        return -1;
403
   
403
   
404
    memcpy(shm, data, size);
404
    memcpy(shm, data, size);
405
   
405
   
406
    /* Send area */
406
    /* Send area */
407
    rc = async_req_1_0(fbphone, FB_PREPARE_SHM, (ipcarg_t) shm);
407
    rc = async_req_1_0(fbphone, FB_PREPARE_SHM, (ipcarg_t) shm);
408
    if (rc)
408
    if (rc)
409
        goto exit;
409
        goto exit;
410
   
410
   
411
    rc = ipc_share_out_start(fbphone, shm, PROTO_READ);
411
    rc = ipc_share_out_start(fbphone, shm, PROTO_READ);
412
    if (rc)
412
    if (rc)
413
        goto drop;
413
        goto drop;
414
   
414
   
415
    /* Obtain pixmap */
415
    /* Obtain pixmap */
416
    rc = async_req_0_0(fbphone, FB_SHM2PIXMAP);
416
    rc = async_req_0_0(fbphone, FB_SHM2PIXMAP);
417
    if (rc < 0)
417
    if (rc < 0)
418
        goto drop;
418
        goto drop;
419
   
419
   
420
    pxid = rc;
420
    pxid = rc;
421
   
421
   
422
drop:
422
drop:
423
    /* Drop area */
423
    /* Drop area */
424
    async_msg_0(fbphone, FB_DROP_SHM);
424
    async_msg_0(fbphone, FB_DROP_SHM);
425
   
425
   
426
exit:
426
exit:
427
    /* Remove area */
427
    /* Remove area */
428
    munmap(shm, size);
428
    munmap(shm, size);
429
   
429
   
430
    return pxid;
430
    return pxid;
431
}
431
}
432
 
432
 
433
extern char _binary_gfx_anim_1_ppm_start[0];
433
extern char _binary_gfx_anim_1_ppm_start[0];
434
extern int _binary_gfx_anim_1_ppm_size;
434
extern int _binary_gfx_anim_1_ppm_size;
435
extern char _binary_gfx_anim_2_ppm_start[0];
435
extern char _binary_gfx_anim_2_ppm_start[0];
436
extern int _binary_gfx_anim_2_ppm_size;
436
extern int _binary_gfx_anim_2_ppm_size;
437
extern char _binary_gfx_anim_3_ppm_start[0];
437
extern char _binary_gfx_anim_3_ppm_start[0];
438
extern int _binary_gfx_anim_3_ppm_size;
438
extern int _binary_gfx_anim_3_ppm_size;
439
extern char _binary_gfx_anim_4_ppm_start[0];
439
extern char _binary_gfx_anim_4_ppm_start[0];
440
extern int _binary_gfx_anim_4_ppm_size;
440
extern int _binary_gfx_anim_4_ppm_size;
441
 
441
 
442
static void make_anim(void)
442
static void make_anim(void)
443
{
443
{
444
    int an = async_req_1_0(fbphone, FB_ANIM_CREATE, cstatus_vp[KERNEL_CONSOLE]);
444
    int an = async_req_1_0(fbphone, FB_ANIM_CREATE, cstatus_vp[KERNEL_CONSOLE]);
445
    if (an < 0)
445
    if (an < 0)
446
        return;
446
        return;
447
   
447
   
448
    int pm = make_pixmap(_binary_gfx_anim_1_ppm_start,
448
    int pm = make_pixmap(_binary_gfx_anim_1_ppm_start,
449
        (int) &_binary_gfx_anim_1_ppm_size);
449
        (int) &_binary_gfx_anim_1_ppm_size);
450
    async_msg_2(fbphone, FB_ANIM_ADDPIXMAP, an, pm);
450
    async_msg_2(fbphone, FB_ANIM_ADDPIXMAP, an, pm);
451
   
451
   
452
    pm = make_pixmap(_binary_gfx_anim_2_ppm_start,
452
    pm = make_pixmap(_binary_gfx_anim_2_ppm_start,
453
        (int) &_binary_gfx_anim_2_ppm_size);
453
        (int) &_binary_gfx_anim_2_ppm_size);
454
    async_msg_2(fbphone, FB_ANIM_ADDPIXMAP, an, pm);
454
    async_msg_2(fbphone, FB_ANIM_ADDPIXMAP, an, pm);
455
   
455
   
456
    pm = make_pixmap(_binary_gfx_anim_3_ppm_start,
456
    pm = make_pixmap(_binary_gfx_anim_3_ppm_start,
457
        (int) &_binary_gfx_anim_3_ppm_size);
457
        (int) &_binary_gfx_anim_3_ppm_size);
458
    async_msg_2(fbphone, FB_ANIM_ADDPIXMAP, an, pm);
458
    async_msg_2(fbphone, FB_ANIM_ADDPIXMAP, an, pm);
459
   
459
   
460
    pm = make_pixmap(_binary_gfx_anim_4_ppm_start,
460
    pm = make_pixmap(_binary_gfx_anim_4_ppm_start,
461
        (int) &_binary_gfx_anim_4_ppm_size);
461
        (int) &_binary_gfx_anim_4_ppm_size);
462
    async_msg_2(fbphone, FB_ANIM_ADDPIXMAP, an, pm);
462
    async_msg_2(fbphone, FB_ANIM_ADDPIXMAP, an, pm);
463
   
463
   
464
    async_msg_1(fbphone, FB_ANIM_START, an);
464
    async_msg_1(fbphone, FB_ANIM_START, an);
465
   
465
   
466
    animation = an;
466
    animation = an;
467
}
467
}
468
 
468
 
469
extern char _binary_gfx_cons_selected_ppm_start[0];
469
extern char _binary_gfx_cons_selected_ppm_start[0];
470
extern int _binary_gfx_cons_selected_ppm_size;
470
extern int _binary_gfx_cons_selected_ppm_size;
471
extern char _binary_gfx_cons_idle_ppm_start[0];
471
extern char _binary_gfx_cons_idle_ppm_start[0];
472
extern int _binary_gfx_cons_idle_ppm_size;
472
extern int _binary_gfx_cons_idle_ppm_size;
473
extern char _binary_gfx_cons_has_data_ppm_start[0];
473
extern char _binary_gfx_cons_has_data_ppm_start[0];
474
extern int _binary_gfx_cons_has_data_ppm_size;
474
extern int _binary_gfx_cons_has_data_ppm_size;
475
extern char _binary_gfx_cons_kernel_ppm_start[0];
475
extern char _binary_gfx_cons_kernel_ppm_start[0];
476
extern int _binary_gfx_cons_kernel_ppm_size;
476
extern int _binary_gfx_cons_kernel_ppm_size;
477
 
477
 
478
/** Initialize nice graphical console environment */
478
/** Initialize nice graphical console environment */
479
void gcons_init(int phone)
479
void gcons_init(int phone)
480
{
480
{
481
    fbphone = phone;
481
    fbphone = phone;
482
   
482
   
483
    int rc = async_req_0_2(phone, FB_GET_RESOLUTION, &xres, &yres);
483
    int rc = async_req_0_2(phone, FB_GET_RESOLUTION, &xres, &yres);
484
    if (rc)
484
    if (rc)
485
        return;
485
        return;
486
   
486
   
487
    if ((xres < 800) || (yres < 600))
487
    if ((xres < 800) || (yres < 600))
488
        return;
488
        return;
489
   
489
   
490
    /* Create console viewport */
490
    /* Create console viewport */
491
   
491
   
492
    /* Align width & height to character size */
492
    /* Align width & height to character size */
493
    console_vp = vp_create(CONSOLE_MARGIN, CONSOLE_TOP,
493
    console_vp = vp_create(CONSOLE_MARGIN, CONSOLE_TOP,
494
        ALIGN_DOWN(xres - 2 * CONSOLE_MARGIN, 8),
494
        ALIGN_DOWN(xres - 2 * CONSOLE_MARGIN, 8),
495
        ALIGN_DOWN(yres - (CONSOLE_TOP + CONSOLE_MARGIN), 16));
495
        ALIGN_DOWN(yres - (CONSOLE_TOP + CONSOLE_MARGIN), 16));
496
   
496
   
497
    if (console_vp < 0)
497
    if (console_vp < 0)
498
        return;
498
        return;
499
   
499
   
500
    /* Create status buttons */
500
    /* Create status buttons */
501
    size_t status_start = STATUS_START + (xres - 800) / 2;
501
    size_t status_start = STATUS_START + (xres - 800) / 2;
502
    size_t i;
502
    size_t i;
503
    for (i = 0; i < CONSOLE_COUNT; i++) {
503
    for (i = 0; i < CONSOLE_COUNT; i++) {
504
        cstatus_vp[i] = vp_create(status_start + CONSOLE_MARGIN +
504
        cstatus_vp[i] = vp_create(status_start + CONSOLE_MARGIN +
505
            i * (STATUS_WIDTH + STATUS_SPACE), STATUS_TOP,
505
            i * (STATUS_WIDTH + STATUS_SPACE), STATUS_TOP,
506
            STATUS_WIDTH, STATUS_HEIGHT);
506
            STATUS_WIDTH, STATUS_HEIGHT);
507
       
507
       
508
        if (cstatus_vp[i] < 0)
508
        if (cstatus_vp[i] < 0)
509
            return;
509
            return;
510
       
510
       
511
        vp_switch(cstatus_vp[i]);
511
        vp_switch(cstatus_vp[i]);
512
        set_rgb_color(0x202020, 0xffffff);
512
        set_rgb_color(0x202020, 0xffffff);
513
    }
513
    }
514
   
514
   
515
    /* Initialize icons */
515
    /* Initialize icons */
516
    ic_pixmaps[CONS_SELECTED] =
516
    ic_pixmaps[CONS_SELECTED] =
517
        make_pixmap(_binary_gfx_cons_selected_ppm_start,
517
        make_pixmap(_binary_gfx_cons_selected_ppm_start,
518
        (size_t) &_binary_gfx_cons_selected_ppm_size);
518
        (size_t) &_binary_gfx_cons_selected_ppm_size);
519
    ic_pixmaps[CONS_IDLE] =
519
    ic_pixmaps[CONS_IDLE] =
520
        make_pixmap(_binary_gfx_cons_idle_ppm_start,
520
        make_pixmap(_binary_gfx_cons_idle_ppm_start,
521
        (size_t) &_binary_gfx_cons_idle_ppm_size);
521
        (size_t) &_binary_gfx_cons_idle_ppm_size);
522
    ic_pixmaps[CONS_HAS_DATA] =
522
    ic_pixmaps[CONS_HAS_DATA] =
523
        make_pixmap(_binary_gfx_cons_has_data_ppm_start,
523
        make_pixmap(_binary_gfx_cons_has_data_ppm_start,
524
        (size_t) &_binary_gfx_cons_has_data_ppm_size);
524
        (size_t) &_binary_gfx_cons_has_data_ppm_size);
525
    ic_pixmaps[CONS_DISCONNECTED] =
525
    ic_pixmaps[CONS_DISCONNECTED] =
526
        make_pixmap(_binary_gfx_cons_idle_ppm_start,
526
        make_pixmap(_binary_gfx_cons_idle_ppm_start,
527
        (size_t) &_binary_gfx_cons_idle_ppm_size);
527
        (size_t) &_binary_gfx_cons_idle_ppm_size);
528
    ic_pixmaps[CONS_KERNEL] =
528
    ic_pixmaps[CONS_KERNEL] =
529
        make_pixmap(_binary_gfx_cons_kernel_ppm_start,
529
        make_pixmap(_binary_gfx_cons_kernel_ppm_start,
530
        (size_t) &_binary_gfx_cons_kernel_ppm_size);
530
        (size_t) &_binary_gfx_cons_kernel_ppm_size);
531
    ic_pixmaps[CONS_DISCONNECTED_SEL] = ic_pixmaps[CONS_SELECTED];
531
    ic_pixmaps[CONS_DISCONNECTED_SEL] = ic_pixmaps[CONS_SELECTED];
532
   
532
   
533
    make_anim();
533
    make_anim();
534
   
534
   
535
    use_gcons = true;
535
    use_gcons = true;
536
    console_state[0] = CONS_DISCONNECTED_SEL;
536
    console_state[0] = CONS_DISCONNECTED_SEL;
537
    console_state[KERNEL_CONSOLE] = CONS_KERNEL;
537
    console_state[KERNEL_CONSOLE] = CONS_KERNEL;
538
   
538
   
539
    gcons_redraw_console();
539
    vp_switch(console_vp);
540
}
540
}
541
 
541
 
542
/** @}
542
/** @}
543
 */
543
 */
544
 
544