refactor rendering engine
This commit is contained in:
+354
-282
@@ -51,7 +51,14 @@ int server_msg_expire = 0;
|
||||
#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
|
||||
render_screen(Screen *s, long timer)
|
||||
@@ -113,9 +120,9 @@ render_screen(Screen *s, long timer)
|
||||
drivers_output(output_state);
|
||||
|
||||
/* Draw a frame... */
|
||||
render_frame(s->widgetlist, 'v', 0, 0,
|
||||
render_frame(s->widgetlist, 0, 0,
|
||||
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 */
|
||||
drivers_cursor(s->cursor_x, s->cursor_y, s->cursor);
|
||||
@@ -157,24 +164,23 @@ render_screen(Screen *s, long timer)
|
||||
/* */
|
||||
static int
|
||||
render_frame(LinkedList *list,
|
||||
char fscroll, /* direction of scrolling */
|
||||
int left, /* left edge of frame */
|
||||
int top, /* top edge of frame */
|
||||
int right, /* right edge of frame */
|
||||
int bottom, /* bottom edge of frame */
|
||||
int fwid, /* frame width? */
|
||||
int fhgt, /* frame height? */
|
||||
char fscroll, /* direction of scrolling */
|
||||
int fspeed, /* speed of scrolling... */
|
||||
long timer) /* current timer tick */
|
||||
{
|
||||
int vis_width = right - left; /* width of visible frame area */
|
||||
int vis_height = bottom - top; /* height of visible frame area */
|
||||
int /*fx = 0,*/ fy = 0; /* Scrolling offset for the frame... */
|
||||
int fy = 0; /* Scrolling offset for the frame... */
|
||||
|
||||
debug(RPT_DEBUG, "%s(list=%p, fscroll='%c', left=%d, top=%d, "
|
||||
"right=%d, bottom=%d, fwid=%d, fhgt=%d, fspeed=%d, timer=%ld)",
|
||||
__FUNCTION__, list, fscroll, left,top, right, bottom,
|
||||
fwid, fhgt, fspeed, timer);
|
||||
debug(RPT_DEBUG, "%s(list=%p, left=%d, top=%d, "
|
||||
"right=%d, bottom=%d, fwid=%d, fhgt=%d, "
|
||||
"fscroll='%c', fspeed=%d, timer=%ld)",
|
||||
__FUNCTION__, list, left, top, right, bottom,
|
||||
fwid, fhgt, fscroll, fspeed, timer);
|
||||
|
||||
/* return on no data or illegal height */
|
||||
if ((list == NULL) || (fhgt <= 0))
|
||||
@@ -182,14 +188,16 @@ render_frame(LinkedList *list,
|
||||
|
||||
if (fscroll == 'v') { /* vertical scrolling */
|
||||
// only set offset !=0 when fspeed is != 0 and there is something to scroll
|
||||
if (fspeed && (fhgt > vis_height)) {
|
||||
int fy_max = fhgt - vis_height + 1;
|
||||
if ((fspeed != 0) && (fhgt > bottom - top)) {
|
||||
int fy_max = fhgt - (bottom - top) + 1;
|
||||
|
||||
fy = (fspeed > 0)
|
||||
? (timer / fspeed) % fy_max
|
||||
: (-fspeed * timer) % fy_max;
|
||||
|
||||
fy = max(fy, 0); // safeguard against negative values
|
||||
|
||||
debug(RPT_DEBUG, "%s: fy=%d", __FUNCTION__, fy);
|
||||
}
|
||||
}
|
||||
else if (fscroll == 'h') { /* horizontal scrolling */
|
||||
@@ -201,7 +209,6 @@ render_frame(LinkedList *list,
|
||||
|
||||
/* loop over all widgets */
|
||||
do {
|
||||
char str[BUFSIZE]; /* scratch buffer */
|
||||
Widget *w = (Widget *) LL_Get(list);
|
||||
|
||||
if (w == NULL)
|
||||
@@ -210,283 +217,22 @@ render_frame(LinkedList *list,
|
||||
/* TODO: Make this cleaner and more flexible! */
|
||||
switch (w->type) {
|
||||
case WID_STRING:
|
||||
if ((w->x > 0) && (w->y > 0) && (w->text) &&
|
||||
(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);
|
||||
}
|
||||
render_string(w, left, top - fy, right, bottom, fy);
|
||||
break;
|
||||
case WID_HBAR:
|
||||
if ((w->x > 0) && (w->y > 0) &&
|
||||
(w->y <= vis_height + fy) && (w->y > fy)) {
|
||||
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 promille = (long) 1000 * w->length / (display_props->cellwidth * full_len);
|
||||
drivers_hbar(w->x + left, w->y + top - fy, full_len, promille, BAR_PATTERN_FILLED);
|
||||
}
|
||||
else {
|
||||
/*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 */
|
||||
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) {
|
||||
/* TODO: Rearrange stuff to get left-extending
|
||||
* hbars to draw correctly...
|
||||
* .. er, this'll require driver modifications,
|
||||
* so I'll leave it out for now.
|
||||
*/
|
||||
}
|
||||
}
|
||||
render_hbar(w, left, top - fy, right, bottom, fy);
|
||||
break;
|
||||
case WID_VBAR: /* FIXME: Vbars don't work in frames! */
|
||||
if ((w->x > 0) && (w->y > 0)) {
|
||||
if (w->length > 0) {
|
||||
/* Improvised len and promille while we have the old widget language */
|
||||
int full_len = display_props->height;
|
||||
int promille = (long) 1000 * w->length / display_props->cellheight / full_len;
|
||||
drivers_vbar(w->x, display_props->height, full_len, promille, BAR_PATTERN_FILLED);
|
||||
}
|
||||
else if (w->length < 0) {
|
||||
/* TODO: Rearrange stuff to get down-extending
|
||||
* vbars to draw correctly...
|
||||
* .. er, this'll require driver modifications,
|
||||
* so I'll leave it out for now.
|
||||
*/
|
||||
}
|
||||
}
|
||||
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... */
|
||||
if ((w->text != NULL) && (vis_width >= 8)) {
|
||||
int length = strlen(w->text);
|
||||
int x;
|
||||
|
||||
drivers_icon(w->x + left, w->y + top, ICON_BLOCK_FILLED);
|
||||
drivers_icon(w->x + left + 1, w->y + top, ICON_BLOCK_FILLED);
|
||||
|
||||
length = min(length, sizeof(str));
|
||||
if (length <= vis_width - 6) {
|
||||
strncpy(str, w->text, length);
|
||||
str[length] = '\0';
|
||||
|
||||
x = length + 4;
|
||||
}
|
||||
else { /* Scroll the title, if it doesn't fit... */
|
||||
int speed = 1;
|
||||
int offset = timer / speed;
|
||||
int reverse = offset / length;
|
||||
|
||||
offset %= length;
|
||||
offset = max(offset, 0);
|
||||
if (offset > length - (vis_width - 6))
|
||||
offset = length - (vis_width - 6);
|
||||
|
||||
if (reverse & 1) /* Scrolling backwards... */
|
||||
offset = (length - (vis_width - 6)) - offset;
|
||||
length = abs(vis_width - 6);
|
||||
length = min(length, sizeof(str));
|
||||
strncpy(str, w->text + offset, length);
|
||||
str[length] = '\0';
|
||||
|
||||
x = vis_width - 2;
|
||||
}
|
||||
|
||||
drivers_string(w->x + 3 + left, w->y + top, str);
|
||||
|
||||
for ( ; x < vis_width; x++) {
|
||||
drivers_icon(w->x + x + left, w->y + top, ICON_BLOCK_FILLED);
|
||||
}
|
||||
}
|
||||
render_title(w, left, top, right, bottom, timer);
|
||||
break;
|
||||
case WID_SCROLLER: /* FIXME: doesn't work in frames... */
|
||||
if ((w->text != NULL) && (w->right >= w->left)) {
|
||||
int length;
|
||||
int offset;
|
||||
int screen_width;
|
||||
|
||||
/*debug(RPT_DEBUG, "%s: %s %d",__FUNCTION__,w->text,timer);*/
|
||||
screen_width = abs(w->right - w->left + 1);
|
||||
screen_width = min(screen_width, sizeof(str));
|
||||
switch (w->length) { /* actually, direction... */
|
||||
/* FIXED: Horz scrollers don't show the
|
||||
* last letter in the string... (1-off error?)
|
||||
*/
|
||||
case 'm': // Marquee
|
||||
length = strlen(w->text);
|
||||
if (length <= screen_width) {
|
||||
/* it fits within the box, just render it */
|
||||
drivers_string(w->left, w->top, w->text);
|
||||
}
|
||||
else {
|
||||
int necessaryTimeUnits = 0;
|
||||
|
||||
if (w->speed > 0) {
|
||||
necessaryTimeUnits = length * w->speed;
|
||||
offset = (timer % (length * w->speed)) / w->speed;
|
||||
}
|
||||
else if (w->speed < 0) {
|
||||
necessaryTimeUnits = length / (w->speed * -1);
|
||||
offset = (timer % (length / (w->speed * -1))) * w->speed * -1;
|
||||
}
|
||||
else {
|
||||
offset = 0;
|
||||
}
|
||||
if (offset <= length) {
|
||||
int room = screen_width - (length - offset);
|
||||
|
||||
strncpy(str, &w->text[offset], screen_width);
|
||||
|
||||
// if there's more room, restart at the beginning
|
||||
if (room > 0) {
|
||||
strncat(str, w->text, room);
|
||||
}
|
||||
|
||||
str[screen_width] = '\0';
|
||||
|
||||
/*debug(RPT_DEBUG, "scroller %s : %d", str, length-offset);*/
|
||||
}
|
||||
else {
|
||||
str[0] = '\0';
|
||||
}
|
||||
drivers_string(w->left, w->top, str);
|
||||
}
|
||||
break;
|
||||
case 'h':
|
||||
length = strlen(w->text) + 1;
|
||||
if (length <= screen_width) {
|
||||
/* it fits within the box, just render it */
|
||||
drivers_string(w->left, w->top, w->text);
|
||||
}
|
||||
else {
|
||||
int effLength = length - screen_width;
|
||||
int necessaryTimeUnits = 0;
|
||||
|
||||
if (w->speed > 0) {
|
||||
necessaryTimeUnits = effLength * w->speed;
|
||||
if (((timer / (effLength * w->speed)) % 2) == 0) {
|
||||
/* wiggle one way */
|
||||
offset = (timer % (effLength * w->speed))
|
||||
/ w->speed;
|
||||
}
|
||||
else {
|
||||
/* wiggle the other */
|
||||
offset = (((timer % (effLength * w->speed))
|
||||
- (effLength * w->speed) + 1)
|
||||
/ w->speed) * -1;
|
||||
}
|
||||
}
|
||||
else if (w->speed < 0) {
|
||||
necessaryTimeUnits = effLength / (w->speed * -1);
|
||||
if (((timer / (effLength / (w->speed * -1))) % 2) == 0) {
|
||||
offset = (timer % (effLength / (w->speed * -1)))
|
||||
* w->speed * -1;
|
||||
}
|
||||
else {
|
||||
offset = (((timer % (effLength / (w->speed * -1)))
|
||||
* w->speed * -1)
|
||||
- effLength + 1) * -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
offset = 0;
|
||||
}
|
||||
if (offset <= length) {
|
||||
strncpy(str, &((w->text)[offset]), screen_width);
|
||||
str[screen_width] = '\0';
|
||||
/*debug(RPT_DEBUG, "scroller %s : %d", str, length-offset); */
|
||||
}
|
||||
else {
|
||||
str[0] = '\0';
|
||||
}
|
||||
drivers_string(w->left, w->top, str);
|
||||
}
|
||||
break;
|
||||
/* FIXME: Vert scrollers don't always seem to scroll */
|
||||
/* back up after hitting the bottom. They jump back to */
|
||||
/* the top instead... (nevermind?) */
|
||||
case 'v':
|
||||
length = strlen(w->text);
|
||||
if (length <= screen_width) {
|
||||
/* no scrolling required... */
|
||||
drivers_string(w->left, w->top, w->text);
|
||||
}
|
||||
else {
|
||||
int lines_required = (length / screen_width)
|
||||
+ (length % screen_width ? 1 : 0);
|
||||
int available_lines = (w->bottom - w->top + 1);
|
||||
|
||||
if (lines_required <= available_lines) {
|
||||
/* easy... */
|
||||
int i;
|
||||
|
||||
for (i = 0; i < lines_required; i++) {
|
||||
strncpy(str, &((w->text)[i * screen_width]), screen_width);
|
||||
str[screen_width] = '\0';
|
||||
drivers_string(w->left, w->top + i, str);
|
||||
}
|
||||
}
|
||||
else {
|
||||
int necessaryTimeUnits = 0;
|
||||
int effLines = lines_required - available_lines + 1;
|
||||
int begin = 0;
|
||||
int i = 0;
|
||||
|
||||
/*debug(RPT_DEBUG, "length: %d sw: %d lines req: %d avail lines: %d effLines: %d ",length,screen_width,lines_required,available_lines,effLines);*/
|
||||
if (w->speed > 0) {
|
||||
necessaryTimeUnits = effLines * w->speed;
|
||||
if (((timer / (effLines * w->speed)) % 2) == 0) {
|
||||
/*debug(RPT_DEBUG, "up ");*/
|
||||
begin = (timer % (effLines * w->speed))
|
||||
/ w->speed;
|
||||
}
|
||||
else {
|
||||
/*debug(RPT_DEBUG, "down ");*/
|
||||
begin = (((timer % (effLines * w->speed))
|
||||
- (effLines * w->speed) + 1) / w->speed)
|
||||
* -1;
|
||||
}
|
||||
}
|
||||
else if (w->speed < 0) {
|
||||
necessaryTimeUnits = effLines / (w->speed * -1);
|
||||
if (((timer / (effLines / (w->speed * -1))) % 2) == 0) {
|
||||
begin = (timer % (effLines / (w->speed * -1)))
|
||||
* w->speed * -1;
|
||||
}
|
||||
else {
|
||||
begin = (((timer % (effLines / (w->speed * -1)))
|
||||
* w->speed * -1) - effLines + 1)
|
||||
* -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
begin = 0;
|
||||
}
|
||||
/*debug(RPT_DEBUG, "rendering begin: %d timer: %d effLines: %d",begin,timer,effLines); */
|
||||
for (i = begin; i < begin + available_lines; i++) {
|
||||
strncpy(str, &((w->text)[i * (screen_width)]), screen_width);
|
||||
str[screen_width] = '\0';
|
||||
/*debug(RPT_DEBUG, "rendering: '%s' of %s", */
|
||||
/*str,w->text); */
|
||||
drivers_string(w->left, w->top + (i - begin), str);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
render_scroller(w, left, top, right, bottom, timer);
|
||||
break;
|
||||
case WID_FRAME:
|
||||
{
|
||||
@@ -499,8 +245,9 @@ render_frame(LinkedList *list,
|
||||
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);
|
||||
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... */
|
||||
@@ -518,6 +265,331 @@ render_frame(LinkedList *list,
|
||||
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) {
|
||||
int full_len = display_props->width - w->x - left + 1;
|
||||
int promille = 1000;
|
||||
|
||||
if ((w->length / display_props->cellwidth) < right - left - w->x + 1)
|
||||
promille = (long) 1000 * w->length / (display_props->cellwidth * full_len);
|
||||
|
||||
drivers_hbar(w->x + left, w->y + top, full_len, promille, BAR_PATTERN_FILLED);
|
||||
}
|
||||
else if (w->length < 0) {
|
||||
/* TODO: Rearrange stuff to get left-extending
|
||||
* hbars to draw correctly...
|
||||
* .. er, this'll require driver modifications,
|
||||
* so I'll leave it out for now.
|
||||
*/
|
||||
}
|
||||
}
|
||||
return 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) {
|
||||
int full_len = display_props->height;
|
||||
int promille = (long) 1000 * w->length / display_props->cellheight / full_len;
|
||||
|
||||
drivers_vbar(w->x, display_props->height, full_len, promille, BAR_PATTERN_FILLED);
|
||||
}
|
||||
else if (w->length < 0) {
|
||||
/* TODO: Rearrange stuff to get down-extending
|
||||
* vbars to draw correctly...
|
||||
* .. er, this'll require driver modifications,
|
||||
* so I'll leave it out for now.
|
||||
*/
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
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 x;
|
||||
|
||||
drivers_icon(w->x + left, w->y + top, ICON_BLOCK_FILLED);
|
||||
drivers_icon(w->x + left + 1, w->y + top, ICON_BLOCK_FILLED);
|
||||
|
||||
length = min(length, sizeof(str));
|
||||
if (length <= vis_width - 6) {
|
||||
strncpy(str, w->text, length);
|
||||
str[length] = '\0';
|
||||
|
||||
x = length + 4;
|
||||
}
|
||||
else { /* Scroll the title, if it doesn't fit... */
|
||||
int speed = 1;
|
||||
int offset = timer / speed;
|
||||
int reverse = offset / length;
|
||||
|
||||
offset %= length;
|
||||
offset = max(offset, 0);
|
||||
if (offset > length - (vis_width - 6))
|
||||
offset = length - (vis_width - 6);
|
||||
|
||||
if (reverse & 1) /* Scrolling backwards... */
|
||||
offset = (length - (vis_width - 6)) - offset;
|
||||
length = abs(vis_width - 6);
|
||||
length = min(length, sizeof(str));
|
||||
strncpy(str, w->text + offset, length);
|
||||
str[length] = '\0';
|
||||
|
||||
x = vis_width - 2;
|
||||
}
|
||||
|
||||
drivers_string(w->x + 3 + left, w->y + top, str);
|
||||
|
||||
for ( ; x < vis_width; x++) {
|
||||
drivers_icon(w->x + x + left, w->y + top, ICON_BLOCK_FILLED);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
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)) {
|
||||
char str[BUFSIZE];
|
||||
int length;
|
||||
int offset;
|
||||
int screen_width;
|
||||
|
||||
/*debug(RPT_DEBUG, "%s: %s %d",__FUNCTION__,w->text,timer);*/
|
||||
screen_width = abs(w->right - w->left + 1);
|
||||
screen_width = min(screen_width, sizeof(str));
|
||||
|
||||
switch (w->length) { /* actually, direction... */
|
||||
case 'm': // Marquee
|
||||
length = strlen(w->text);
|
||||
if (length <= screen_width) {
|
||||
/* it fits within the box, just render it */
|
||||
drivers_string(w->left, w->top, w->text);
|
||||
}
|
||||
else {
|
||||
int necessaryTimeUnits = 0;
|
||||
|
||||
if (w->speed > 0) {
|
||||
necessaryTimeUnits = length * w->speed;
|
||||
offset = (timer % (length * w->speed)) / w->speed;
|
||||
}
|
||||
else if (w->speed < 0) {
|
||||
necessaryTimeUnits = length / (w->speed * -1);
|
||||
offset = (timer % (length / (w->speed * -1))) * w->speed * -1;
|
||||
}
|
||||
else {
|
||||
offset = 0;
|
||||
}
|
||||
if (offset <= length) {
|
||||
int room = screen_width - (length - offset);
|
||||
|
||||
strncpy(str, &w->text[offset], screen_width);
|
||||
|
||||
// if there's more room, restart at the beginning
|
||||
if (room > 0) {
|
||||
strncat(str, w->text, room);
|
||||
}
|
||||
|
||||
str[screen_width] = '\0';
|
||||
|
||||
/*debug(RPT_DEBUG, "scroller %s : %d", str, length-offset);*/
|
||||
}
|
||||
else {
|
||||
str[0] = '\0';
|
||||
}
|
||||
drivers_string(w->left, w->top, str);
|
||||
}
|
||||
break;
|
||||
case 'h':
|
||||
length = strlen(w->text) + 1;
|
||||
if (length <= screen_width) {
|
||||
/* it fits within the box, just render it */
|
||||
drivers_string(w->left, w->top, w->text);
|
||||
}
|
||||
else {
|
||||
int effLength = length - screen_width;
|
||||
int necessaryTimeUnits = 0;
|
||||
|
||||
if (w->speed > 0) {
|
||||
necessaryTimeUnits = effLength * w->speed;
|
||||
if (((timer / (effLength * w->speed)) % 2) == 0) {
|
||||
/* wiggle one way */
|
||||
offset = (timer % (effLength * w->speed))
|
||||
/ w->speed;
|
||||
}
|
||||
else {
|
||||
/* wiggle the other */
|
||||
offset = (((timer % (effLength * w->speed))
|
||||
- (effLength * w->speed) + 1)
|
||||
/ w->speed) * -1;
|
||||
}
|
||||
}
|
||||
else if (w->speed < 0) {
|
||||
necessaryTimeUnits = effLength / (w->speed * -1);
|
||||
if (((timer / (effLength / (w->speed * -1))) % 2) == 0) {
|
||||
offset = (timer % (effLength / (w->speed * -1)))
|
||||
* w->speed * -1;
|
||||
}
|
||||
else {
|
||||
offset = (((timer % (effLength / (w->speed * -1)))
|
||||
* w->speed * -1)
|
||||
- effLength + 1) * -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
offset = 0;
|
||||
}
|
||||
if (offset <= length) {
|
||||
strncpy(str, &((w->text)[offset]), screen_width);
|
||||
str[screen_width] = '\0';
|
||||
/*debug(RPT_DEBUG, "scroller %s : %d", str, length-offset); */
|
||||
}
|
||||
else {
|
||||
str[0] = '\0';
|
||||
}
|
||||
drivers_string(w->left, w->top, str);
|
||||
}
|
||||
break;
|
||||
/* FIXME: Vert scrollers don't always seem to scroll */
|
||||
/* back up after hitting the bottom. They jump back to */
|
||||
/* the top instead... (nevermind?) */
|
||||
case 'v':
|
||||
length = strlen(w->text);
|
||||
if (length <= screen_width) {
|
||||
/* no scrolling required... */
|
||||
drivers_string(w->left, w->top, w->text);
|
||||
}
|
||||
else {
|
||||
int lines_required = (length / screen_width)
|
||||
+ (length % screen_width ? 1 : 0);
|
||||
int available_lines = (w->bottom - w->top + 1);
|
||||
|
||||
if (lines_required <= available_lines) {
|
||||
/* easy... */
|
||||
int i;
|
||||
|
||||
for (i = 0; i < lines_required; i++) {
|
||||
strncpy(str, &((w->text)[i * screen_width]), screen_width);
|
||||
str[screen_width] = '\0';
|
||||
drivers_string(w->left, w->top + i, str);
|
||||
}
|
||||
}
|
||||
else {
|
||||
int necessaryTimeUnits = 0;
|
||||
int effLines = lines_required - available_lines + 1;
|
||||
int begin = 0;
|
||||
int i = 0;
|
||||
|
||||
/*debug(RPT_DEBUG, "length: %d sw: %d lines req: %d avail lines: %d effLines: %d ",length,screen_width,lines_required,available_lines,effLines);*/
|
||||
if (w->speed > 0) {
|
||||
necessaryTimeUnits = effLines * w->speed;
|
||||
if (((timer / (effLines * w->speed)) % 2) == 0) {
|
||||
/*debug(RPT_DEBUG, "up ");*/
|
||||
begin = (timer % (effLines * w->speed))
|
||||
/ w->speed;
|
||||
}
|
||||
else {
|
||||
/*debug(RPT_DEBUG, "down ");*/
|
||||
begin = (((timer % (effLines * w->speed))
|
||||
- (effLines * w->speed) + 1) / w->speed)
|
||||
* -1;
|
||||
}
|
||||
}
|
||||
else if (w->speed < 0) {
|
||||
necessaryTimeUnits = effLines / (w->speed * -1);
|
||||
if (((timer / (effLines / (w->speed * -1))) % 2) == 0) {
|
||||
begin = (timer % (effLines / (w->speed * -1)))
|
||||
* w->speed * -1;
|
||||
}
|
||||
else {
|
||||
begin = (((timer % (effLines / (w->speed * -1)))
|
||||
* w->speed * -1) - effLines + 1)
|
||||
* -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
begin = 0;
|
||||
}
|
||||
/*debug(RPT_DEBUG, "rendering begin: %d timer: %d effLines: %d",begin,timer,effLines); */
|
||||
for (i = begin; i < begin + available_lines; i++) {
|
||||
strncpy(str, &((w->text)[i * (screen_width)]), screen_width);
|
||||
str[screen_width] = '\0';
|
||||
/*debug(RPT_DEBUG, "rendering: '%s' of %s", */
|
||||
/*str,w->text); */
|
||||
drivers_string(w->left, w->top + (i - begin), str);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
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
|
||||
server_msg(const char *text, int expire)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user