Rev 1668 | Rev 1673 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1668 | Rev 1672 | ||
---|---|---|---|
Line 92... | Line 92... | ||
92 | /* Style for text printing */ |
92 | /* Style for text printing */ |
93 | style_t style; |
93 | style_t style; |
94 | /* Auto-cursor position */ |
94 | /* Auto-cursor position */ |
95 | int cursor_active, cur_col, cur_row; |
95 | int cursor_active, cur_col, cur_row; |
96 | int cursor_shown; |
96 | int cursor_shown; |
- | 97 | /* Double buffering */ |
|
- | 98 | __u8 *dbdata; |
|
- | 99 | unsigned int dboffset; |
|
- | 100 | unsigned int paused; |
|
97 | } viewport_t; |
101 | } viewport_t; |
98 | 102 | ||
99 | #define MAX_ANIM_LEN 8 |
103 | #define MAX_ANIM_LEN 8 |
100 | #define MAX_ANIMATIONS 4 |
104 | #define MAX_ANIMATIONS 4 |
101 | typedef struct { |
105 | typedef struct { |
Line 210... | Line 214... | ||
210 | */ |
214 | */ |
211 | static void putpixel(int vp, unsigned int x, unsigned int y, int color) |
215 | static void putpixel(int vp, unsigned int x, unsigned int y, int color) |
212 | { |
216 | { |
213 | int dx = viewports[vp].x + x; |
217 | int dx = viewports[vp].x + x; |
214 | int dy = viewports[vp].y + y; |
218 | int dy = viewports[vp].y + y; |
- | 219 | ||
- | 220 | if (! viewports[vp].paused) |
|
215 | (*screen.rgb2scr)(&screen.fbaddress[POINTPOS(dx,dy)],color); |
221 | (*screen.rgb2scr)(&screen.fbaddress[POINTPOS(dx,dy)],color); |
- | 222 | ||
- | 223 | if (viewports[vp].dbdata) { |
|
- | 224 | int dline = (y + viewports[vp].dboffset) % viewports[vp].height; |
|
- | 225 | int doffset = screen.pixelbytes * (dline * viewports[vp].width + x); |
|
- | 226 | (*screen.rgb2scr)(&viewports[vp].dbdata[doffset],color); |
|
- | 227 | } |
|
216 | } |
228 | } |
- | 229 | ||
217 | /** Get pixel from viewport */ |
230 | /** Get pixel from viewport */ |
218 | static int getpixel(int vp, unsigned int x, unsigned int y) |
231 | static int getpixel(int vp, unsigned int x, unsigned int y) |
219 | { |
232 | { |
220 | int dx = viewports[vp].x + x; |
233 | int dx = viewports[vp].x + x; |
221 | int dy = viewports[vp].y + y; |
234 | int dy = viewports[vp].y + y; |
Line 241... | Line 254... | ||
241 | 254 | ||
242 | /* Clear first line */ |
255 | /* Clear first line */ |
243 | for (x = 0; x < width; x++) |
256 | for (x = 0; x < width; x++) |
244 | putpixel_mem(tmpline, x, 0, color); |
257 | putpixel_mem(tmpline, x, 0, color); |
245 | 258 | ||
- | 259 | if (!viewports[vp].paused) { |
|
246 | /* Recompute to screen coords */ |
260 | /* Recompute to screen coords */ |
247 | sx += viewports[vp].x; |
261 | sx += viewports[vp].x; |
248 | sy += viewports[vp].y; |
262 | sy += viewports[vp].y; |
249 | /* Copy the rest */ |
263 | /* Copy the rest */ |
250 | for (y = sy;y < sy+height; y++) |
264 | for (y = sy;y < sy+height; y++) |
251 | memcpy(&screen.fbaddress[POINTPOS(sx,y)], tmpline, |
265 | memcpy(&screen.fbaddress[POINTPOS(sx,y)], tmpline, |
252 | screen.pixelbytes * width); |
266 | screen.pixelbytes * width); |
- | 267 | } |
|
- | 268 | if (viewports[vp].dbdata) { |
|
- | 269 | for (y=sy;y < sy+height; y++) { |
|
- | 270 | int rline = (y + viewports[vp].dboffset) % viewports[vp].height; |
|
- | 271 | int rpos = (rline * viewports[vp].width + sx) * screen.pixelbytes; |
|
- | 272 | memcpy(&viewports[vp].dbdata[rpos], tmpline, screen.pixelbytes * width); |
|
- | 273 | } |
|
- | 274 | } |
|
253 | 275 | ||
254 | } |
276 | } |
255 | 277 | ||
256 | /** Fill viewport with background color */ |
278 | /** Fill viewport with background color */ |
257 | static void clear_port(int vp) |
279 | static void clear_port(int vp) |
Line 259... | Line 281... | ||
259 | viewport_t *vport = &viewports[vp]; |
281 | viewport_t *vport = &viewports[vp]; |
260 | 282 | ||
261 | draw_rectangle(vp, 0, 0, vport->width, vport->height, vport->style.bg_color); |
283 | draw_rectangle(vp, 0, 0, vport->width, vport->height, vport->style.bg_color); |
262 | } |
284 | } |
263 | 285 | ||
264 | /** Scroll port up/down |
286 | /** Scroll unbuffered viewport up/down |
265 | * |
287 | * |
266 | * @param vp Viewport to scroll |
288 | * @param vp Viewport to scroll |
267 | * @param rows Positive number - scroll up, negative - scroll down |
289 | * @param rows Positive number - scroll up, negative - scroll down |
268 | */ |
290 | */ |
269 | static void scroll_port(int vp, int rows) |
291 | static void scroll_port_nodb(int vp, int lines) |
270 | { |
292 | { |
271 | int y; |
293 | int y; |
272 | int startline; |
294 | int startline; |
273 | int endline; |
295 | int endline; |
274 | viewport_t *vport = &viewports[vp]; |
296 | viewport_t *vport = &viewports[vp]; |
275 | 297 | ||
276 | if (rows > 0) { |
298 | if (lines > 0) { |
277 | for (y=vport->y; y < vport->y+vport->height - rows*FONT_SCANLINES; y++) |
299 | for (y=vport->y; y < vport->y+vport->height - lines; y++) |
278 | memcpy(&screen.fbaddress[POINTPOS(vport->x,y)], |
300 | memcpy(&screen.fbaddress[POINTPOS(vport->x,y)], |
279 | &screen.fbaddress[POINTPOS(vport->x,y + rows*FONT_SCANLINES)], |
301 | &screen.fbaddress[POINTPOS(vport->x,y + lines)], |
280 | screen.pixelbytes * vport->width); |
302 | screen.pixelbytes * vport->width); |
281 | draw_rectangle(vp, 0, FONT_SCANLINES*(vport->rows - 1), |
303 | draw_rectangle(vp, 0, vport->height - lines, |
282 | vport->width, FONT_SCANLINES, vport->style.bg_color); |
304 | vport->width, lines, vport->style.bg_color); |
283 | } else if (rows < 0) { |
305 | } else if (lines < 0) { |
284 | rows = -rows; |
306 | lines = -lines; |
285 | for (y=vport->y + vport->height-1; y >= vport->y + rows*FONT_SCANLINES; y--) |
307 | for (y=vport->y + vport->height-1; y >= vport->y + lines; y--) |
286 | memcpy(&screen.fbaddress[POINTPOS(vport->x,y)], |
308 | memcpy(&screen.fbaddress[POINTPOS(vport->x,y)], |
287 | &screen.fbaddress[POINTPOS(vport->x,y - rows*FONT_SCANLINES)], |
309 | &screen.fbaddress[POINTPOS(vport->x,y - lines)], |
288 | screen.pixelbytes * vport->width); |
310 | screen.pixelbytes * vport->width); |
289 | draw_rectangle(vp, 0, 0, vport->width, FONT_SCANLINES, vport->style.bg_color); |
311 | draw_rectangle(vp, 0, 0, vport->width, lines, vport->style.bg_color); |
- | 312 | } |
|
- | 313 | } |
|
- | 314 | ||
- | 315 | /** Refresh given viewport from double buffer */ |
|
- | 316 | static void refresh_viewport_db(int vp) |
|
- | 317 | { |
|
- | 318 | unsigned int y, srcy, srcoff, dsty, dstx; |
|
- | 319 | ||
- | 320 | for (y = 0; y < viewports[vp].height; y++) { |
|
- | 321 | srcy = (y + viewports[vp].dboffset) % viewports[vp].height; |
|
- | 322 | srcoff = (viewports[vp].width * srcy) * screen.pixelbytes; |
|
- | 323 | ||
- | 324 | dstx = viewports[vp].x; |
|
- | 325 | dsty = viewports[vp].y + y; |
|
- | 326 | ||
- | 327 | memcpy(&screen.fbaddress[POINTPOS(dstx,dsty)], |
|
- | 328 | &viewports[vp].dbdata[srcoff], |
|
- | 329 | viewports[vp].width*screen.pixelbytes); |
|
290 | } |
330 | } |
291 | } |
331 | } |
292 | 332 | ||
- | 333 | /** Scroll viewport that has double buffering enabled */ |
|
- | 334 | static void scroll_port_db(int vp, int lines) |
|
- | 335 | { |
|
- | 336 | ++viewports[vp].paused; |
|
- | 337 | if (lines > 0) { |
|
- | 338 | draw_rectangle(vp, 0, 0, viewports[vp].width, lines, |
|
- | 339 | viewports[vp].style.bg_color); |
|
- | 340 | viewports[vp].dboffset += lines; |
|
- | 341 | viewports[vp].dboffset %= viewports[vp].height; |
|
- | 342 | } else if (lines < 0) { |
|
- | 343 | lines = -lines; |
|
- | 344 | draw_rectangle(vp, 0, viewports[vp].height-lines, |
|
- | 345 | viewports[vp].width, lines, |
|
- | 346 | viewports[vp].style.bg_color); |
|
- | 347 | ||
- | 348 | if (viewports[vp].dboffset < lines) |
|
- | 349 | viewports[vp].dboffset += viewports[vp].height; |
|
- | 350 | viewports[vp].dboffset -= lines; |
|
- | 351 | } |
|
- | 352 | ||
- | 353 | --viewports[vp].paused; |
|
- | 354 | ||
- | 355 | refresh_viewport_db(vp); |
|
- | 356 | ||
- | 357 | } |
|
- | 358 | ||
- | 359 | /** Scrolls viewport given number of lines */ |
|
- | 360 | static void scroll_port(int vp, int lines) |
|
- | 361 | { |
|
- | 362 | if (viewports[vp].dbdata) |
|
- | 363 | scroll_port_db(vp, lines); |
|
- | 364 | else |
|
- | 365 | scroll_port_nodb(vp, lines); |
|
- | 366 | ||
- | 367 | } |
|
- | 368 | ||
293 | static void invert_pixel(int vp,unsigned int x, unsigned int y) |
369 | static void invert_pixel(int vp,unsigned int x, unsigned int y) |
294 | { |
370 | { |
295 | putpixel(vp, x, y, ~getpixel(vp, x, y)); |
371 | putpixel(vp, x, y, ~getpixel(vp, x, y)); |
296 | } |
372 | } |
297 | 373 | ||
Line 983... | Line 1059... | ||
983 | if (i > vport->rows || i < (- (int)vport->rows)) { |
1059 | if (i > vport->rows || i < (- (int)vport->rows)) { |
984 | retval = EINVAL; |
1060 | retval = EINVAL; |
985 | break; |
1061 | break; |
986 | } |
1062 | } |
987 | cursor_hide(vp); |
1063 | cursor_hide(vp); |
988 | scroll_port(vp, i); |
1064 | scroll_port(vp, i*FONT_SCANLINES); |
989 | cursor_print(vp); |
1065 | cursor_print(vp); |
990 | retval = 0; |
1066 | retval = 0; |
991 | break; |
1067 | break; |
- | 1068 | case FB_VIEWPORT_DB: |
|
- | 1069 | /* Enable double buffering */ |
|
- | 1070 | i = IPC_GET_ARG1(call); |
|
- | 1071 | if (i == -1) |
|
- | 1072 | i = vp; |
|
- | 1073 | if (i < 0 || i >= MAX_VIEWPORTS) { |
|
- | 1074 | retval = EINVAL; |
|
- | 1075 | break; |
|
- | 1076 | } |
|
- | 1077 | if (! viewports[i].initialized ) { |
|
- | 1078 | while (1) |
|
- | 1079 | ; |
|
- | 1080 | retval = EADDRNOTAVAIL; |
|
- | 1081 | break; |
|
- | 1082 | } |
|
- | 1083 | viewports[i].dboffset = 0; |
|
- | 1084 | if (IPC_GET_ARG2(call) == 1 && !viewports[i].dbdata) |
|
- | 1085 | viewports[i].dbdata = malloc(screen.pixelbytes*viewports[i].width * viewports[i].height); |
|
- | 1086 | else if (IPC_GET_ARG2(call) == 0 && viewports[i].dbdata) { |
|
- | 1087 | free(viewports[i].dbdata); |
|
- | 1088 | viewports[i].dbdata = NULL; |
|
- | 1089 | } |
|
- | 1090 | retval = 0; |
|
- | 1091 | break; |
|
992 | case FB_VIEWPORT_SWITCH: |
1092 | case FB_VIEWPORT_SWITCH: |
993 | i = IPC_GET_ARG1(call); |
1093 | i = IPC_GET_ARG1(call); |
994 | if (i < 0 || i >= MAX_VIEWPORTS) { |
1094 | if (i < 0 || i >= MAX_VIEWPORTS) { |
995 | retval = EINVAL; |
1095 | retval = EINVAL; |
996 | break; |
1096 | break; |
Line 1020... | Line 1120... | ||
1020 | if (! viewports[i].initialized ) { |
1120 | if (! viewports[i].initialized ) { |
1021 | retval = EADDRNOTAVAIL; |
1121 | retval = EADDRNOTAVAIL; |
1022 | break; |
1122 | break; |
1023 | } |
1123 | } |
1024 | viewports[i].initialized = 0; |
1124 | viewports[i].initialized = 0; |
- | 1125 | if (viewports[i].dbdata) { |
|
- | 1126 | free(viewports[i].dbdata); |
|
- | 1127 | viewports[i].dbdata = NULL; |
|
- | 1128 | } |
|
1025 | retval = 0; |
1129 | retval = 0; |
1026 | break; |
1130 | break; |
1027 | case FB_SET_STYLE: |
1131 | case FB_SET_STYLE: |
1028 | vport->style.fg_color = IPC_GET_ARG1(call); |
1132 | vport->style.fg_color = IPC_GET_ARG1(call); |
1029 | vport->style.bg_color = IPC_GET_ARG2(call); |
1133 | vport->style.bg_color = IPC_GET_ARG2(call); |