Browse Source

[fbcon] Add support for displaying a cursor

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 11 years ago
parent
commit
a2638a8edd
2 changed files with 97 additions and 25 deletions
  1. 95
    25
      src/core/fbcon.c
  2. 2
    0
      src/include/ipxe/fbcon.h

+ 95
- 25
src/core/fbcon.c View File

288
  */
288
  */
289
 static void fbcon_clear ( struct fbcon *fbcon, unsigned int ypos ) {
289
 static void fbcon_clear ( struct fbcon *fbcon, unsigned int ypos ) {
290
 	struct fbcon_text_cell cell = {
290
 	struct fbcon_text_cell cell = {
291
-		.foreground = 0,
291
+		.foreground = fbcon->foreground,
292
 		.background = fbcon->background,
292
 		.background = fbcon->background,
293
 		.character = ' ',
293
 		.character = ' ',
294
 	};
294
 	};
317
 static void fbcon_scroll ( struct fbcon *fbcon ) {
317
 static void fbcon_scroll ( struct fbcon *fbcon ) {
318
 	size_t row_len;
318
 	size_t row_len;
319
 
319
 
320
-	/* If we are not yet at the bottom of the screen, just update
321
-	 * the cursor position.
322
-	 */
323
-	if ( fbcon->ypos < ( fbcon->character.height - 1 ) ) {
324
-		fbcon->ypos++;
325
-		return;
326
-	}
320
+	/* Sanity check */
321
+	assert ( fbcon->ypos == fbcon->character.height );
327
 
322
 
328
-	/* Otherwise, scroll up character array */
323
+	/* Scroll up character array */
329
 	row_len = ( fbcon->character.width * sizeof ( struct fbcon_text_cell ));
324
 	row_len = ( fbcon->character.width * sizeof ( struct fbcon_text_cell ));
330
 	memmove_user ( fbcon->text.start, 0, fbcon->text.start, row_len,
325
 	memmove_user ( fbcon->text.start, 0, fbcon->text.start, row_len,
331
 		       ( row_len * ( fbcon->character.height - 1 ) ) );
326
 		       ( row_len * ( fbcon->character.height - 1 ) ) );
332
 	fbcon_clear ( fbcon, ( fbcon->character.height - 1 ) );
327
 	fbcon_clear ( fbcon, ( fbcon->character.height - 1 ) );
328
+
329
+	/* Update cursor position */
330
+	fbcon->ypos--;
331
+}
332
+
333
+/**
334
+ * Draw character at cursor position
335
+ *
336
+ * @v fbcon		Frame buffer console
337
+ * @v show_cursor	Show cursor
338
+ */
339
+static void fbcon_draw_cursor ( struct fbcon *fbcon, int show_cursor ) {
340
+	struct fbcon_text_cell cell;
341
+	size_t offset;
342
+	uint32_t background;
343
+
344
+	offset = ( ( ( fbcon->ypos * fbcon->character.width ) + fbcon->xpos ) *
345
+		   sizeof ( cell ) );
346
+	copy_from_user ( &cell, fbcon->text.start, offset, sizeof ( cell ) );
347
+	if ( show_cursor ) {
348
+		background = cell.background;
349
+		cell.background = cell.foreground;
350
+		cell.foreground = ( ( background == FBCON_TRANSPARENT ) ?
351
+				    0 : background );
352
+	}
353
+	fbcon_draw_character ( fbcon, &cell, fbcon->xpos, fbcon->ypos );
333
 }
354
 }
334
 
355
 
335
 /**
356
 /**
346
 	int cx = ( params[1] - 1 );
367
 	int cx = ( params[1] - 1 );
347
 	int cy = ( params[0] - 1 );
368
 	int cy = ( params[0] - 1 );
348
 
369
 
370
+	fbcon_draw_cursor ( fbcon, 0 );
349
 	fbcon->xpos = cx;
371
 	fbcon->xpos = cx;
350
 	if ( fbcon->xpos >= fbcon->character.width )
372
 	if ( fbcon->xpos >= fbcon->character.width )
351
 		fbcon->xpos = ( fbcon->character.width - 1 );
373
 		fbcon->xpos = ( fbcon->character.width - 1 );
352
 	fbcon->ypos = cy;
374
 	fbcon->ypos = cy;
353
 	if ( fbcon->ypos >= fbcon->character.height )
375
 	if ( fbcon->ypos >= fbcon->character.height )
354
 		fbcon->ypos = ( fbcon->character.height - 1 );
376
 		fbcon->ypos = ( fbcon->character.height - 1 );
377
+	fbcon_draw_cursor ( fbcon, fbcon->show_cursor );
355
 }
378
 }
356
 
379
 
357
 /**
380
 /**
375
 	/* Reset cursor position */
398
 	/* Reset cursor position */
376
 	fbcon->xpos = 0;
399
 	fbcon->xpos = 0;
377
 	fbcon->ypos = 0;
400
 	fbcon->ypos = 0;
401
+	fbcon_draw_cursor ( fbcon, fbcon->show_cursor );
378
 }
402
 }
379
 
403
 
380
 /**
404
 /**
437
 	}
461
 	}
438
 }
462
 }
439
 
463
 
464
+/**
465
+ * Handle ANSI DECTCEM set (show cursor)
466
+ *
467
+ * @v ctx		ANSI escape sequence context
468
+ * @v count		Parameter count
469
+ * @v params		List of graphic rendition aspects
470
+ */
471
+static void fbcon_handle_dectcem_set ( struct ansiesc_context *ctx,
472
+				       unsigned int count __unused,
473
+				       int params[] __unused ) {
474
+	struct fbcon *fbcon = container_of ( ctx, struct fbcon, ctx );
475
+
476
+	fbcon->show_cursor = 1;
477
+	fbcon_draw_cursor ( fbcon, 1 );
478
+}
479
+
480
+/**
481
+ * Handle ANSI DECTCEM reset (hide cursor)
482
+ *
483
+ * @v ctx		ANSI escape sequence context
484
+ * @v count		Parameter count
485
+ * @v params		List of graphic rendition aspects
486
+ */
487
+static void fbcon_handle_dectcem_reset ( struct ansiesc_context *ctx,
488
+					 unsigned int count __unused,
489
+					 int params[] __unused ) {
490
+	struct fbcon *fbcon = container_of ( ctx, struct fbcon, ctx );
491
+
492
+	fbcon->show_cursor = 0;
493
+	fbcon_draw_cursor ( fbcon, 0 );
494
+}
495
+
440
 /** ANSI escape sequence handlers */
496
 /** ANSI escape sequence handlers */
441
 static struct ansiesc_handler fbcon_ansiesc_handlers[] = {
497
 static struct ansiesc_handler fbcon_ansiesc_handlers[] = {
442
 	{ ANSIESC_CUP, fbcon_handle_cup },
498
 	{ ANSIESC_CUP, fbcon_handle_cup },
443
 	{ ANSIESC_ED, fbcon_handle_ed },
499
 	{ ANSIESC_ED, fbcon_handle_ed },
444
 	{ ANSIESC_SGR, fbcon_handle_sgr },
500
 	{ ANSIESC_SGR, fbcon_handle_sgr },
501
+	{ ANSIESC_DECTCEM_SET, fbcon_handle_dectcem_set },
502
+	{ ANSIESC_DECTCEM_RESET, fbcon_handle_dectcem_reset },
445
 	{ 0, NULL }
503
 	{ 0, NULL }
446
 };
504
 };
447
 
505
 
462
 	/* Handle control characters */
520
 	/* Handle control characters */
463
 	switch ( character ) {
521
 	switch ( character ) {
464
 	case '\r':
522
 	case '\r':
523
+		fbcon_draw_cursor ( fbcon, 0 );
465
 		fbcon->xpos = 0;
524
 		fbcon->xpos = 0;
466
-		return;
525
+		break;
467
 	case '\n':
526
 	case '\n':
527
+		fbcon_draw_cursor ( fbcon, 0 );
468
 		fbcon->xpos = 0;
528
 		fbcon->xpos = 0;
469
-		fbcon_scroll ( fbcon );
470
-		return;
529
+		fbcon->ypos++;
530
+		break;
471
 	case '\b':
531
 	case '\b':
532
+		fbcon_draw_cursor ( fbcon, 0 );
472
 		if ( fbcon->xpos ) {
533
 		if ( fbcon->xpos ) {
473
 			fbcon->xpos--;
534
 			fbcon->xpos--;
474
 		} else if ( fbcon->ypos ) {
535
 		} else if ( fbcon->ypos ) {
475
 			fbcon->xpos = ( fbcon->character.width - 1 );
536
 			fbcon->xpos = ( fbcon->character.width - 1 );
476
 			fbcon->ypos--;
537
 			fbcon->ypos--;
477
 		}
538
 		}
478
-		return;
539
+		break;
540
+	default:
541
+		/* Print character at current cursor position */
542
+		cell.foreground = ( fbcon->foreground | fbcon->bold );
543
+		cell.background = fbcon->background;
544
+		cell.character = character;
545
+		fbcon_store_character ( fbcon, &cell, fbcon->xpos, fbcon->ypos);
546
+		fbcon_draw_character ( fbcon, &cell, fbcon->xpos, fbcon->ypos );
547
+
548
+		/* Advance cursor */
549
+		fbcon->xpos++;
550
+		if ( fbcon->xpos >= fbcon->character.width ) {
551
+			fbcon->xpos = 0;
552
+			fbcon->ypos++;
553
+		}
554
+		break;
479
 	}
555
 	}
480
 
556
 
481
-	/* Print character at current cursor position */
482
-	cell.foreground = ( fbcon->foreground | fbcon->bold );
483
-	cell.background = fbcon->background;
484
-	cell.character = character;
485
-	fbcon_store_character ( fbcon, &cell, fbcon->xpos, fbcon->ypos );
486
-	fbcon_draw_character ( fbcon, &cell, fbcon->xpos, fbcon->ypos );
487
-
488
-	/* Advance cursor */
489
-	fbcon->xpos++;
490
-	if ( fbcon->xpos >= fbcon->character.width ) {
491
-		fbcon->xpos = 0;
557
+	/* Scroll screen if necessary */
558
+	if ( fbcon->ypos >= fbcon->character.height )
492
 		fbcon_scroll ( fbcon );
559
 		fbcon_scroll ( fbcon );
493
-	}
560
+
561
+	/* Show cursor */
562
+	fbcon_draw_cursor ( fbcon, fbcon->show_cursor );
494
 }
563
 }
495
 
564
 
496
 /**
565
 /**
673
 	fbcon->map = map;
742
 	fbcon->map = map;
674
 	fbcon->font = font;
743
 	fbcon->font = font;
675
 	fbcon->ctx.handlers = fbcon_ansiesc_handlers;
744
 	fbcon->ctx.handlers = fbcon_ansiesc_handlers;
745
+	fbcon->show_cursor = 1;
676
 
746
 
677
 	/* Derive overall length */
747
 	/* Derive overall length */
678
 	fbcon->len = ( pixel->height * pixel->stride );
748
 	fbcon->len = ( pixel->height * pixel->stride );

+ 2
- 0
src/include/ipxe/fbcon.h View File

147
 	struct fbcon_text text;
147
 	struct fbcon_text text;
148
 	/** Background picture */
148
 	/** Background picture */
149
 	struct fbcon_picture picture;
149
 	struct fbcon_picture picture;
150
+	/** Display cursor */
151
+	int show_cursor;
150
 };
152
 };
151
 
153
 
152
 extern int fbcon_init ( struct fbcon *fbcon, userptr_t start,
154
 extern int fbcon_init ( struct fbcon *fbcon, userptr_t start,

Loading…
Cancel
Save