void * LL_GetNext (LinkedList * list) // ... next node { if (!list) return NULL; if (0 > LL_Next (list)) return NULL; return LL_Get (list); }
////////////////////////////////////////////////////////////////////// // Sorts the list, then rewinds it... // int LL_Sort (LinkedList * list, int compare (void *, void *)) { int i, j; // Junk / loop variables int numnodes; // number of nodes in list LL_node *best, *last; // best match and last node in the list LL_node *current; if (!list) return -1; if (!compare) return -1; numnodes = LL_Length (list); // get the number of nodes... if (0 > LL_End (list)) return -1; // Find the last node. last = LL_GetNode (list); if (numnodes < 2) return 0; for (i = numnodes - 1; i > 0; i--) { LL_Rewind (list); // get the first node again best = last; // reset our "best" node for (j = 0; j < i; j++) { current = LL_GetNode (list); // If we found a better match... if (compare (current->data, best->data) > 0) { best = current; // keep track of the "best" match } LL_Next (list); // Go to the next node. } LL_SwapNodes (last, best); // Switch two nodes... if (best) last = best->prev; else return -1; //last = LL_FindPrev(best); // And go backwards by one node. } //return LLFindFirst(current); // return pointer to the first node. LL_Rewind (list); return 0; }
////////////////////////////////////////////////////////////////////// // Removes a specific node... void * LL_Remove (LinkedList * list, void *data) { void *find; if (!list) return NULL; LL_Rewind (list); do { find = LL_Get (list); if (find == data) return LL_DeleteNode (list); } while (LL_Next (list) == 0); return NULL; }
////////////////////////////////////////////////////////////////////// // Searching... // Goes to the list item which matches "value", and returns the // data found there. // // The "compare" function should return 0 for a "match" // // Note that this does *not* rewind the list first! You should do // it yourself if you want to start from the beginning! void * LL_Find (LinkedList * list, int compare (void *, void *), void *value) { void *data; if (!list) return NULL; if (!compare) return NULL; if (!value) return NULL; do { data = LL_Get (list); if (0 == compare (data, value)) return data; } while (LL_Next (list) == 0); return NULL; }
static int render_frame(LinkedList *list, 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 fy = 0; /* Scrolling offset for the frame... */ 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)) return -1; if (fscroll == 'v') { /* vertical scrolling */ // only set offset !=0 when fspeed is != 0 and there is something to scroll 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 */ /* TODO: Frames don't scroll horizontally yet! */ } /* reset widget list */ LL_Rewind(list); /* loop over all widgets */ do { Widget *w = (Widget *) LL_Get(list); if (w == NULL) return -1; /* TODO: Make this cleaner and more flexible! */ switch (w->type) { case WID_STRING: render_string(w, left, top - fy, right, bottom, fy); break; case WID_HBAR: render_hbar(w, left, top - fy, right, bottom, fy); break; case WID_VBAR: /* FIXME: Vbars don't work in frames! */ render_vbar(w, left, top, right, bottom); break; case WID_ICON: /* FIXME: Icons don't work in frames! */ 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: /* FALLTHROUGH */ default: break; } } while (LL_Next(list) == 0); return 0; }