aboutsummaryrefslogtreecommitdiff
path: root/payloads/libpayload/curses/PDCurses-3.4/pdcurses/panel.c
diff options
context:
space:
mode:
Diffstat (limited to 'payloads/libpayload/curses/PDCurses-3.4/pdcurses/panel.c')
-rw-r--r--payloads/libpayload/curses/PDCurses-3.4/pdcurses/panel.c630
1 files changed, 630 insertions, 0 deletions
diff --git a/payloads/libpayload/curses/PDCurses-3.4/pdcurses/panel.c b/payloads/libpayload/curses/PDCurses-3.4/pdcurses/panel.c
new file mode 100644
index 0000000000..77028c6ffc
--- /dev/null
+++ b/payloads/libpayload/curses/PDCurses-3.4/pdcurses/panel.c
@@ -0,0 +1,630 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: panel.c,v 1.8 2008/07/14 12:35:23 wmcbrine Exp $")
+
+/*man-start**************************************************************
+
+ Name: panel
+
+ Synopsis:
+ int bottom_panel(PANEL *pan);
+ int del_panel(PANEL *pan);
+ int hide_panel(PANEL *pan);
+ int move_panel(PANEL *pan, int starty, int startx);
+ PANEL *new_panel(WINDOW *win);
+ PANEL *panel_above(const PANEL *pan);
+ PANEL *panel_below(const PANEL *pan);
+ int panel_hidden(const PANEL *pan);
+ const void *panel_userptr(const PANEL *pan);
+ WINDOW *panel_window(const PANEL *pan);
+ int replace_panel(PANEL *pan, WINDOW *win);
+ int set_panel_userptr(PANEL *pan, const void *uptr);
+ int show_panel(PANEL *pan);
+ int top_panel(PANEL *pan);
+ void update_panels(void);
+
+ Description:
+ The panel library is built using the curses library, and any
+ program using panels routines must call one of the curses
+ initialization routines such as initscr(). A program using these
+ routines must be linked with the panels and curses libraries.
+ The header <panel.h> includes the header <curses.h>.
+
+ The panels package gives the applications programmer a way to
+ have depth relationships between curses windows; a curses window
+ is associated with every panel. The panels routines allow curses
+ windows to overlap without making visible the overlapped
+ portions of underlying windows. The initial curses window,
+ stdscr, lies beneath all panels. The set of currently visible
+ panels is the 'deck' of panels.
+
+ The panels package allows the applications programmer to create
+ panels, fetch and set their associated windows, shuffle panels
+ in the deck, and manipulate panels in other ways.
+
+ bottom_panel() places pan at the bottom of the deck. The size,
+ location and contents of the panel are unchanged.
+
+ del_panel() deletes pan, but not its associated winwow.
+
+ hide_panel() removes a panel from the deck and thus hides it
+ from view.
+
+ move_panel() moves the curses window associated with pan, so
+ that its upper lefthand corner is at the supplied coordinates.
+ (Do not use mvwin() on the window.)
+
+ new_panel() creates a new panel associated with win and returns
+ the panel pointer. The new panel is placed at the top of the
+ deck.
+
+ panel_above() returns a pointer to the panel in the deck above
+ pan, or NULL if pan is the top panel. If the value of pan passed
+ is NULL, this function returns a pointer to the bottom panel in
+ the deck.
+
+ panel_below() returns a pointer to the panel in the deck below
+ pan, or NULL if pan is the bottom panel. If the value of pan
+ passed is NULL, this function returns a pointer to the top panel
+ in the deck.
+
+ panel_hidden() returns OK if pan is hidden and ERR if it is not.
+
+ panel_userptr() - Each panel has a user pointer available for
+ maintaining relevant information. This function returns a
+ pointer to that information previously set up by
+ set_panel_userptr().
+
+ panel_window() returns a pointer to the curses window associated
+ with the panel.
+
+ replace_panel() replaces the current window of pan with win.
+
+ set_panel_userptr() - Each panel has a user pointer available
+ for maintaining relevant information. This function sets the
+ value of that information.
+
+ show_panel() makes a previously hidden panel visible and places
+ it back in the deck on top.
+
+ top_panel() places pan on the top of the deck. The size,
+ location and contents of the panel are unchanged.
+
+ update_panels() refreshes the virtual screen to reflect the
+ depth relationships between the panels in the deck. The user
+ must use doupdate() to refresh the physical screen.
+
+ Return Value:
+ Each routine that returns a pointer to an object returns NULL if
+ an error occurs. Each panel routine that returns an integer,
+ returns OK if it executes successfully and ERR if it does not.
+
+ Portability X/Open BSD SYS V
+ bottom_panel - - Y
+ del_panel - - Y
+ hide_panel - - Y
+ move_panel - - Y
+ new_panel - - Y
+ panel_above - - Y
+ panel_below - - Y
+ panel_hidden - - Y
+ panel_userptr - - Y
+ panel_window - - Y
+ replace_panel - - Y
+ set_panel_userptr - - Y
+ show_panel - - Y
+ top_panel - - Y
+ update_panels - - Y
+
+ Credits:
+ Original Author - Warren Tucker <wht@n4hgf.mt-park.ga.us>
+
+**man-end****************************************************************/
+
+#include <panel.h>
+#include <stdlib.h>
+
+PANEL *_bottom_panel = (PANEL *)0;
+PANEL *_top_panel = (PANEL *)0;
+PANEL _stdscr_pseudo_panel = { (WINDOW *)0 };
+
+#ifdef PANEL_DEBUG
+
+static void dPanel(char *text, PANEL *pan)
+{
+ PDC_LOG(("%s id=%s b=%s a=%s y=%d x=%d", text, pan->user,
+ pan->below ? pan->below->user : "--",
+ pan->above ? pan->above->user : "--",
+ pan->wstarty, pan->wstartx));
+}
+
+static void dStack(char *fmt, int num, PANEL *pan)
+{
+ char s80[80];
+
+ sprintf(s80, fmt, num, pan);
+ PDC_LOG(("%s b=%s t=%s", s80, _bottom_panel ? _bottom_panel->user : "--",
+ _top_panel ? _top_panel->user : "--"));
+
+ if (pan)
+ PDC_LOG(("pan id=%s", pan->user));
+
+ pan = _bottom_panel;
+
+ while (pan)
+ {
+ dPanel("stk", pan);
+ pan = pan->above;
+ }
+}
+
+/* debugging hook for wnoutrefresh */
+
+static void Wnoutrefresh(PANEL *pan)
+{
+ dPanel("wnoutrefresh", pan);
+ wnoutrefresh(pan->win);
+}
+
+static void Touchpan(PANEL *pan)
+{
+ dPanel("Touchpan", pan);
+ touchwin(pan->win);
+}
+
+static void Touchline(PANEL *pan, int start, int count)
+{
+ char s80[80];
+
+ sprintf(s80, "Touchline s=%d c=%d", start, count);
+ dPanel(s80, pan);
+ touchline(pan->win, start, count);
+}
+
+#else /* PANEL_DEBUG */
+
+#define dPanel(text, pan)
+#define dStack(fmt, num, pan)
+#define Wnoutrefresh(pan) wnoutrefresh((pan)->win)
+#define Touchpan(pan) touchwin((pan)->win)
+#define Touchline(pan, start, count) touchline((pan)->win, start, count)
+
+#endif /* PANEL_DEBUG */
+
+static bool _panels_overlapped(PANEL *pan1, PANEL *pan2)
+{
+ if (!pan1 || !pan2)
+ return FALSE;
+
+ return ((pan1->wstarty >= pan2->wstarty && pan1->wstarty < pan2->wendy)
+ || (pan2->wstarty >= pan1->wstarty && pan2->wstarty < pan1->wendy))
+ && ((pan1->wstartx >= pan2->wstartx && pan1->wstartx < pan2->wendx)
+ || (pan2->wstartx >= pan1->wstartx && pan2->wstartx < pan1->wendx));
+}
+
+static void _free_obscure(PANEL *pan)
+{
+ PANELOBS *tobs = pan->obscure; /* "this" one */
+ PANELOBS *nobs; /* "next" one */
+
+ while (tobs)
+ {
+ nobs = tobs->above;
+ free((char *)tobs);
+ tobs = nobs;
+ }
+ pan->obscure = (PANELOBS *)0;
+}
+
+static void _override(PANEL *pan, int show)
+{
+ int y;
+ PANEL *pan2;
+ PANELOBS *tobs = pan->obscure; /* "this" one */
+
+ if (show == 1)
+ Touchpan(pan);
+ else if (!show)
+ {
+ Touchpan(pan);
+ Touchpan(&_stdscr_pseudo_panel);
+ }
+ else if (show == -1)
+ while (tobs && (tobs->pan != pan))
+ tobs = tobs->above;
+
+ while (tobs)
+ {
+ if ((pan2 = tobs->pan) != pan)
+ for (y = pan->wstarty; y < pan->wendy; y++)
+ if ((y >= pan2->wstarty) && (y < pan2->wendy) &&
+ ((is_linetouched(pan->win, y - pan->wstarty)) ||
+ (is_linetouched(stdscr, y))))
+ Touchline(pan2, y - pan2->wstarty, 1);
+
+ tobs = tobs->above;
+ }
+}
+
+static void _calculate_obscure(void)
+{
+ PANEL *pan, *pan2;
+ PANELOBS *tobs; /* "this" one */
+ PANELOBS *lobs; /* last one */
+
+ pan = _bottom_panel;
+
+ while (pan)
+ {
+ if (pan->obscure)
+ _free_obscure(pan);
+
+ lobs = (PANELOBS *)0;
+ pan2 = _bottom_panel;
+
+ while (pan2)
+ {
+ if (_panels_overlapped(pan, pan2))
+ {
+ if ((tobs = malloc(sizeof(PANELOBS))) == NULL)
+ return;
+
+ tobs->pan = pan2;
+ dPanel("obscured", pan2);
+ tobs->above = (PANELOBS *)0;
+
+ if (lobs)
+ lobs->above = tobs;
+ else
+ pan->obscure = tobs;
+
+ lobs = tobs;
+ }
+
+ pan2 = pan2->above;
+ }
+
+ _override(pan, 1);
+ pan = pan->above;
+ }
+}
+
+/* check to see if panel is in the stack */
+
+static bool _panel_is_linked(const PANEL *pan)
+{
+ PANEL *pan2 = _bottom_panel;
+
+ while (pan2)
+ {
+ if (pan2 == pan)
+ return TRUE;
+
+ pan2 = pan2->above;
+ }
+
+ return FALSE;
+}
+
+/* link panel into stack at top */
+
+static void _panel_link_top(PANEL *pan)
+{
+#ifdef PANEL_DEBUG
+ dStack("<lt%d>", 1, pan);
+ if (_panel_is_linked(pan))
+ return;
+#endif
+ pan->above = (PANEL *)0;
+ pan->below = (PANEL *)0;
+
+ if (_top_panel)
+ {
+ _top_panel->above = pan;
+ pan->below = _top_panel;
+ }
+
+ _top_panel = pan;
+
+ if (!_bottom_panel)
+ _bottom_panel = pan;
+
+ _calculate_obscure();
+ dStack("<lt%d>", 9, pan);
+}
+
+/* link panel into stack at bottom */
+
+static void _panel_link_bottom(PANEL *pan)
+{
+#ifdef PANEL_DEBUG
+ dStack("<lb%d>", 1, pan);
+ if (_panel_is_linked(pan))
+ return;
+#endif
+ pan->above = (PANEL *)0;
+ pan->below = (PANEL *)0;
+
+ if (_bottom_panel)
+ {
+ _bottom_panel->below = pan;
+ pan->above = _bottom_panel;
+ }
+
+ _bottom_panel = pan;
+
+ if (!_top_panel)
+ _top_panel = pan;
+
+ _calculate_obscure();
+ dStack("<lb%d>", 9, pan);
+}
+
+static void _panel_unlink(PANEL *pan)
+{
+ PANEL *prev;
+ PANEL *next;
+
+#ifdef PANEL_DEBUG
+ dStack("<u%d>", 1, pan);
+ if (!_panel_is_linked(pan))
+ return;
+#endif
+ _override(pan, 0);
+ _free_obscure(pan);
+
+ prev = pan->below;
+ next = pan->above;
+
+ /* if non-zero, we will not update the list head */
+
+ if (prev)
+ {
+ prev->above = next;
+ if(next)
+ next->below = prev;
+ }
+ else if (next)
+ next->below = prev;
+
+ if (pan == _bottom_panel)
+ _bottom_panel = next;
+
+ if (pan == _top_panel)
+ _top_panel = prev;
+
+ _calculate_obscure();
+
+ pan->above = (PANEL *)0;
+ pan->below = (PANEL *)0;
+ dStack("<u%d>", 9, pan);
+
+}
+
+/************************************************************************
+ * The following are the public functions for the panels library. *
+ ************************************************************************/
+
+int bottom_panel(PANEL *pan)
+{
+ if (!pan)
+ return ERR;
+
+ if (pan == _bottom_panel)
+ return OK;
+
+ if (_panel_is_linked(pan))
+ hide_panel(pan);
+
+ _panel_link_bottom(pan);
+
+ return OK;
+}
+
+int del_panel(PANEL *pan)
+{
+ if (pan)
+ {
+ if (_panel_is_linked(pan))
+ hide_panel(pan);
+
+ free((char *)pan);
+ return OK;
+ }
+
+ return ERR;
+}
+
+int hide_panel(PANEL *pan)
+{
+ if (!pan)
+ return ERR;
+
+ if (!_panel_is_linked(pan))
+ {
+ pan->above = (PANEL *)0;
+ pan->below = (PANEL *)0;
+ return ERR;
+ }
+
+ _panel_unlink(pan);
+
+ return OK;
+}
+
+int move_panel(PANEL *pan, int starty, int startx)
+{
+ WINDOW *win;
+ int maxy, maxx;
+
+ if (!pan)
+ return ERR;
+
+ if (_panel_is_linked(pan))
+ _override(pan, 0);
+
+ win = pan->win;
+
+ if (mvwin(win, starty, startx) == ERR)
+ return ERR;
+
+ getbegyx(win, pan->wstarty, pan->wstartx);
+ getmaxyx(win, maxy, maxx);
+ pan->wendy = pan->wstarty + maxy;
+ pan->wendx = pan->wstartx + maxx;
+
+ if (_panel_is_linked(pan))
+ _calculate_obscure();
+
+ return OK;
+}
+
+PANEL *new_panel(WINDOW *win)
+{
+ PANEL *pan = malloc(sizeof(PANEL));
+
+ if (!_stdscr_pseudo_panel.win)
+ {
+ _stdscr_pseudo_panel.win = stdscr;
+ _stdscr_pseudo_panel.wstarty = 0;
+ _stdscr_pseudo_panel.wstartx = 0;
+ _stdscr_pseudo_panel.wendy = LINES;
+ _stdscr_pseudo_panel.wendx = COLS;
+ _stdscr_pseudo_panel.user = "stdscr";
+ _stdscr_pseudo_panel.obscure = (PANELOBS *)0;
+ }
+
+ if (pan)
+ {
+ int maxy, maxx;
+
+ pan->win = win;
+ pan->above = (PANEL *)0;
+ pan->below = (PANEL *)0;
+ getbegyx(win, pan->wstarty, pan->wstartx);
+ getmaxyx(win, maxy, maxx);
+ pan->wendy = pan->wstarty + maxy;
+ pan->wendx = pan->wstartx + maxx;
+#ifdef PANEL_DEBUG
+ pan->user = "new";
+#else
+ pan->user = (char *)0;
+#endif
+ pan->obscure = (PANELOBS *)0;
+ show_panel(pan);
+ }
+
+ return pan;
+}
+
+PANEL *panel_above(const PANEL *pan)
+{
+ return pan ? pan->above : _bottom_panel;
+}
+
+PANEL *panel_below(const PANEL *pan)
+{
+ return pan ? pan->below : _top_panel;
+}
+
+int panel_hidden(const PANEL *pan)
+{
+ if (!pan)
+ return ERR;
+
+ return _panel_is_linked(pan) ? ERR : OK;
+}
+
+const void *panel_userptr(const PANEL *pan)
+{
+ return pan ? pan->user : NULL;
+}
+
+WINDOW *panel_window(const PANEL *pan)
+{
+ PDC_LOG(("panel_window() - called\n"));
+
+ return pan->win;
+}
+
+int replace_panel(PANEL *pan, WINDOW *win)
+{
+ int maxy, maxx;
+
+ if (!pan)
+ return ERR;
+
+ if (_panel_is_linked(pan))
+ _override(pan, 0);
+
+ pan->win = win;
+ getbegyx(win, pan->wstarty, pan->wstartx);
+ getmaxyx(win, maxy, maxx);
+ pan->wendy = pan->wstarty + maxy;
+ pan->wendx = pan->wstartx + maxx;
+
+ if (_panel_is_linked(pan))
+ _calculate_obscure();
+
+ return OK;
+}
+
+int set_panel_userptr(PANEL *pan, const void *uptr)
+{
+ if (!pan)
+ return ERR;
+
+ pan->user = uptr;
+ return OK;
+}
+
+int show_panel(PANEL *pan)
+{
+ if (!pan)
+ return ERR;
+
+ if (pan == _top_panel)
+ return OK;
+
+ if (_panel_is_linked(pan))
+ hide_panel(pan);
+
+ _panel_link_top(pan);
+
+ return OK;
+}
+
+int top_panel(PANEL *pan)
+{
+ return show_panel(pan);
+}
+
+void update_panels(void)
+{
+ PANEL *pan;
+
+ PDC_LOG(("update_panels() - called\n"));
+
+ pan = _bottom_panel;
+
+ while (pan)
+ {
+ _override(pan, -1);
+ pan = pan->above;
+ }
+
+ if (is_wintouched(stdscr))
+ Wnoutrefresh(&_stdscr_pseudo_panel);
+
+ pan = _bottom_panel;
+
+ while (pan)
+ {
+ if (is_wintouched(pan->win) || !pan->above)
+ Wnoutrefresh(pan);
+
+ pan = pan->above;
+ }
+}