refactor rendering engine

This commit is contained in:
marschap
2007-04-29 12:08:16 +00:00
parent 8214555559
commit 2e63f102d9
+153 -81
View File
@@ -51,7 +51,14 @@ int server_msg_expire = 0;
#define BUFSIZE 1024 /* larger than display width => large enough */ #define BUFSIZE 1024 /* larger than display width => large enough */
static int render_frame(LinkedList *list, char fscroll, int left, int top, int right, int bottom, int fwid, int fhgt, int fspeed, long timer); static int render_frame(LinkedList *list, int left, int top, int right, int bottom, int fwid, int fhgt, char fscroll, int fspeed, long timer);
static int render_string(Widget *w, int left, int top, int right, int bottom, int fy);
static int render_hbar(Widget *w, int left, int top, int right, int bottom, int fy);
static int render_vbar(Widget *w, int left, int top, int right, int bottom);
static int render_title(Widget *w, int left, int top, int right, int bottom, long timer);
static int render_scroller(Widget *w, int left, int top, int right, int bottom, long timer);
static int render_num(Widget *w, int left, int top, int right, int bottom);
int int
render_screen(Screen *s, long timer) render_screen(Screen *s, long timer)
@@ -113,9 +120,9 @@ render_screen(Screen *s, long timer)
drivers_output(output_state); drivers_output(output_state);
/* Draw a frame... */ /* Draw a frame... */
render_frame(s->widgetlist, 'v', 0, 0, render_frame(s->widgetlist, 0, 0,
display_props->width, display_props->height, display_props->width, display_props->height,
s->width, s->height, max(s->duration / s->height, 1), timer); s->width, s->height, 'v', max(s->duration / s->height, 1), timer);
/* Set the cursor */ /* Set the cursor */
drivers_cursor(s->cursor_x, s->cursor_y, s->cursor); drivers_cursor(s->cursor_x, s->cursor_y, s->cursor);
@@ -157,24 +164,23 @@ render_screen(Screen *s, long timer)
/* */ /* */
static int static int
render_frame(LinkedList *list, render_frame(LinkedList *list,
char fscroll, /* direction of scrolling */
int left, /* left edge of frame */ int left, /* left edge of frame */
int top, /* top edge of frame */ int top, /* top edge of frame */
int right, /* right edge of frame */ int right, /* right edge of frame */
int bottom, /* bottom edge of frame */ int bottom, /* bottom edge of frame */
int fwid, /* frame width? */ int fwid, /* frame width? */
int fhgt, /* frame height? */ int fhgt, /* frame height? */
char fscroll, /* direction of scrolling */
int fspeed, /* speed of scrolling... */ int fspeed, /* speed of scrolling... */
long timer) /* current timer tick */ long timer) /* current timer tick */
{ {
int vis_width = right - left; /* width of visible frame area */ int fy = 0; /* Scrolling offset for the frame... */
int vis_height = bottom - top; /* height of visible frame area */
int /*fx = 0,*/ fy = 0; /* Scrolling offset for the frame... */
debug(RPT_DEBUG, "%s(list=%p, fscroll='%c', left=%d, top=%d, " debug(RPT_DEBUG, "%s(list=%p, left=%d, top=%d, "
"right=%d, bottom=%d, fwid=%d, fhgt=%d, fspeed=%d, timer=%ld)", "right=%d, bottom=%d, fwid=%d, fhgt=%d, "
__FUNCTION__, list, fscroll, left,top, right, bottom, "fscroll='%c', fspeed=%d, timer=%ld)",
fwid, fhgt, fspeed, timer); __FUNCTION__, list, left, top, right, bottom,
fwid, fhgt, fscroll, fspeed, timer);
/* return on no data or illegal height */ /* return on no data or illegal height */
if ((list == NULL) || (fhgt <= 0)) if ((list == NULL) || (fhgt <= 0))
@@ -182,14 +188,16 @@ render_frame(LinkedList *list,
if (fscroll == 'v') { /* vertical scrolling */ if (fscroll == 'v') { /* vertical scrolling */
// only set offset !=0 when fspeed is != 0 and there is something to scroll // only set offset !=0 when fspeed is != 0 and there is something to scroll
if (fspeed && (fhgt > vis_height)) { if ((fspeed != 0) && (fhgt > bottom - top)) {
int fy_max = fhgt - vis_height + 1; int fy_max = fhgt - (bottom - top) + 1;
fy = (fspeed > 0) fy = (fspeed > 0)
? (timer / fspeed) % fy_max ? (timer / fspeed) % fy_max
: (-fspeed * timer) % fy_max; : (-fspeed * timer) % fy_max;
fy = max(fy, 0); // safeguard against negative values fy = max(fy, 0); // safeguard against negative values
debug(RPT_DEBUG, "%s: fy=%d", __FUNCTION__, fy);
} }
} }
else if (fscroll == 'h') { /* horizontal scrolling */ else if (fscroll == 'h') { /* horizontal scrolling */
@@ -201,7 +209,6 @@ render_frame(LinkedList *list,
/* loop over all widgets */ /* loop over all widgets */
do { do {
char str[BUFSIZE]; /* scratch buffer */
Widget *w = (Widget *) LL_Get(list); Widget *w = (Widget *) LL_Get(list);
if (w == NULL) if (w == NULL)
@@ -210,34 +217,92 @@ render_frame(LinkedList *list,
/* TODO: Make this cleaner and more flexible! */ /* TODO: Make this cleaner and more flexible! */
switch (w->type) { switch (w->type) {
case WID_STRING: case WID_STRING:
if ((w->x > 0) && (w->y > 0) && (w->text) && render_string(w, left, top - fy, right, bottom, fy);
(w->y <= vis_height + fy) && (w->y > fy)) {
int length;
w->x = min(w->x, vis_width);
length = min(vis_width - w->x + 1, sizeof(str));
strncpy(str, w->text, length);
str[length] = '\0';
drivers_string(w->x + left, w->y + top - fy, str);
}
break; break;
case WID_HBAR: case WID_HBAR:
if ((w->x > 0) && (w->y > 0) && render_hbar(w, left, top - fy, right, bottom, fy);
(w->y <= vis_height + fy) && (w->y > fy)) { break;
case WID_VBAR: /* FIXME: Vbars don't work in frames! */
render_vbar(w, left, top, right, bottom);
break;
case WID_ICON:
drivers_icon(w->x, w->y, w->length);
break;
case WID_TITLE: /* FIXME: Doesn't work quite right in frames... */
render_title(w, left, top, right, bottom, timer);
break;
case WID_SCROLLER: /* FIXME: doesn't work in frames... */
render_scroller(w, left, top, right, bottom, timer);
break;
case WID_FRAME:
{
/* FIXME: doesn't handle nested frames quite right!
* doesn't handle scrolling in nested frames at all...
*/
int new_left = left + w->left - 1;
int new_top = top + w->top - 1;
int new_right = min(left + w->right, right);
int new_bottom = min(top + w->bottom, bottom);
if ((new_left < right) && (new_top < bottom)) /* Render only if it's visible... */
render_frame(w->frame_screen->widgetlist, new_left, new_top,
new_right, new_bottom, w->width, w->height,
w->length, w->speed, timer);
}
break;
case WID_NUM: /* FIXME: doesn't work in frames... */
/* NOTE: y=10 means COLON (:) */
if ((w->x > 0) && (w->y >= 0) && (w->y <= 10)) {
drivers_num(w->x + left, w->y);
}
break;
case WID_NONE:
default:
break;
}
} while (LL_Next(list) == 0);
return 0;
}
static int
render_string(Widget *w, int left, int top, int right, int bottom, int fy)
{
debug(RPT_DEBUG, "%s(w=%p, left=%d, top=%d, right=%d, bottom=%d, fy=%d)",
__FUNCTION__, w, left, top, right, bottom, fy);
if ((w != NULL) && (w->text != NULL) &&
(w->x > 0) && (w->y > 0) && (w->y > fy) && (w->y <= bottom - top)) {
int length;
char str[BUFSIZE];
w->x = min(w->x, right - left);
length = min(right - left - w->x + 1, sizeof(str));
strncpy(str, w->text, length);
str[length] = '\0';
drivers_string(w->x + left, w->y + top, str);
}
return 0;
}
static int
render_hbar(Widget *w, int left, int top, int right, int bottom, int fy)
{
debug(RPT_DEBUG, "%s(w=%p, left=%d, top=%d, right=%d, bottom=%d, fy=%d)",
__FUNCTION__, w, left, top, right, bottom, fy);
if ((w != NULL) &&
(w->x > 0) && (w->y > 0) && (w->y > fy) && (w->y <= bottom - top)) {
if (w->length > 0) { if (w->length > 0) {
if ((w->length / display_props->cellwidth) < vis_width - w->x + 1) {
/*was: drivers_hbar(w->x + left, w->y + top - fy, w->length); */
/* improvised len and promille */
int full_len = display_props->width - w->x - left + 1; int full_len = display_props->width - w->x - left + 1;
int promille = (long) 1000 * w->length / (display_props->cellwidth * full_len); int promille = 1000;
drivers_hbar(w->x + left, w->y + top - fy, full_len, promille, BAR_PATTERN_FILLED);
} if ((w->length / display_props->cellwidth) < right - left - w->x + 1)
else { promille = (long) 1000 * w->length / (display_props->cellwidth * full_len);
/*was: drivers_hbar(w->x + left, w->y + top - fy, wid * display_props->cellwidth); */
/* Improvised len and promille while we have the old widget language */ drivers_hbar(w->x + left, w->y + top, full_len, promille, BAR_PATTERN_FILLED);
int full_len = (display_props->width - w->x - left + 1);
drivers_hbar(w->x + left, w->y + top - fy, full_len, 1000, BAR_PATTERN_FILLED);
}
} }
else if (w->length < 0) { else if (w->length < 0) {
/* TODO: Rearrange stuff to get left-extending /* TODO: Rearrange stuff to get left-extending
@@ -247,13 +312,21 @@ render_frame(LinkedList *list,
*/ */
} }
} }
break; return 0;
case WID_VBAR: /* FIXME: Vbars don't work in frames! */ }
if ((w->x > 0) && (w->y > 0)) {
static int
render_vbar(Widget *w, int left, int top, int right, int bottom)
{
debug(RPT_DEBUG, "%s(w=%p, left=%d, top=%d, right=%d, bottom=%d)",
__FUNCTION__, w, left, top, right, bottom);
if ((w != NULL) && (w->x > 0) && (w->y > 0)) {
if (w->length > 0) { if (w->length > 0) {
/* Improvised len and promille while we have the old widget language */
int full_len = display_props->height; int full_len = display_props->height;
int promille = (long) 1000 * w->length / display_props->cellheight / full_len; int promille = (long) 1000 * w->length / display_props->cellheight / full_len;
drivers_vbar(w->x, display_props->height, full_len, promille, BAR_PATTERN_FILLED); drivers_vbar(w->x, display_props->height, full_len, promille, BAR_PATTERN_FILLED);
} }
else if (w->length < 0) { else if (w->length < 0) {
@@ -264,13 +337,20 @@ render_frame(LinkedList *list,
*/ */
} }
} }
break; return 0;
case WID_ICON: }
drivers_icon(w->x, w->y, w->length);
break;
case WID_TITLE: /* FIXME: Doesn't work quite right in frames... */ static int
if ((w->text != NULL) && (vis_width >= 8)) { render_title(Widget *w, int left, int top, int right, int bottom, long timer)
{
debug(RPT_DEBUG, "%s(w=%p, left=%d, top=%d, right=%d, bottom=%d, timer=%ld)",
__FUNCTION__, w, left, top, right, bottom, timer);
int vis_width = right - left;
if ((w != NULL) && (w->text != NULL) && (vis_width >= 8)) {
char str[BUFSIZE];
int length = strlen(w->text); int length = strlen(w->text);
int x; int x;
@@ -310,9 +390,18 @@ render_frame(LinkedList *list,
drivers_icon(w->x + x + left, w->y + top, ICON_BLOCK_FILLED); drivers_icon(w->x + x + left, w->y + top, ICON_BLOCK_FILLED);
} }
} }
break; return 0;
case WID_SCROLLER: /* FIXME: doesn't work in frames... */ }
static int
render_scroller(Widget *w, int left, int top, int right, int bottom, long timer)
{
debug(RPT_DEBUG, "%s(w=%p, left=%d, top=%d, right=%d, bottom=%d, timer=%ld)",
__FUNCTION__, w, left, top, right, bottom, timer);
if ((w->text != NULL) && (w->right >= w->left)) { if ((w->text != NULL) && (w->right >= w->left)) {
char str[BUFSIZE];
int length; int length;
int offset; int offset;
int screen_width; int screen_width;
@@ -320,10 +409,8 @@ render_frame(LinkedList *list,
/*debug(RPT_DEBUG, "%s: %s %d",__FUNCTION__,w->text,timer);*/ /*debug(RPT_DEBUG, "%s: %s %d",__FUNCTION__,w->text,timer);*/
screen_width = abs(w->right - w->left + 1); screen_width = abs(w->right - w->left + 1);
screen_width = min(screen_width, sizeof(str)); screen_width = min(screen_width, sizeof(str));
switch (w->length) { /* actually, direction... */ switch (w->length) { /* actually, direction... */
/* FIXED: Horz scrollers don't show the
* last letter in the string... (1-off error?)
*/
case 'm': // Marquee case 'm': // Marquee
length = strlen(w->text); length = strlen(w->text);
if (length <= screen_width) { if (length <= screen_width) {
@@ -487,37 +574,22 @@ render_frame(LinkedList *list,
break; break;
} }
} }
break;
case WID_FRAME:
{
/* FIXME: doesn't handle nested frames quite right!
* doesn't handle scrolling in nested frames at all...
*/
int new_left = left + w->left - 1;
int new_top = top + w->top - 1;
int new_right = min(left + w->right, right);
int new_bottom = min(top + w->bottom, bottom);
if ((new_left < right) && (new_top < bottom)) /* Render only if it's visible... */
render_frame(w->frame_screen->widgetlist, w->length, new_left, new_top,
new_right, new_bottom, w->width, w->height, w->speed, timer);
}
break;
case WID_NUM: /* FIXME: doesn't work in frames... */
/* NOTE: y=10 means COLON (:) */
if ((w->x > 0) && (w->y >= 0) && (w->y <= 10)) {
drivers_num(w->x + left, w->y);
}
break;
case WID_NONE:
default:
break;
}
} while (LL_Next(list) == 0);
return 0; return 0;
} }
static int render_num(Widget *w, int left, int top, int right, int bottom)
{
debug(RPT_DEBUG, "%s(w=%p, left=%d, top=%d, right=%d, bottom=%d)",
__FUNCTION__, w, left, top, right, bottom);
/* NOTE: y=10 means COLON (:) */
if ((w != NULL) && (w->x > 0) && (w->y >= 0) && (w->y <= 10)) {
drivers_num(w->x + left, w->y);
}
}
int int
server_msg(const char *text, int expire) server_msg(const char *text, int expire)
{ {