Subversion Repositories HelenOS-historic

Rev

Rev 1547 | Rev 1555 | Go to most recent revision | Show entire file | Regard 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 153... Line 185...
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)
158
        send_call_2(fb_info.phone, FB_CURSOR_GOTO, scr->position_y, scr->position_x);
190
        curs_goto(scr->position_y, scr->position_x);
159
   
191
   
160
}
192
}
161
 
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;
162
 
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 */
-
 
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
    }
-
 
214
   
-
 
215
    return newpmap;
-
 
216
}
-
 
217
 
163
/** Handler for keyboard */
218
/** Switch to new console */
164
static void keyboard_events(ipc_callid_t iid, ipc_call_t *icall)
219
static void change_console(int newcons)
165
{
220
{
166
    ipc_callid_t callid;
-
 
167
    ipc_call_t call;
-
 
168
    int retval;
-
 
169
    int i, j;
-
 
170
    char c,d;
-
 
171
    connection_t *conn;
221
    connection_t *conn;
-
 
222
    static int console_pixmap = -1;
-
 
223
    int i, j;
-
 
224
    char c;
172
   
225
 
173
    /* Ignore parameters, the connection is alread opened */
-
 
174
    while (1) {
-
 
175
        callid = async_get_call(&call);
226
    if (newcons == active_console)
176
        switch (IPC_GET_METHOD(call)) {
-
 
177
        case IPC_M_PHONE_HUNGUP:
-
 
178
            ipc_answer_fast(callid,0,0,0);
-
 
179
            /* TODO: Handle hangup */
-
 
180
            return;
227
        return;
181
        case KBD_PUSHCHAR:
-
 
182
            /* got key from keyboard driver */
-
 
183
           
228
 
184
            retval = 0;
229
    if (newcons == -1) {
185
            c = IPC_GET_ARG1(call);
230
        if (active_console == -1)
186
            /* switch to another virtual console */
-
 
187
           
231
            return;
188
            conn = &connections[active_console];
232
        active_console = -1;
189
//          if ((c >= KBD_KEY_F1) && (c < KBD_KEY_F1 + CONSOLE_COUNT)) {
-
 
190
            if ((c >= '0') && (c < '0' + CONSOLE_COUNT)) {
-
 
191
                if (c == '0') {
233
        curs_visibility(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
                     
234
 
-
 
235
        if (kernel_pixmap == -1) {
-
 
236
            /* store/restore unsupported */
-
 
237
            set_style_col(DEFAULT_FOREGROUND, DEFAULT_BACKGROUND);
-
 
238
            clrscr();
200
                } else {
239
        } else {
201
                    c = c - '1';
240
            gcons_in_kernel();
202
                    if (c == active_console)
241
            console_pixmap = switch_screens(kernel_pixmap);
203
                        break;
-
 
204
                    active_console = c;
242
            kernel_pixmap = -1;
205
                    gcons_change_console(c);
243
        }
206
               
244
 
-
 
245
        __SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE);
-
 
246
        return;
207
                }
247
    }
208
               
248
   
-
 
249
    if (console_pixmap != -1) {
209
                conn = &connections[active_console];
250
        kernel_pixmap = switch_screens(console_pixmap);
-
 
251
        console_pixmap = -1;
-
 
252
    }
210
 
253
   
-
 
254
    active_console = newcons;
211
                nsend_call(fb_info.phone, FB_CURSOR_VISIBILITY, 0);
255
    gcons_change_console(newcons);
-
 
256
    conn = &connections[active_console];
212
       
257
 
-
 
258
    curs_visibility(0);
213
                if (interbuffer) {
259
    if (interbuffer) {
214
                    for (i = 0; i < conn->screenbuffer.size_x; i++)
260
        for (i = 0; i < conn->screenbuffer.size_x; i++)
215
                        for (j = 0; j < conn->screenbuffer.size_y; j++)
261
            for (j = 0; j < conn->screenbuffer.size_y; j++)
216
                            interbuffer[i + j*conn->screenbuffer.size_x] = *get_field_at(&(conn->screenbuffer),i, j);
262
                interbuffer[i + j*conn->screenbuffer.size_x] = *get_field_at(&(conn->screenbuffer),i, j);
217
                           
263
       
218
                    sync_send_2(fb_info.phone, FB_DRAW_TEXT_DATA, 0, 0, NULL, NULL);       
264
        sync_send_2(fb_info.phone, FB_DRAW_TEXT_DATA, 0, 0, NULL, NULL);       
219
                } else {
265
    } else {
220
                    nsend_call(fb_info.phone, FB_CLEAR, 0);
-
 
221
               
266
        clrscr();
222
                   
267
       
223
                    for (i = 0; i < conn->screenbuffer.size_x; i++)
268
        for (i = 0; i < conn->screenbuffer.size_x; i++)
224
                        for (j = 0; j < conn->screenbuffer.size_y; j++) {
269
            for (j = 0; j < conn->screenbuffer.size_y; j++) {
225
                            d = get_field_at(&(conn->screenbuffer),i, j)->character;
270
                c = get_field_at(&(conn->screenbuffer),i, j)->character;
226
                            if (d && d != ' ')
271
                if (c && c != ' ')
227
                                nsend_call_3(fb_info.phone, FB_PUTCHAR, d, j, i);
272
                    prtchr(c, j, i);
228
                        }
273
            }
229
 
274
       
230
                }
275
    }
231
                nsend_call_2(fb_info.phone, FB_CURSOR_GOTO, conn->screenbuffer.position_y, conn->screenbuffer.position_x);
276
    curs_goto(conn->screenbuffer.position_y, conn->screenbuffer.position_x);
232
                nsend_call_2(fb_info.phone, FB_SET_STYLE, conn->screenbuffer.style.fg_color, \
277
    set_style(&conn->screenbuffer.style);
-
 
278
    curs_visibility(1);
-
 
279
}
-
 
280
 
233
                        conn->screenbuffer.style.bg_color);
281
/** Handler for keyboard */
234
                send_call(fb_info.phone, FB_CURSOR_VISIBILITY, 1);
282
static void keyboard_events(ipc_callid_t iid, ipc_call_t *icall)
-
 
283
{
-
 
284
    ipc_callid_t callid;
-
 
285
    ipc_call_t call;
-
 
286
    int retval;
-
 
287
    char c;
-
 
288
    connection_t *conn;
235
 
289
   
-
 
290
    /* Ignore parameters, the connection is alread opened */
-
 
291
    while (1) {
-
 
292
        callid = async_get_call(&call);
-
 
293
        switch (IPC_GET_METHOD(call)) {
-
 
294
        case IPC_M_PHONE_HUNGUP:
-
 
295
            ipc_answer_fast(callid,0,0,0);
-
 
296
            /* TODO: Handle hangup */
-
 
297
            return;
-
 
298
        case KBD_PUSHCHAR:
-
 
299
            /* got key from keyboard driver */
-
 
300
           
-
 
301
            retval = 0;
-
 
302
            c = IPC_GET_ARG1(call);
-
 
303
            /* switch to another virtual console */
-
 
304
           
-
 
305
            conn = &connections[active_console];
-
 
306
//          if ((c >= KBD_KEY_F1) && (c < KBD_KEY_F1 + CONSOLE_COUNT)) {
-
 
307
            if ((c >= '0') && (c < '0' + CONSOLE_COUNT)) {
-
 
308
                if (c == '0')
-
 
309
                    change_console(-1);
-
 
310
                else
-
 
311
                    change_console(c - '1');
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 360... Line 436...
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
    }
364
 
440
   
-
 
441
    /* Save old kernel screen */
-
 
442
    kernel_pixmap = switch_screens(-1);
-
 
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