soc/intel/xeon_sp/util: Enhance lock_pam0123
[coreboot2.git] / payloads / libpayload / curses / PDCurses / pdcurses / panel.c
blob87b987d4b4bd7fba4e162bcb9ff9da2347e7e899
1 /* Public Domain Curses */
3 #include <curspriv.h>
5 RCSID("$Id: panel.c,v 1.8 2008/07/14 12:35:23 wmcbrine Exp $")
7 /*man-start**************************************************************
9 Name: panel
11 Synopsis:
12 int bottom_panel(PANEL *pan);
13 int del_panel(PANEL *pan);
14 int hide_panel(PANEL *pan);
15 int move_panel(PANEL *pan, int starty, int startx);
16 PANEL *new_panel(WINDOW *win);
17 PANEL *panel_above(const PANEL *pan);
18 PANEL *panel_below(const PANEL *pan);
19 int panel_hidden(const PANEL *pan);
20 const void *panel_userptr(const PANEL *pan);
21 WINDOW *panel_window(const PANEL *pan);
22 int replace_panel(PANEL *pan, WINDOW *win);
23 int set_panel_userptr(PANEL *pan, const void *uptr);
24 int show_panel(PANEL *pan);
25 int top_panel(PANEL *pan);
26 void update_panels(void);
28 Description:
29 The panel library is built using the curses library, and any
30 program using panels routines must call one of the curses
31 initialization routines such as initscr(). A program using these
32 routines must be linked with the panels and curses libraries.
33 The header <panel.h> includes the header <curses.h>.
35 The panels package gives the applications programmer a way to
36 have depth relationships between curses windows; a curses window
37 is associated with every panel. The panels routines allow curses
38 windows to overlap without making visible the overlapped
39 portions of underlying windows. The initial curses window,
40 stdscr, lies beneath all panels. The set of currently visible
41 panels is the 'deck' of panels.
43 The panels package allows the applications programmer to create
44 panels, fetch and set their associated windows, shuffle panels
45 in the deck, and manipulate panels in other ways.
47 bottom_panel() places pan at the bottom of the deck. The size,
48 location and contents of the panel are unchanged.
50 del_panel() deletes pan, but not its associated winwow.
52 hide_panel() removes a panel from the deck and thus hides it
53 from view.
55 move_panel() moves the curses window associated with pan, so
56 that its upper lefthand corner is at the supplied coordinates.
57 (Do not use mvwin() on the window.)
59 new_panel() creates a new panel associated with win and returns
60 the panel pointer. The new panel is placed at the top of the
61 deck.
63 panel_above() returns a pointer to the panel in the deck above
64 pan, or NULL if pan is the top panel. If the value of pan passed
65 is NULL, this function returns a pointer to the bottom panel in
66 the deck.
68 panel_below() returns a pointer to the panel in the deck below
69 pan, or NULL if pan is the bottom panel. If the value of pan
70 passed is NULL, this function returns a pointer to the top panel
71 in the deck.
73 panel_hidden() returns OK if pan is hidden and ERR if it is not.
75 panel_userptr() - Each panel has a user pointer available for
76 maintaining relevant information. This function returns a
77 pointer to that information previously set up by
78 set_panel_userptr().
80 panel_window() returns a pointer to the curses window associated
81 with the panel.
83 replace_panel() replaces the current window of pan with win.
85 set_panel_userptr() - Each panel has a user pointer available
86 for maintaining relevant information. This function sets the
87 value of that information.
89 show_panel() makes a previously hidden panel visible and places
90 it back in the deck on top.
92 top_panel() places pan on the top of the deck. The size,
93 location and contents of the panel are unchanged.
95 update_panels() refreshes the virtual screen to reflect the
96 depth relationships between the panels in the deck. The user
97 must use doupdate() to refresh the physical screen.
99 Return Value:
100 Each routine that returns a pointer to an object returns NULL if
101 an error occurs. Each panel routine that returns an integer,
102 returns OK if it executes successfully and ERR if it does not.
104 Portability X/Open BSD SYS V
105 bottom_panel - - Y
106 del_panel - - Y
107 hide_panel - - Y
108 move_panel - - Y
109 new_panel - - Y
110 panel_above - - Y
111 panel_below - - Y
112 panel_hidden - - Y
113 panel_userptr - - Y
114 panel_window - - Y
115 replace_panel - - Y
116 set_panel_userptr - - Y
117 show_panel - - Y
118 top_panel - - Y
119 update_panels - - Y
121 Credits:
122 Original Author - Warren Tucker <wht@n4hgf.mt-park.ga.us>
124 **man-end****************************************************************/
126 #include <panel.h>
127 #include <stdlib.h>
129 PANEL *_bottom_panel = (PANEL *)0;
130 PANEL *_top_panel = (PANEL *)0;
131 PANEL _stdscr_pseudo_panel = { (WINDOW *)0 };
133 #ifdef PANEL_DEBUG
135 static void dPanel(char *text, PANEL *pan)
137 PDC_LOG(("%s id=%s b=%s a=%s y=%d x=%d", text, pan->user,
138 pan->below ? pan->below->user : "--",
139 pan->above ? pan->above->user : "--",
140 pan->wstarty, pan->wstartx));
143 static void dStack(char *fmt, int num, PANEL *pan)
145 char s80[80];
147 sprintf(s80, fmt, num, pan);
148 PDC_LOG(("%s b=%s t=%s", s80, _bottom_panel ? _bottom_panel->user : "--",
149 _top_panel ? _top_panel->user : "--"));
151 if (pan)
152 PDC_LOG(("pan id=%s", pan->user));
154 pan = _bottom_panel;
156 while (pan)
158 dPanel("stk", pan);
159 pan = pan->above;
163 /* debugging hook for wnoutrefresh */
165 static void Wnoutrefresh(PANEL *pan)
167 dPanel("wnoutrefresh", pan);
168 wnoutrefresh(pan->win);
171 static void Touchpan(PANEL *pan)
173 dPanel("Touchpan", pan);
174 touchwin(pan->win);
177 static void Touchline(PANEL *pan, int start, int count)
179 char s80[80];
181 sprintf(s80, "Touchline s=%d c=%d", start, count);
182 dPanel(s80, pan);
183 touchline(pan->win, start, count);
186 #else /* PANEL_DEBUG */
188 #define dPanel(text, pan)
189 #define dStack(fmt, num, pan)
190 #define Wnoutrefresh(pan) wnoutrefresh((pan)->win)
191 #define Touchpan(pan) touchwin((pan)->win)
192 #define Touchline(pan, start, count) touchline((pan)->win, start, count)
194 #endif /* PANEL_DEBUG */
196 static bool _panels_overlapped(PANEL *pan1, PANEL *pan2)
198 if (!pan1 || !pan2)
199 return FALSE;
201 return ((pan1->wstarty >= pan2->wstarty && pan1->wstarty < pan2->wendy)
202 || (pan2->wstarty >= pan1->wstarty && pan2->wstarty < pan1->wendy))
203 && ((pan1->wstartx >= pan2->wstartx && pan1->wstartx < pan2->wendx)
204 || (pan2->wstartx >= pan1->wstartx && pan2->wstartx < pan1->wendx));
207 static void _free_obscure(PANEL *pan)
209 PANELOBS *tobs = pan->obscure; /* "this" one */
210 PANELOBS *nobs; /* "next" one */
212 while (tobs)
214 nobs = tobs->above;
215 free((char *)tobs);
216 tobs = nobs;
218 pan->obscure = (PANELOBS *)0;
221 static void _override(PANEL *pan, int show)
223 int y;
224 PANEL *pan2;
225 PANELOBS *tobs = pan->obscure; /* "this" one */
227 if (show == 1)
228 Touchpan(pan);
229 else if (!show)
231 Touchpan(pan);
232 Touchpan(&_stdscr_pseudo_panel);
234 else if (show == -1)
235 while (tobs && (tobs->pan != pan))
236 tobs = tobs->above;
238 while (tobs)
240 if ((pan2 = tobs->pan) != pan)
241 for (y = pan->wstarty; y < pan->wendy; y++)
242 if ((y >= pan2->wstarty) && (y < pan2->wendy) &&
243 ((is_linetouched(pan->win, y - pan->wstarty)) ||
244 (is_linetouched(stdscr, y))))
245 Touchline(pan2, y - pan2->wstarty, 1);
247 tobs = tobs->above;
251 static void _calculate_obscure(void)
253 PANEL *pan, *pan2;
254 PANELOBS *tobs; /* "this" one */
255 PANELOBS *lobs; /* last one */
257 pan = _bottom_panel;
259 while (pan)
261 if (pan->obscure)
262 _free_obscure(pan);
264 lobs = (PANELOBS *)0;
265 pan2 = _bottom_panel;
267 while (pan2)
269 if (_panels_overlapped(pan, pan2))
271 if ((tobs = malloc(sizeof(PANELOBS))) == NULL)
272 return;
274 tobs->pan = pan2;
275 dPanel("obscured", pan2);
276 tobs->above = (PANELOBS *)0;
278 if (lobs)
279 lobs->above = tobs;
280 else
281 pan->obscure = tobs;
283 lobs = tobs;
286 pan2 = pan2->above;
289 _override(pan, 1);
290 pan = pan->above;
294 /* check to see if panel is in the stack */
296 static bool _panel_is_linked(const PANEL *pan)
298 PANEL *pan2 = _bottom_panel;
300 while (pan2)
302 if (pan2 == pan)
303 return TRUE;
305 pan2 = pan2->above;
308 return FALSE;
311 /* link panel into stack at top */
313 static void _panel_link_top(PANEL *pan)
315 #ifdef PANEL_DEBUG
316 dStack("<lt%d>", 1, pan);
317 if (_panel_is_linked(pan))
318 return;
319 #endif
320 pan->above = (PANEL *)0;
321 pan->below = (PANEL *)0;
323 if (_top_panel)
325 _top_panel->above = pan;
326 pan->below = _top_panel;
329 _top_panel = pan;
331 if (!_bottom_panel)
332 _bottom_panel = pan;
334 _calculate_obscure();
335 dStack("<lt%d>", 9, pan);
338 /* link panel into stack at bottom */
340 static void _panel_link_bottom(PANEL *pan)
342 #ifdef PANEL_DEBUG
343 dStack("<lb%d>", 1, pan);
344 if (_panel_is_linked(pan))
345 return;
346 #endif
347 pan->above = (PANEL *)0;
348 pan->below = (PANEL *)0;
350 if (_bottom_panel)
352 _bottom_panel->below = pan;
353 pan->above = _bottom_panel;
356 _bottom_panel = pan;
358 if (!_top_panel)
359 _top_panel = pan;
361 _calculate_obscure();
362 dStack("<lb%d>", 9, pan);
365 static void _panel_unlink(PANEL *pan)
367 PANEL *prev;
368 PANEL *next;
370 #ifdef PANEL_DEBUG
371 dStack("<u%d>", 1, pan);
372 if (!_panel_is_linked(pan))
373 return;
374 #endif
375 _override(pan, 0);
376 _free_obscure(pan);
378 prev = pan->below;
379 next = pan->above;
381 /* if non-zero, we will not update the list head */
383 if (prev)
385 prev->above = next;
386 if(next)
387 next->below = prev;
389 else if (next)
390 next->below = prev;
392 if (pan == _bottom_panel)
393 _bottom_panel = next;
395 if (pan == _top_panel)
396 _top_panel = prev;
398 _calculate_obscure();
400 pan->above = (PANEL *)0;
401 pan->below = (PANEL *)0;
402 dStack("<u%d>", 9, pan);
406 /************************************************************************
407 * The following are the public functions for the panels library. *
408 ************************************************************************/
410 int bottom_panel(PANEL *pan)
412 if (!pan)
413 return ERR;
415 if (pan == _bottom_panel)
416 return OK;
418 if (_panel_is_linked(pan))
419 hide_panel(pan);
421 _panel_link_bottom(pan);
423 return OK;
426 int del_panel(PANEL *pan)
428 if (pan)
430 if (_panel_is_linked(pan))
431 hide_panel(pan);
433 free((char *)pan);
434 return OK;
437 return ERR;
440 int hide_panel(PANEL *pan)
442 if (!pan)
443 return ERR;
445 if (!_panel_is_linked(pan))
447 pan->above = (PANEL *)0;
448 pan->below = (PANEL *)0;
449 return ERR;
452 _panel_unlink(pan);
454 return OK;
457 int move_panel(PANEL *pan, int starty, int startx)
459 WINDOW *win;
460 int maxy, maxx;
462 if (!pan)
463 return ERR;
465 if (_panel_is_linked(pan))
466 _override(pan, 0);
468 win = pan->win;
470 if (mvwin(win, starty, startx) == ERR)
471 return ERR;
473 getbegyx(win, pan->wstarty, pan->wstartx);
474 getmaxyx(win, maxy, maxx);
475 pan->wendy = pan->wstarty + maxy;
476 pan->wendx = pan->wstartx + maxx;
478 if (_panel_is_linked(pan))
479 _calculate_obscure();
481 return OK;
484 PANEL *new_panel(WINDOW *win)
486 PANEL *pan = malloc(sizeof(PANEL));
488 if (!_stdscr_pseudo_panel.win)
490 _stdscr_pseudo_panel.win = stdscr;
491 _stdscr_pseudo_panel.wstarty = 0;
492 _stdscr_pseudo_panel.wstartx = 0;
493 _stdscr_pseudo_panel.wendy = LINES;
494 _stdscr_pseudo_panel.wendx = COLS;
495 _stdscr_pseudo_panel.user = "stdscr";
496 _stdscr_pseudo_panel.obscure = (PANELOBS *)0;
499 if (pan)
501 int maxy, maxx;
503 pan->win = win;
504 pan->above = (PANEL *)0;
505 pan->below = (PANEL *)0;
506 getbegyx(win, pan->wstarty, pan->wstartx);
507 getmaxyx(win, maxy, maxx);
508 pan->wendy = pan->wstarty + maxy;
509 pan->wendx = pan->wstartx + maxx;
510 #ifdef PANEL_DEBUG
511 pan->user = "new";
512 #else
513 pan->user = (char *)0;
514 #endif
515 pan->obscure = (PANELOBS *)0;
516 show_panel(pan);
519 return pan;
522 PANEL *panel_above(const PANEL *pan)
524 return pan ? pan->above : _bottom_panel;
527 PANEL *panel_below(const PANEL *pan)
529 return pan ? pan->below : _top_panel;
532 int panel_hidden(const PANEL *pan)
534 if (!pan)
535 return ERR;
537 return _panel_is_linked(pan) ? ERR : OK;
540 const void *panel_userptr(const PANEL *pan)
542 return pan ? pan->user : NULL;
545 WINDOW *panel_window(const PANEL *pan)
547 PDC_LOG(("panel_window() - called\n"));
549 return pan->win;
552 int replace_panel(PANEL *pan, WINDOW *win)
554 int maxy, maxx;
556 if (!pan)
557 return ERR;
559 if (_panel_is_linked(pan))
560 _override(pan, 0);
562 pan->win = win;
563 getbegyx(win, pan->wstarty, pan->wstartx);
564 getmaxyx(win, maxy, maxx);
565 pan->wendy = pan->wstarty + maxy;
566 pan->wendx = pan->wstartx + maxx;
568 if (_panel_is_linked(pan))
569 _calculate_obscure();
571 return OK;
574 int set_panel_userptr(PANEL *pan, const void *uptr)
576 if (!pan)
577 return ERR;
579 pan->user = uptr;
580 return OK;
583 int show_panel(PANEL *pan)
585 if (!pan)
586 return ERR;
588 if (pan == _top_panel)
589 return OK;
591 if (_panel_is_linked(pan))
592 hide_panel(pan);
594 _panel_link_top(pan);
596 return OK;
599 int top_panel(PANEL *pan)
601 return show_panel(pan);
604 void update_panels(void)
606 PANEL *pan;
608 PDC_LOG(("update_panels() - called\n"));
610 pan = _bottom_panel;
612 while (pan)
614 _override(pan, -1);
615 pan = pan->above;
618 if (is_wintouched(stdscr))
619 Wnoutrefresh(&_stdscr_pseudo_panel);
621 pan = _bottom_panel;
623 while (pan)
625 if (is_wintouched(pan->win) || !pan->above)
626 Wnoutrefresh(pan);
628 pan = pan->above;