vdr  2.2.0
osdbase.c
Go to the documentation of this file.
1 /*
2  * osdbase.c: Basic interface to the On Screen Display
3  *
4  * See the main source file 'vdr.c' for copyright information and
5  * how to reach the author.
6  *
7  * $Id: osdbase.c 3.3 2015/01/15 10:11:11 kls Exp $
8  */
9 
10 #include "osdbase.h"
11 #include <string.h>
12 #include "device.h"
13 #include "i18n.h"
14 #include "menuitems.h"
15 #include "remote.h"
16 #include "status.h"
17 
18 // --- cOsdItem --------------------------------------------------------------
19 
21 {
22  text = NULL;
23  state = State;
24  selectable = true;
25  fresh = true;
26 }
27 
28 cOsdItem::cOsdItem(const char *Text, eOSState State, bool Selectable)
29 {
30  text = NULL;
31  state = State;
33  fresh = true;
34  SetText(Text);
35 }
36 
38 {
39  free(text);
40 }
41 
42 void cOsdItem::SetText(const char *Text, bool Copy)
43 {
44  free(text);
45  text = Copy ? strdup(Text ? Text : "") : (char *)Text; // text assumes ownership!
46 }
47 
48 void cOsdItem::SetSelectable(bool Selectable)
49 {
51 }
52 
53 void cOsdItem::SetFresh(bool Fresh)
54 {
55  fresh = Fresh;
56 }
57 
58 void cOsdItem::SetMenuItem(cSkinDisplayMenu *DisplayMenu, int Index, bool Current, bool Selectable)
59 {
60  DisplayMenu->SetItem(Text(), Index, Current, Selectable);
61 }
62 
64 {
65  return Key == kOk ? state : osUnknown;
66 }
67 
68 // --- cOsdObject ------------------------------------------------------------
69 
70 void cOsdObject::Show(void)
71 {
72  if (isMenu)
73  ((cOsdMenu *)this)->Display();
74 }
75 
76 // --- cOsdMenu --------------------------------------------------------------
77 
80 
81 cOsdMenu::cOsdMenu(const char *Title, int c0, int c1, int c2, int c3, int c4)
82 {
83  isMenu = true;
84  digit = 0;
85  key_nr = -1;
86  hasHotkeys = false;
87  displayMenuItems = 0;
88  title = NULL;
91  SetTitle(Title);
92  SetCols(c0, c1, c2, c3, c4);
93  first = 0;
94  current = marked = -1;
95  subMenu = NULL;
96  helpRed = helpGreen = helpYellow = helpBlue = NULL;
97  helpDisplayed = false;
98  status = NULL;
99  if (!displayMenuCount++)
100  SetDisplayMenu();
101 }
102 
104 {
105  free(title);
106  delete subMenu;
107  free(status);
108  displayMenu->Clear();
110  if (!--displayMenuCount)
112 }
113 
115 {
116  menuCategory = MenuCategory;
117 }
118 
120 {
121  menuSortMode = MenuSortMode;
122 }
123 
125 {
126  if (displayMenu) {
127  displayMenu->Clear();
128  delete displayMenu;
129  }
131 }
132 
133 const char *cOsdMenu::hk(const char *s)
134 {
135  static cString buffer;
136  if (s && hasHotkeys) {
137  if (digit == 0 && '1' <= *s && *s <= '9' && *(s + 1) == ' ')
138  digit = -1; // prevents automatic hotkeys - input already has them
139  if (digit >= 0) {
140  digit++;
141  buffer = cString::sprintf(" %2d%s %s", digit, (digit > 9) ? "" : " ", s);
142  s = buffer;
143  }
144  }
145  return s;
146 }
147 
148 void cOsdMenu::SetCols(int c0, int c1, int c2, int c3, int c4)
149 {
150  cols[0] = c0;
151  cols[1] = c1;
152  cols[2] = c2;
153  cols[3] = c3;
154  cols[4] = c4;
155 }
156 
157 void cOsdMenu::SetHasHotkeys(bool HasHotkeys)
158 {
159  hasHotkeys = HasHotkeys;
160  digit = 0;
161 }
162 
163 void cOsdMenu::SetStatus(const char *s)
164 {
165  free(status);
166  status = s ? strdup(s) : NULL;
168 }
169 
170 void cOsdMenu::SetTitle(const char *Title)
171 {
172  free(title);
173  title = strdup(Title);
174 }
175 
176 void cOsdMenu::DisplayHelp(bool Force)
177 {
178  if (!helpDisplayed || Force) {
181  helpDisplayed = true;
182  }
183 }
184 
185 void cOsdMenu::SetHelp(const char *Red, const char *Green, const char *Yellow, const char *Blue)
186 {
187  // strings are NOT copied - must be constants!!!
188  helpRed = Red;
189  helpGreen = Green;
190  helpYellow = Yellow;
191  helpBlue = Blue;
192  DisplayHelp(true);
193 }
194 
195 void cOsdMenu::Del(int Index)
196 {
197  cList<cOsdItem>::Del(Get(Index));
198  int count = Count();
199  while (current < count && !SelectableItem(current))
200  current++;
201  if (current == count) {
202  while (current > 0 && !SelectableItem(current))
203  current--;
204  }
205  if (Index == first && first > 0)
206  first--;
207 }
208 
209 void cOsdMenu::Add(cOsdItem *Item, bool Current, cOsdItem *After)
210 {
211  cList<cOsdItem>::Add(Item, After);
212  if (Current)
213  current = Item->Index();
214 }
215 
216 void cOsdMenu::Ins(cOsdItem *Item, bool Current, cOsdItem *Before)
217 {
218  cList<cOsdItem>::Ins(Item, Before);
219  if (Current)
220  current = Item->Index();
221 }
222 
224 {
225  if (subMenu) {
226  subMenu->Display();
227  return;
228  }
230  displayMenu->Clear();
236  displayMenu->SetTabs(cols[0], cols[1], cols[2], cols[3], cols[4]);//XXX
239  DisplayHelp(true);
240  int count = Count();
241  if (count > 0) {
242  int ni = 0;
243  for (cOsdItem *item = First(); item; item = Next(item)) {
244  cStatus::MsgOsdItem(item->Text(), ni++);
245  if (current < 0 && item->Selectable())
246  current = item->Index();
247  }
248  if (current < 0)
249  current = 0; // just for safety - there HAS to be a current item!
250  first = min(first, max(0, count - displayMenuItems)); // in case the menu size has changed
251  if (current - first >= displayMenuItems || current < first) {
253  if (first + displayMenuItems > count)
254  first = count - displayMenuItems;
255  if (first < 0)
256  first = 0;
257  }
258  int i = first;
259  int n = 0;
260  for (cOsdItem *item = Get(first); item; item = Next(item)) {
261  bool CurrentSelectable = (i == current) && item->Selectable();
262  item->SetMenuItem(displayMenu, i - first, CurrentSelectable, item->Selectable());
263  if (CurrentSelectable)
264  cStatus::MsgOsdCurrentItem(item->Text());
265  if (++n == displayMenuItems)
266  break;
267  i++;
268  }
269  }
270  displayMenu->SetScrollbar(count, first);
271  if (!isempty(status))
273 }
274 
276 {
277  current = Item ? Item->Index() : -1;
278 }
279 
281 {
282  cOsdItem *item = Get(current);
283  if (item)
284  item->Set();
285 }
286 
287 void cOsdMenu::DisplayCurrent(bool Current)
288 {
289  cOsdItem *item = Get(current);
290  if (item) {
291  item->SetMenuItem(displayMenu, current - first, Current && item->Selectable(), item->Selectable());
292  if (Current && item->Selectable())
294  if (!Current)
295  item->SetFresh(true); // leaving the current item resets 'fresh'
296  if (cMenuEditItem *MenuEditItem = dynamic_cast<cMenuEditItem *>(item)) {
297  if (!MenuEditItem->DisplayHelp(Current))
298  DisplayHelp();
299  else
300  helpDisplayed = false;
301  }
302  }
303 }
304 
306 {
307  if (Item) {
308  int Index = Item->Index();
309  int Offset = Index - first;
310  if (Offset >= 0 && Offset < first + displayMenuItems) {
311  bool Current = Index == current;
312  Item->SetMenuItem(displayMenu, Offset, Current && Item->Selectable(), Item->Selectable());
313  if (Current && Item->Selectable())
315  }
316  }
317 }
318 
319 void cOsdMenu::Clear(void)
320 {
321  if (marked >= 0)
322  SetStatus(NULL);
323  first = 0;
324  current = marked = -1;
326 }
327 
329 {
330  cOsdItem *item = Get(idx);
331  return item && item->Selectable();
332 }
333 
335 {
336  int tmpCurrent = current;
337  int lastOnScreen = first + displayMenuItems - 1;
338  int last = Count() - 1;
339  if (last < 0)
340  return;
341  while (--tmpCurrent != current) {
342  if (tmpCurrent < 0) {
343  if (first > 0) {
344  // make non-selectable items at the beginning visible:
345  first = 0;
346  Display();
347  return;
348  }
349  if (Setup.MenuScrollWrap)
350  tmpCurrent = last + 1;
351  else
352  return;
353  }
354  else if (SelectableItem(tmpCurrent))
355  break;
356  }
357  if (first <= tmpCurrent && tmpCurrent <= lastOnScreen)
358  DisplayCurrent(false);
359  current = tmpCurrent;
360  if (current < first) {
361  first = Setup.MenuScrollPage ? max(0, current - displayMenuItems + 1) : current;
362  Display();
363  }
364  else if (current > lastOnScreen) {
365  first = max(0, current - displayMenuItems + 1);
366  Display();
367  }
368  else
369  DisplayCurrent(true);
370 }
371 
373 {
374  int tmpCurrent = current;
375  int lastOnScreen = first + displayMenuItems - 1;
376  int last = Count() - 1;
377  if (last < 0)
378  return;
379  while (++tmpCurrent != current) {
380  if (tmpCurrent > last) {
381  if (first < last - displayMenuItems) {
382  // make non-selectable items at the end visible:
383  first = last - displayMenuItems + 1;
384  Display();
385  return;
386  }
387  if (Setup.MenuScrollWrap)
388  tmpCurrent = -1;
389  else
390  return;
391  }
392  else if (SelectableItem(tmpCurrent))
393  break;
394  }
395  if (first <= tmpCurrent && tmpCurrent <= lastOnScreen)
396  DisplayCurrent(false);
397  current = tmpCurrent;
398  if (current > lastOnScreen) {
399  first = Setup.MenuScrollPage ? current : max(0, current - displayMenuItems + 1);
400  if (first + displayMenuItems > last)
401  first = max(0, last - displayMenuItems + 1);
402  Display();
403  }
404  else if (current < first) {
405  first = current;
406  Display();
407  }
408  else
409  DisplayCurrent(true);
410 }
411 
413 {
414  int oldCurrent = current;
415  int oldFirst = first;
418  int last = Count() - 1;
419  if (current < 0)
420  current = 0;
421  if (first < 0)
422  first = 0;
423  int tmpCurrent = current;
424  while (!SelectableItem(tmpCurrent) && --tmpCurrent >= 0)
425  ;
426  if (tmpCurrent < 0) {
427  tmpCurrent = current;
428  while (++tmpCurrent <= last && !SelectableItem(tmpCurrent))
429  ;
430  }
431  current = tmpCurrent <= last ? tmpCurrent : -1;
432  if (current >= 0) {
433  if (current < first)
434  first = current;
435  else if (current - first >= displayMenuItems)
437  }
438  if (current != oldCurrent || first != oldFirst) {
439  Display();
440  DisplayCurrent(true);
441  }
442  else if (Setup.MenuScrollWrap)
443  CursorUp();
444 }
445 
447 {
448  int oldCurrent = current;
449  int oldFirst = first;
452  int last = Count() - 1;
453  if (current > last)
454  current = last;
455  if (first + displayMenuItems > last)
456  first = max(0, last - displayMenuItems + 1);
457  int tmpCurrent = current;
458  while (!SelectableItem(tmpCurrent) && ++tmpCurrent <= last)
459  ;
460  if (tmpCurrent > last) {
461  tmpCurrent = current;
462  while (--tmpCurrent >= 0 && !SelectableItem(tmpCurrent))
463  ;
464  }
465  current = tmpCurrent > 0 ? tmpCurrent : -1;
466  if (current >= 0) {
467  if (current < first)
468  first = current;
469  else if (current - first >= displayMenuItems)
471  }
472  if (current != oldCurrent || first != oldFirst) {
473  Display();
474  DisplayCurrent(true);
475  }
476  else if (Setup.MenuScrollWrap)
477  CursorDown();
478 }
479 
480 void cOsdMenu::Mark(void)
481 {
482  if (Count() && marked < 0) {
483  marked = current;
484  SetStatus(tr("Up/Dn for new location - OK to move"));
485  }
486 }
487 
488 #define MENUKEY_TIMEOUT 1500
489 
491 {
492  bool match = false;
493  bool highlight = false;
494  int item_nr;
495  int i;
496 
497  if (Key == kNone) {
498  if (lastActivity.TimedOut())
499  Key = kOk;
500  else
501  return osContinue;
502  }
503  else
505  for (cOsdItem *item = Last(); item; item = Prev(item)) {
506  const char *s = item->Text();
507  i = 0;
508  item_nr = 0;
509  if (s && (s = skipspace(s)) != '\0' && '0' <= s[i] && s[i] <= '9') {
510  do {
511  item_nr = item_nr * 10 + (s[i] - '0');
512  }
513  while ( !((s[++i] == '\t')||(s[i] == ' ')) && (s[i] != '\0') && ('0' <= s[i]) && (s[i] <= '9'));
514  if ((Key == kOk) && (item_nr == key_nr)) {
515  current = item->Index();
516  RefreshCurrent();
517  Display();
518  cRemote::Put(kOk, true);
519  key_nr = -1;
520  break;
521  }
522  else if (Key != kOk) {
523  if (!highlight && (item_nr == (Key - k0))) {
524  highlight = true;
525  current = item->Index();
526  }
527  if (!match && (key_nr == -1) && ((item_nr / 10) == (Key - k0))) {
528  match = true;
529  key_nr = (Key - k0);
530  }
531  else if (((key_nr == -1) && (item_nr == (Key - k0))) || (!match && (key_nr >= 0) && (item_nr == (10 * key_nr + Key - k0)))) {
532  current = item->Index();
533  cRemote::Put(kOk, true);
534  key_nr = -1;
535  break;
536  }
537  }
538  }
539  }
540  if ((!match) && (Key != kNone))
541  key_nr = -1;
542  return osContinue;
543 }
544 
546 {
547  delete subMenu;
548  subMenu = SubMenu;
549  subMenu->Display();
550  return osContinue; // convenience return value
551 }
552 
554 {
555  delete subMenu;
556  subMenu = NULL;
557  if (ReDisplay) {
558  RefreshCurrent();
559  Display();
560  }
561  return osContinue; // convenience return value
562 }
563 
565 {
566  if (subMenu) {
567  eOSState state = subMenu->ProcessKey(Key);
568  if (state == osBack)
569  return CloseSubMenu();
570  return state;
571  }
572 
573  cOsdItem *item = Get(current);
574  if (marked < 0 && item) {
575  eOSState state = item->ProcessKey(Key);
576  if (state != osUnknown) {
577  DisplayCurrent(true);
578  return state;
579  }
580  }
581  switch (int(Key)) {
582  case kNone:
583  case k0...k9: return hasHotkeys ? HotKey(Key) : osUnknown;
584  case kUp|k_Repeat:
585  case kUp: CursorUp(); break;
586  case kDown|k_Repeat:
587  case kDown: CursorDown(); break;
588  case kLeft|k_Repeat:
589  case kLeft: PageUp(); break;
590  case kRight|k_Repeat:
591  case kRight: PageDown(); break;
592  case kBack: return osBack;
593  case kOk: if (marked >= 0) {
594  SetStatus(NULL);
595  if (marked != current)
596  Move(marked, current);
597  marked = -1;
598  break;
599  }
600  // else run into default
601  default: if (marked < 0)
602  return osUnknown;
603  }
604  return osContinue;
605 }
virtual ~cOsdMenu()
Definition: osdbase.c:103
void SetStatus(const char *s)
Definition: osdbase.c:163
void DisplayItem(cOsdItem *Item)
Definition: osdbase.c:305
static void MsgOsdCurrentItem(const char *Text)
Definition: status.c:110
virtual void Del(int Index)
Definition: osdbase.c:195
bool isempty(const char *s)
Definition: tools.c:297
const char * helpGreen
Definition: osdbase.h:97
int Index(void) const
Definition: tools.c:1989
void Set(int Ms=0)
Definition: tools.c:738
const char * helpBlue
Definition: osdbase.h:97
int key_nr
Definition: osdbase.h:102
Definition: keys.h:23
void Add(cOsdItem *Item, bool Current=false, cOsdItem *After=NULL)
Definition: osdbase.c:209
cOsdItem(eOSState State=osUnknown)
Definition: osdbase.c:20
void Add(cListObject *Object, cListObject *After=NULL)
Definition: tools.c:2014
eMenuCategory menuCategory
Definition: osdbase.h:94
bool hasHotkeys
Definition: osdbase.h:101
cOsdMenu * subMenu
Definition: osdbase.h:96
static cString sprintf(const char *fmt,...) __attribute__((format(printf
Definition: tools.c:1080
Definition: keys.h:17
virtual void SetMessage(eMessageType Type, const char *Text)=0
Sets a one line message Text, with the given Type.
Definition: keys.h:61
int displayMenuItems
Definition: osdbase.h:90
cOsdMenu * SubMenu(void)
Definition: osdbase.h:127
virtual void Clear(void)
Definition: osdbase.c:319
cOsdItem * Get(int Index) const
Definition: tools.h:491
virtual void SetScrollbar(int Total, int Offset)
Sets the Total number of items in the currently displayed list, and the Offset of the first item that...
Definition: skins.c:133
eMenuCategory MenuCategory(void) const
Returns the menu category, set by a previous call to SetMenuCategory().
Definition: skins.h:165
eOSState HotKey(eKeys Key)
Definition: osdbase.c:490
void RefreshCurrent(void)
Definition: osdbase.c:280
T max(T a, T b)
Definition: tools.h:55
bool selectable
Definition: osdbase.h:53
void PageUp(void)
Definition: osdbase.c:412
virtual cSkinDisplayMenu * DisplayMenu(void)=0
Creates and returns a new object for displaying a menu.
bool fresh
Definition: osdbase.h:55
void SetFresh(bool Fresh)
Definition: osdbase.c:53
void SetDisplayMenu(void)
Definition: osdbase.c:124
int Current(void) const
Definition: osdbase.h:138
int Count(void) const
Definition: tools.h:485
T min(T a, T b)
Definition: tools.h:54
#define MENUKEY_TIMEOUT
Definition: osdbase.c:488
static void MsgOsdHelpKeys(const char *Red, const char *Green, const char *Yellow, const char *Blue)
Definition: status.c:98
virtual void SetItem(const char *Text, int Index, bool Current, bool Selectable)=0
Sets the item at the given Index to Text.
cTimeMs lastActivity
Definition: osdbase.h:103
virtual void Clear(void)
Definition: tools.c:2087
Definition: keys.h:55
int marked
Definition: osdbase.h:93
cOsdItem * Last(void) const
Definition: tools.h:493
static cSkinDisplayMenu * displayMenu
Definition: osdbase.h:88
char * status
Definition: osdbase.h:99
eOSState
Definition: osdbase.h:18
const char * Text(void) const
Definition: osdbase.h:64
virtual void SetTabs(int Tab1, int Tab2=0, int Tab3=0, int Tab4=0, int Tab5=0)
Sets the tab columns to the given values, which are the number of characters in each column...
Definition: skins.c:95
void SetHasHotkeys(bool HasHotkeys=true)
Definition: osdbase.c:157
bool Selectable(void) const
Definition: osdbase.h:60
virtual eOSState ProcessKey(eKeys Key)
Definition: osdbase.c:564
void PageDown(void)
Definition: osdbase.c:446
void Ins(cOsdItem *Item, bool Current=false, cOsdItem *Before=NULL)
Definition: osdbase.c:216
cOsdItem * Next(const cOsdItem *object) const
Definition: tools.h:495
void SetCols(int c0, int c1=0, int c2=0, int c3=0, int c4=0)
Definition: osdbase.c:148
virtual void SetMenuSortMode(eMenuSortMode MenuSortMode)
Sets the mode by which the items in this menu are sorted.
Definition: skins.h:178
void SetMenuCategory(eMenuCategory MenuCategory)
Definition: osdbase.c:114
static void MsgOsdTitle(const char *Title)
Definition: status.c:86
bool TimedOut(void) const
Definition: tools.c:743
void CursorDown(void)
Definition: osdbase.c:372
char * title
Definition: osdbase.h:91
cOsdMenu(const char *Title, int c0=0, int c1=0, int c2=0, int c3=0, int c4=0)
Definition: osdbase.c:81
void SetText(const char *Text, bool Copy=true)
Definition: osdbase.c:42
void SetSelectable(bool Selectable)
Definition: osdbase.c:48
Definition: keys.h:18
const char * helpYellow
Definition: osdbase.h:97
void Ins(cListObject *Object, cListObject *Before=NULL)
Definition: tools.c:2030
virtual ~cOsdItem()
Definition: osdbase.c:37
virtual void Display(void)
Definition: osdbase.c:223
cSetup Setup
Definition: config.c:372
bool Put(uint64_t Code, bool Repeat=false, bool Release=false)
Definition: remote.c:124
Definition: keys.h:20
void Mark(void)
Definition: osdbase.c:480
int digit
Definition: osdbase.h:100
static int displayMenuCount
Definition: osdbase.h:89
int current
Definition: osdbase.h:93
eMenuSortMode menuSortMode
Definition: osdbase.h:95
Definition: skins.h:24
virtual eOSState ProcessKey(eKeys Key)
Definition: osdbase.c:63
virtual void Show(void)
Definition: osdbase.c:70
void DisplayHelp(bool Force=false)
Definition: osdbase.c:176
int first
Definition: osdbase.h:93
Definition: keys.h:21
void SetCurrent(cOsdItem *Item)
Definition: osdbase.c:275
void DisplayCurrent(bool Current)
Definition: osdbase.c:287
void SetMenuSortMode(eMenuSortMode MenuSortMode)
Definition: osdbase.c:119
cOsdItem * First(void) const
Definition: tools.h:492
eOSState CloseSubMenu(bool ReDisplay=true)
Definition: osdbase.c:553
void Del(cListObject *Object, bool DeleteObject=true)
Definition: tools.c:2046
eMenuCategory
Definition: skins.h:91
static void MsgOsdClear(void)
Definition: status.c:80
bool isMenu
Definition: osdbase.h:73
virtual void SetMenuCategory(eMenuCategory MenuCategory)
Sets the current menu category.
Definition: skins.c:90
const char * hk(const char *s)
Definition: osdbase.c:133
#define tr(s)
Definition: i18n.h:85
virtual void Move(int From, int To)
Definition: tools.c:2058
void DELETENULL(T *&p)
Definition: tools.h:48
char * skipspace(const char *s)
Definition: tools.h:200
void SetHelp(const char *Red, const char *Green=NULL, const char *Yellow=NULL, const char *Blue=NULL)
Definition: osdbase.c:185
bool SelectableItem(int idx)
Definition: osdbase.c:328
int count
Definition: tools.h:475
virtual int MaxItems(void)=0
Returns the maximum number of items the menu can display.
char * text
Definition: osdbase.h:51
virtual void SetTitle(const char *Title)=0
Sets the title of this menu to Title.
void CursorUp(void)
Definition: osdbase.c:334
Definition: keys.h:28
int MenuScrollWrap
Definition: config.h:266
virtual void Set(void)
Definition: osdbase.h:65
bool helpDisplayed
Definition: osdbase.h:98
int MenuScrollPage
Definition: config.h:265
Definition: osdbase.h:34
eOSState state
Definition: osdbase.h:52
virtual void Clear(void)=0
Clears the entire central area of the menu.
const char * helpRed
Definition: osdbase.h:97
void SetTitle(const char *Title)
Definition: osdbase.c:170
cSkin * Current(void)
Returns a pointer to the current skin.
Definition: skins.h:436
eOSState AddSubMenu(cOsdMenu *SubMenu)
Definition: osdbase.c:545
static void MsgOsdItem(const char *Text, int Index)
Definition: status.c:104
virtual void SetMenuItem(cSkinDisplayMenu *DisplayMenu, int Index, bool Current, bool Selectable)
Definition: osdbase.c:58
cOsdItem * Prev(const cOsdItem *object) const
Definition: tools.h:494
int cols[cSkinDisplayMenu::MaxTabs]
Definition: osdbase.h:92
eKeys
Definition: keys.h:16
virtual void SetButtons(const char *Red, const char *Green=NULL, const char *Yellow=NULL, const char *Blue=NULL)=0
Sets the color buttons to the given strings.
Definition: tools.h:168
eMenuSortMode
Definition: skins.h:124
Definition: keys.h:22
cSkins Skins
Definition: skins.c:219