]> Joshua Wise's Git repositories - netwatch.git/blame - cs410/cs410.c
First pass of 410watch UI code.
[netwatch.git] / cs410 / cs410.c
CommitLineData
6093edb5
JW
1/* cs410.c
2 * Entry points for 15-410 extensions
3 * NetWatch system management mode administration console
4 *
5 * Copyright (c) 2008 Jacob Potter and Joshua Wise. All rights reserved.
6 * This program is free software; you can redistribute and/or modify it under
7 * the terms found in the file LICENSE in the root of this source tree.
8 *
9 */
10
11#include <io.h>
12#include <smi.h>
13#include <smram.h>
14#include <video_defines.h>
15#include <output.h>
16#include <minilib.h>
17
18#define CONSCOLOR 0x1F
19
20unsigned char oldcons[80 * 25 * 2];
21
22static unsigned char vga_read(unsigned char idx)
23{
24 outb(CRTC_IDX_REG, idx);
25 return inb(CRTC_DATA_REG);
26}
27
28static char * vga_base()
29{
30 return (char *) (
31 0xB8000
32 + (((unsigned int) vga_read(CRTC_START_ADDR_MSB_IDX)) << 9)
33 + (((unsigned int) vga_read(CRTC_START_ADDR_LSB_IDX)) << 1)
34 );
35}
36
37static void grey_console()
38{
39 int i;
40 char *p = vga_base();
41
42 for (i = 0; i < 80*25; i++, p+=2)
43 p[1] &= ~0xF8; /* Clear the background and any brightness. */
44}
45
46#define CHAR(x, y) (base[((y)*80+(x))*2])
47#define COLOR(x, y) (base[((y)*80+(x))*2+1])
48
49static void ui_frame(int xp, int yp, int xs, int ys, char *title)
50{
51 int x, y;
52 char *base = vga_base();
53
54 /* Blank and fill the region. */
55 for (y = yp; y <= (yp + ys); y++)
56 for (x = xp; x <= (xp + xs); x++)
57 {
58 CHAR(x, y) = ' ';
59 COLOR(x, y) = CONSCOLOR;
60 }
61
62 /* Draw the top and the bottom (and the bar if need be). */
63 for (x = xp; x <= (xp + xs); x++)
64 {
65 CHAR(x, yp) = 0xCD /* double line horizontal */;
66 CHAR(x, yp+ys) = 0xCD /* double line horizontal */;
67 if (title)
68 CHAR(x, yp+2) = 0xC4 /* single line horizontal */;
69 }
70
71 /* Draw the left and right. */
72 for (y = yp; y <= (yp + ys); y++)
73 {
74 CHAR(xp, y) = 0xBA /* double line vertical */;
75 CHAR(xp+xs, y) = 0xBA /* double line vertical */;
76 }
77
78 /* Drop in the corners. */
79 CHAR(xp, yp) = 0xC9;
80 CHAR(xp+xs, yp) = 0xBB;
81 CHAR(xp, yp+ys) = 0xC8;
82 CHAR(xp+xs, yp+ys) = 0xBC;
83 if (title)
84 {
85 CHAR(xp, yp+2) = 0xC7;
86 CHAR(xp+xs, yp+2) = 0xB6;
87 }
88
89 /* Drop in the text. */
90 if (title)
91 for (x = (xs - strlen(title)) / 2 + xp; *title; x++, title++)
92 CHAR(x, yp+1) = *title;
93}
94
95static void ui_label(int xp, int yp, char *s)
96{
97 int x;
98 char *base = vga_base();
99
100 for (x = xp; *s; x++, s++)
101 CHAR(x, yp) = *s;
102}
103
104typedef enum ui_element_type {
105 UI_FRAME = 0,
106 UI_LABEL = 1,
107 UI_END = -1
108} ui_element_type_t;
109
110typedef union ui_element {
111 ui_element_type_t type;
112 struct {
113 ui_element_type_t type;
114 int xp, yp;
115 int xs, ys;
116 char *title;
117 } frame;
118 struct {
119 ui_element_type_t type;
120 int xp, yp;
121 char *text;
122 } label;
123} ui_element_t;
124
125static ui_element_t mainmenu[] = {
126 { .frame = {
127 .type = UI_FRAME,
128 .xp = 10, .yp = 5,
129 .xs = 60, .ys = 15,
130 .title = "NetWatch main menu" } },
131 { .label = {
132 .type = UI_LABEL,
133 .xp = 12, .yp = 8,
134 .text = "Options:" } },
135 { .label = {
136 .type = UI_LABEL,
137 .xp = 12, .yp = 10,
138 .text = "q - Return to system" } },
139 { .type = UI_END }
140};
141
142static void ui_render(ui_element_t *ui)
143{
144 for (; ui->type != UI_END; ui++)
145 switch (ui->type)
146 {
147 case UI_FRAME:
148 ui_frame(ui->frame.xp, ui->frame.yp,
149 ui->frame.xs, ui->frame.ys,
150 ui->frame.title);
151 break;
152 case UI_LABEL:
153 ui_label(ui->label.xp, ui->label.yp,
154 ui->label.text);
155 break;
156 case UI_END:
157 default:
158 return; /* ??? */
159 }
160}
161
162void cs410_pwrbtn_handler(smi_event_t ev)
163{
164 smram_state_t old_state;
165
166 outputf("410watch: Power button event");
167
168 /* Save off the console. */
169 old_state = smram_save_state();
170 smram_aseg_set_state(SMRAM_ASEG_SMMCODE);
171 memcpy(oldcons, vga_base(), 80*25*2);
172
173 /* Pull a Simics, and grey out the console -- why not? */
174 grey_console();
175
176 /* Show the main menu. */
177 ui_render(mainmenu);
178
179 /* Allow access to data in ASEG. */
180 smram_restore_state(old_state);
181
182 /* Now just sit for a while to show off our newly greyed console. */
183 char c;
184 char *p = vga_base() + (11*80+12)*2;
185 extern int getchar();
186 while ((c = getchar()) != 'q')
187 {
188 smram_aseg_set_state(SMRAM_ASEG_SMMCODE);
189 *p = c;
190 p += 2;
191 smram_restore_state(old_state);
192 }
193
194 /* Put the console back. */
195 smram_aseg_set_state(SMRAM_ASEG_SMMCODE);
196 memcpy(vga_base(), oldcons, 80*25*2);
197 smram_restore_state(old_state);
198
199}
This page took 0.054521 seconds and 4 git commands to generate.