////////////////////////////////////////////////////////////////////// // Add an item to the end of its "priority group" // The list is assumed to be sorted already... int LL_PriorityEnqueue (LinkedList * list, void *add, int compare (void *, void *)) { void *data; int i; if (!list) return -1; if (!add) return -1; if (!compare) return -1; // From the end of the list, keep searching while we're "less than" // the given nodes... LL_End (list); do { data = LL_Get (list); if (data) { i = compare (add, data); if (i >= 0) // If we're in the right place, add it and exit { LL_AddNode (list, add); return 0; } } } while (LL_Prev (list) == 0); // If we're less than *everything*, put it at the beginning LL_Unshift (list, add); return 0; }
void * LL_GetLast (LinkedList * list) // ... last node { if (!list) return NULL; if (0 > LL_End (list)) return NULL; return LL_Get (list); }
void * LL_GetPrev (LinkedList * list) // ... prev node { if (!list) return NULL; if (0 > LL_Prev (list)) return NULL; return LL_Get (list); }
void * LL_GetNext (LinkedList * list) // ... next node { if (!list) return NULL; if (0 > LL_Next (list)) return NULL; return LL_Get (list); }
void * LL_GetFirst (LinkedList * list) // gets data from first node { if (!list) return NULL; if (0 > LL_Rewind (list)) return NULL; return LL_Get (list); }
////////////////////////////////////////////////////////////////////// // 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; }
void input_release_client_keys(Client *client) { KeyReservation *kr; debug(RPT_DEBUG, "%s(client=[%d])", __FUNCTION__, (client?client->sock:-1)); kr=LL_GetFirst(keylist); while (kr) { if (kr->client == client) { report(RPT_INFO, "Key \"%.40s\" was reserved in %s mode by client [%d] and is now released", kr->key, (kr->exclusive?"exclusive":"shared"), (client?client->sock:-1)); free(kr->key); free(kr); LL_DeleteNode(keylist); kr = LL_Get(keylist); } else { kr = LL_GetNext(keylist); } } }
////////////////////////////////////////////////////////////////////// // 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; }