Subversion Repositories HelenOS-historic

Rev

Rev 1547 | Rev 1555 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1547 Rev 1552
Line 67... Line 67...
67
    int client_phone;       /**< Phone to connected client. */
67
    int client_phone;       /**< Phone to connected client. */
68
    int used;           /**< 1 if this virtual console is connected to some client.*/
68
    int used;           /**< 1 if this virtual console is connected to some client.*/
69
    screenbuffer_t screenbuffer;    /**< Screenbuffer for saving screen contents and related settings. */
69
    screenbuffer_t screenbuffer;    /**< Screenbuffer for saving screen contents and related settings. */
70
} connection_t;
70
} connection_t;
71
 
71
 
72
connection_t connections[CONSOLE_COUNT];    /**< Array of data for virtual consoles */
72
static connection_t connections[CONSOLE_COUNT]; /**< Array of data for virtual consoles */
73
keyfield_t *interbuffer = NULL;         /**< Pointer to memory shared with framebufer used for faster virt. console switching */
73
static keyfield_t *interbuffer = NULL;          /**< Pointer to memory shared with framebufer used for faster virt. console switching */
-
 
74
 
-
 
75
static int kernel_pixmap = -1;      /**< Number of fb pixmap, where kernel console is stored */
74
 
76
 
75
 
77
 
76
/** Find unused virtual console.
78
/** Find unused virtual console.
77
 *
79
 *
78
 */
80
 */
Line 101... Line 103...
101
        ++i;
103
        ++i;
102
    }
104
    }
103
    return  CONSOLE_COUNT;
105
    return  CONSOLE_COUNT;
104
}
106
}
105
 
107
 
-
 
108
static void clrscr(void)
-
 
109
{
-
 
110
    nsend_call(fb_info.phone, FB_CLEAR, 0);
-
 
111
}
-
 
112
 
-
 
113
static void curs_visibility(int v)
-
 
114
{
-
 
115
    send_call(fb_info.phone, FB_CURSOR_VISIBILITY, v);
-
 
116
}
-
 
117
 
-
 
118
static void curs_goto(int row, int col)
-
 
119
{
-
 
120
    nsend_call_2(fb_info.phone, FB_CURSOR_GOTO, row, col);
-
 
121
   
-
 
122
}
-
 
123
 
-
 
124
static void set_style(style_t *style)
-
 
125
{
-
 
126
    nsend_call_2(fb_info.phone, FB_SET_STYLE, style->fg_color, style->bg_color);
-
 
127
}
-
 
128
 
-
 
129
static void set_style_col(int fgcolor, int bgcolor)
-
 
130
{
-
 
131
    nsend_call_2(fb_info.phone, FB_SET_STYLE, fgcolor, bgcolor);
-
 
132
}
-
 
133
 
-
 
134
static void prtchr(char c, int row, int col)
-
 
135
{
-
 
136
    nsend_call_3(fb_info.phone, FB_PUTCHAR, c, row, col);
-
 
137
   
-
 
138
}
-
 
139
 
106
/** Check key and process special keys.
140
/** Check key and process special keys.
107
 *
141
 *
108
 * */
142
 * */
109
static void write_char(int console, char key)
143
static void write_char(int console, char key)
110
{
144
{
Line 125... Line 159...
125
            if (scr->position_x == 0)
159
            if (scr->position_x == 0)
126
                break;
160
                break;
127
 
161
 
128
            scr->position_x--;
162
            scr->position_x--;
129
 
163
 
130
            if (console == active_console) {
164
            if (console == active_console)
131
                nsend_call_3(fb_info.phone, FB_PUTCHAR, ' ', scr->position_y, scr->position_x);
165
                prtchr(' ', scr->position_y, scr->position_x);
132
            }
-
 
133
   
166
   
134
            screenbuffer_putchar(scr, ' ');
167
            screenbuffer_putchar(scr, ' ');
135
           
168
           
136
            break;
169
            break;
137
        default:   
170
        default:   
138
            if (console == active_console) {
171
            if (console == active_console)
139
                nsend_call_3(fb_info.phone, FB_PUTCHAR, key, scr->position_y, scr->position_x);
172
                prtchr(key, scr->position_y, scr->position_x);
140
            }
-
 
141
   
173
   
142
            screenbuffer_putchar(scr, key);
174
            screenbuffer_putchar(scr, key);
143
            scr->position_x++;
175
            scr->position_x++;
144
    }
176
    }
145
   
177
   
Line 152... Line 184...
152
            nsend_call(fb_info.phone, FB_SCROLL, 1);
184
            nsend_call(fb_info.phone, FB_SCROLL, 1);
153
    }
185
    }
154
   
186
   
155
    scr->position_x = scr->position_x % scr->size_x;
187
    scr->position_x = scr->position_x % scr->size_x;
156
   
188
   
157
    if (console == active_console) 
189
    if (console == active_console)
-
 
190
        curs_goto(scr->position_y, scr->position_x);
-
 
191
   
-
 
192
}
-
 
193
 
-
 
194
/** Save current screen to pixmap, draw old pixmap
-
 
195
 *
-
 
196
 * @param oldpixmap Old pixmap
-
 
197
 * @return ID of pixmap of current screen
-
 
198
 */
-
 
199
static int switch_screens(int oldpixmap)
-
 
200
{
-
 
201
    int newpmap;
-
 
202
       
-
 
203
    /* Save screen */
-
 
204
    newpmap = sync_send(fb_info.phone, FB_VP2PIXMAP, 0, NULL);
-
 
205
    if (newpmap < 0)
-
 
206
        return -1;
-
 
207
 
-
 
208
    if (oldpixmap != -1) {
-
 
209
        /* Show old screen */
158
        send_call_2(fb_info.phone, FB_CURSOR_GOTO, scr->position_y, scr->position_x);
210
        nsend_call_2(fb_info.phone, FB_VP_DRAW_PIXMAP, 0, oldpixmap);
-
 
211
        /* Drop old pixmap */
-
 
212
        nsend_call(fb_info.phone, FB_DROP_PIXMAP, oldpixmap);
-
 
213
    }
159
   
214
   
-
 
215
    return newpmap;
160
}
216
}
161
 
217
 
-
 
218
/** Switch to new console */
-
 
219
static void change_console(int newcons)
-
 
220
{
-
 
221
    connection_t *conn;
-
 
222
    static int console_pixmap = -1;
-
 
223
    int i, j;
-
 
224
    char c;
-
 
225
 
-
 
226
    if (newcons == active_console)
-
 
227
        return;
-
 
228
 
-
 
229
    if (newcons == -1) {
-
 
230
        if (active_console == -1)
-
 
231
            return;
-
 
232
        active_console = -1;
-
 
233
        curs_visibility(0);
-
 
234
 
-
 
235
        if (kernel_pixmap == -1) {
-
 
236
            /* store/restore unsupported */
-
 
237
            set_style_col(DEFAULT_FOREGROUND, DEFAULT_BACKGROUND);
-
 
238
            clrscr();
-
 
239
        } else {
-
 
240
            gcons_in_kernel();
-
 
241
            console_pixmap = switch_screens(kernel_pixmap);
-
 
242
            kernel_pixmap = -1;
-
 
243
        }
-
 
244
 
-
 
245
        __SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE);
-
 
246
        return;
-
 
247
    }
-
 
248
   
-
 
249
    if (console_pixmap != -1) {
-
 
250
        kernel_pixmap = switch_screens(console_pixmap);
-
 
251
        console_pixmap = -1;
-
 
252
    }
-
 
253
   
-
 
254
    active_console = newcons;
-
 
255
    gcons_change_console(newcons);
-
 
256
    conn = &connections[active_console];
-
 
257
 
-
 
258
    curs_visibility(0);
-
 
259
    if (interbuffer) {
-
 
260
        for (i = 0; i < conn->screenbuffer.size_x; i++)
-
 
261
            for (j = 0; j < conn->screenbuffer.size_y; j++)
-
 
262
                interbuffer[i + j*conn->screenbuffer.size_x] = *get_field_at(&(conn->screenbuffer),i, j);
-
 
263
       
-
 
264
        sync_send_2(fb_info.phone, FB_DRAW_TEXT_DATA, 0, 0, NULL, NULL);       
-
 
265
    } else {
-
 
266
        clrscr();
-
 
267
       
-
 
268
        for (i = 0; i < conn->screenbuffer.size_x; i++)
-
 
269
            for (j = 0; j < conn->screenbuffer.size_y; j++) {
-
 
270
                c = get_field_at(&(conn->screenbuffer),i, j)->character;
-
 
271
                if (c && c != ' ')
-
 
272
                    prtchr(c, j, i);
-
 
273
            }
-
 
274
       
-
 
275
    }
-
 
276
    curs_goto(conn->screenbuffer.position_y, conn->screenbuffer.position_x);
-
 
277
    set_style(&conn->screenbuffer.style);
-
 
278
    curs_visibility(1);
-
 
279
}
162
 
280
 
163
/** Handler for keyboard */
281
/** Handler for keyboard */
164
static void keyboard_events(ipc_callid_t iid, ipc_call_t *icall)
282
static void keyboard_events(ipc_callid_t iid, ipc_call_t *icall)
165
{
283
{
166
    ipc_callid_t callid;
284
    ipc_callid_t callid;
167
    ipc_call_t call;
285
    ipc_call_t call;
168
    int retval;
286
    int retval;
169
    int i, j;
-
 
170
    char c,d;
287
    char c;
171
    connection_t *conn;
288
    connection_t *conn;
172
   
289
   
173
    /* Ignore parameters, the connection is alread opened */
290
    /* Ignore parameters, the connection is alread opened */
174
    while (1) {
291
    while (1) {
175
        callid = async_get_call(&call);
292
        callid = async_get_call(&call);
Line 186... Line 303...
186
            /* switch to another virtual console */
303
            /* switch to another virtual console */
187
           
304
           
188
            conn = &connections[active_console];
305
            conn = &connections[active_console];
189
//          if ((c >= KBD_KEY_F1) && (c < KBD_KEY_F1 + CONSOLE_COUNT)) {
306
//          if ((c >= KBD_KEY_F1) && (c < KBD_KEY_F1 + CONSOLE_COUNT)) {
190
            if ((c >= '0') && (c < '0' + CONSOLE_COUNT)) {
307
            if ((c >= '0') && (c < '0' + CONSOLE_COUNT)) {
191
                if (c == '0') {
308
                if (c == '0')
192
                    /* switch to kernel console*/
-
 
193
                    nsend_call(fb_info.phone, FB_CURSOR_VISIBILITY, 0);
-
 
194
                    nsend_call_2(fb_info.phone, FB_SET_STYLE, DEFAULT_FOREGROUND_COLOR, DEFAULT_BACKGROUND_COLOR);
-
 
195
                    nsend_call(fb_info.phone, FB_CLEAR, 0);
-
 
196
                    /* FIXME: restore kernel console */
-
 
197
                     __SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE);
-
 
198
                     break;
-
 
199
                     
-
 
200
                } else {
-
 
201
                    c = c - '1';
-
 
202
                    if (c == active_console)
-
 
203
                        break;
-
 
204
                    active_console = c;
-
 
205
                    gcons_change_console(c);
309
                    change_console(-1);
206
               
-
 
207
                }
-
 
208
               
-
 
209
                conn = &connections[active_console];
-
 
210
 
-
 
211
                nsend_call(fb_info.phone, FB_CURSOR_VISIBILITY, 0);
-
 
212
       
-
 
213
                if (interbuffer) {
-
 
214
                    for (i = 0; i < conn->screenbuffer.size_x; i++)
-
 
215
                        for (j = 0; j < conn->screenbuffer.size_y; j++)
-
 
216
                            interbuffer[i + j*conn->screenbuffer.size_x] = *get_field_at(&(conn->screenbuffer),i, j);
-
 
217
                           
-
 
218
                    sync_send_2(fb_info.phone, FB_DRAW_TEXT_DATA, 0, 0, NULL, NULL);       
-
 
219
                } else {
310
                else
220
                    nsend_call(fb_info.phone, FB_CLEAR, 0);
-
 
221
               
-
 
222
                   
-
 
223
                    for (i = 0; i < conn->screenbuffer.size_x; i++)
-
 
224
                        for (j = 0; j < conn->screenbuffer.size_y; j++) {
-
 
225
                            d = get_field_at(&(conn->screenbuffer),i, j)->character;
-
 
226
                            if (d && d != ' ')
311
                    change_console(c - '1');
227
                                nsend_call_3(fb_info.phone, FB_PUTCHAR, d, j, i);
-
 
228
                        }
-
 
229
 
-
 
230
                }
-
 
231
                nsend_call_2(fb_info.phone, FB_CURSOR_GOTO, conn->screenbuffer.position_y, conn->screenbuffer.position_x);
-
 
232
                nsend_call_2(fb_info.phone, FB_SET_STYLE, conn->screenbuffer.style.fg_color, \
-
 
233
                        conn->screenbuffer.style.bg_color);
-
 
234
                send_call(fb_info.phone, FB_CURSOR_VISIBILITY, 1);
-
 
235
 
-
 
236
                break;
312
                break;
237
            }
313
            }
238
           
314
           
239
            /* if client is awaiting key, send it */
315
            /* if client is awaiting key, send it */
240
            if (conn->keyrequest_counter > 0) {    
316
            if (conn->keyrequest_counter > 0) {    
Line 312... Line 388...
312
           
388
           
313
            arg1 = IPC_GET_ARG1(call);
389
            arg1 = IPC_GET_ARG1(call);
314
            arg2 = IPC_GET_ARG2(call);
390
            arg2 = IPC_GET_ARG2(call);
315
            screenbuffer_set_style(&(connections[consnum].screenbuffer),arg1, arg2);
391
            screenbuffer_set_style(&(connections[consnum].screenbuffer),arg1, arg2);
316
            if (consnum == active_console)
392
            if (consnum == active_console)
317
                nsend_call_2(fb_info.phone, FB_SET_STYLE, arg1, arg2);
393
                set_style_col(arg1, arg2);
318
               
394
               
319
            break;
395
            break;
320
        case CONSOLE_GETCHAR:
396
        case CONSOLE_GETCHAR:
321
            if (keybuffer_empty(&(connections[consnum].keybuffer))) {
397
            if (keybuffer_empty(&(connections[consnum].keybuffer))) {
322
                /* buffer is empty -> store request */
398
                /* buffer is empty -> store request */
Line 359... Line 435...
359
    /* Connect to framebuffer driver */
435
    /* Connect to framebuffer driver */
360
   
436
   
361
    while ((fb_info.phone = ipc_connect_me_to(PHONE_NS, SERVICE_VIDEO, 0)) < 0) {
437
    while ((fb_info.phone = ipc_connect_me_to(PHONE_NS, SERVICE_VIDEO, 0)) < 0) {
362
        usleep(10000);
438
        usleep(10000);
363
    }
439
    }
-
 
440
   
-
 
441
    /* Save old kernel screen */
-
 
442
    kernel_pixmap = switch_screens(-1);
364
 
443
 
365
    /* Initialize gcons */
444
    /* Initialize gcons */
366
    gcons_init(fb_info.phone);
445
    gcons_init(fb_info.phone);
367
    /* Synchronize, the gcons can have something in queue */
446
    /* Synchronize, the gcons can have something in queue */
368
    sync_send_2(fb_info.phone, FB_GET_CSIZE, 0, 0, NULL, NULL);
447
    sync_send_2(fb_info.phone, FB_GET_CSIZE, 0, 0, NULL, NULL);
369
 
448
 
370
   
449
   
371
    ipc_call_sync_2(fb_info.phone, FB_GET_CSIZE, 0, 0, &(fb_info.rows), &(fb_info.cols));
450
    ipc_call_sync_2(fb_info.phone, FB_GET_CSIZE, 0, 0, &(fb_info.rows), &(fb_info.cols));
372
    nsend_call_2(fb_info.phone, FB_SET_STYLE, DEFAULT_FOREGROUND_COLOR, DEFAULT_BACKGROUND_COLOR);
451
    set_style_col(DEFAULT_FOREGROUND, DEFAULT_BACKGROUND);
373
    nsend_call(fb_info.phone, FB_CLEAR, 0);
452
    clrscr();
374
   
453
   
375
    /* Init virtual consoles */
454
    /* Init virtual consoles */
376
    for (i = 0; i < CONSOLE_COUNT; i++) {
455
    for (i = 0; i < CONSOLE_COUNT; i++) {
377
        connections[i].used = 0;
456
        connections[i].used = 0;
378
        keybuffer_init(&(connections[i].keybuffer));
457
        keybuffer_init(&(connections[i].keybuffer));
Line 392... Line 471...
392
            munmap(interbuffer, sizeof(keyfield_t) * fb_info.cols * fb_info.rows);
471
            munmap(interbuffer, sizeof(keyfield_t) * fb_info.cols * fb_info.rows);
393
            interbuffer = NULL;
472
            interbuffer = NULL;
394
        }
473
        }
395
    }
474
    }
396
 
475
 
397
    /* FIXME: save kernel console screen */
-
 
398
   
-
 
399
    async_new_connection(phonehash, 0, NULL, keyboard_events);
476
    async_new_connection(phonehash, 0, NULL, keyboard_events);
400
   
477
   
401
    sync_send_2(fb_info.phone, FB_CURSOR_GOTO, 0, 0, NULL, NULL);
478
    sync_send_2(fb_info.phone, FB_CURSOR_GOTO, 0, 0, NULL, NULL);
402
    nsend_call(fb_info.phone, FB_CURSOR_VISIBILITY, 1);
479
    nsend_call(fb_info.phone, FB_CURSOR_VISIBILITY, 1);
403
 
480