home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / SLAX 6.0.8 / slax-6.0.8.iso / slax / base / 006-devel.lzm / usr / include / ncurses / cursesm.h < prev    next >
Encoding:
C/C++ Source or Header  |  2008-11-21  |  19.0 KB  |  673 lines

  1. // * This makes emacs happy -*-Mode: C++;-*-
  2. /****************************************************************************
  3.  * Copyright (c) 1998-2003,2005 Free Software Foundation, Inc.              *
  4.  *                                                                          *
  5.  * Permission is hereby granted, free of charge, to any person obtaining a  *
  6.  * copy of this software and associated documentation files (the            *
  7.  * "Software"), to deal in the Software without restriction, including      *
  8.  * without limitation the rights to use, copy, modify, merge, publish,      *
  9.  * distribute, distribute with modifications, sublicense, and/or sell       *
  10.  * copies of the Software, and to permit persons to whom the Software is    *
  11.  * furnished to do so, subject to the following conditions:                 *
  12.  *                                                                          *
  13.  * The above copyright notice and this permission notice shall be included  *
  14.  * in all copies or substantial portions of the Software.                   *
  15.  *                                                                          *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
  17.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
  18.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
  19.  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
  20.  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
  21.  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
  22.  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
  23.  *                                                                          *
  24.  * Except as contained in this notice, the name(s) of the above copyright   *
  25.  * holders shall not be used in advertising or otherwise to promote the     *
  26.  * sale, use or other dealings in this Software without prior written       *
  27.  * authorization.                                                           *
  28.  ****************************************************************************/
  29.  
  30. /****************************************************************************
  31.  *   Author: Juergen Pfeifer, 1997                                          *
  32.  ****************************************************************************/
  33.  
  34. // $Id: cursesm.h,v 1.25 2005/08/13 18:10:36 tom Exp $
  35.  
  36. #ifndef NCURSES_CURSESM_H_incl
  37. #define NCURSES_CURSESM_H_incl 1
  38.  
  39. #include <cursesp.h>
  40.  
  41. extern "C" {
  42. #  include <menu.h>
  43. }
  44. //
  45. // -------------------------------------------------------------------------
  46. // This wraps the ITEM type of <menu.h>
  47. // -------------------------------------------------------------------------
  48. //
  49. class NCURSES_IMPEXP NCursesMenuItem
  50. {
  51.   friend class NCursesMenu;
  52.  
  53. protected:
  54.   ITEM *item;
  55.  
  56.   inline void OnError (int err) const THROWS(NCursesMenuException) {
  57.     if (err != E_OK)
  58.       THROW(new NCursesMenuException (err));
  59.   }
  60.  
  61. public:
  62.   NCursesMenuItem (const char* p_name     = NULL,
  63.            const char* p_descript = NULL)
  64.     : item(0)
  65.   {
  66.     item = p_name ? ::new_item (p_name, p_descript) : STATIC_CAST(ITEM*)(0);
  67.     if (p_name && !item)
  68.       OnError (E_SYSTEM_ERROR);
  69.   }
  70.   // Create an item. If you pass both parameters as NULL, a delimiting
  71.   // item is constructed which can be used to terminate a list of
  72.   // NCursesMenu objects.
  73.  
  74.   NCursesMenuItem& operator=(const NCursesMenuItem& rhs)
  75.   {
  76.     if (this != &rhs) {
  77.       *this = rhs;
  78.     }
  79.     return *this;
  80.   }
  81.  
  82.   NCursesMenuItem(const NCursesMenuItem& rhs)
  83.     : item(0)
  84.   {
  85.   }
  86.  
  87.   virtual ~NCursesMenuItem ();
  88.   // Release the items memory
  89.  
  90.   inline const char* name () const {
  91.     return ::item_name (item);
  92.   }
  93.   // Name of the item
  94.  
  95.   inline const char* description () const {
  96.     return ::item_description (item);
  97.   }
  98.   // Description of the item
  99.  
  100.   inline int (index) (void) const {
  101.     return ::item_index (item);
  102.   }
  103.   // Index of the item in an item array (or -1)
  104.  
  105.   inline void options_on (Item_Options opts) {
  106.     OnError (::item_opts_on (item, opts));
  107.   }
  108.   // Switch on the items options
  109.  
  110.   inline void options_off (Item_Options opts) {
  111.     OnError (::item_opts_off (item, opts));
  112.   }
  113.   // Switch off the item's option
  114.  
  115.   inline Item_Options options () const {
  116.     return ::item_opts (item);
  117.   }
  118.   // Retrieve the items options
  119.  
  120.   inline void set_options (Item_Options opts) {
  121.     OnError (::set_item_opts (item, opts));
  122.   }
  123.   // Set the items options
  124.  
  125.   inline void set_value (bool f) {
  126.     OnError (::set_item_value (item,f));
  127.   }
  128.   // Set/Reset the items selection state
  129.  
  130.   inline bool value () const {
  131.     return ::item_value (item);
  132.   }
  133.   // Retrieve the items selection state
  134.  
  135.   inline bool visible () const {
  136.     return ::item_visible (item);
  137.   }
  138.   // Retrieve visibility of the item
  139.  
  140.   virtual bool action();
  141.   // Perform an action associated with this item; you may use this in an
  142.   // user supplied driver for a menu; you may derive from this class and
  143.   // overload action() to supply items with different actions.
  144.   // If an action returns true, the menu will be exited. The default action
  145.   // is to do nothing.
  146. };
  147.  
  148. // Prototype for an items callback function.
  149. typedef bool ITEMCALLBACK(NCursesMenuItem&);
  150.  
  151. // If you don't like to create a child class for individual items to
  152. // overload action(), you may use this class and provide a callback
  153. // function pointer for items.
  154. class NCURSES_IMPEXP NCursesMenuCallbackItem : public NCursesMenuItem
  155. {
  156. private:
  157.   ITEMCALLBACK* p_fct;
  158.  
  159. public:
  160.   NCursesMenuCallbackItem(ITEMCALLBACK* fct       = NULL,
  161.               const char* p_name      = NULL,
  162.               const char* p_descript  = NULL )
  163.     : NCursesMenuItem (p_name, p_descript),
  164.       p_fct (fct) {
  165.   }
  166.  
  167.   NCursesMenuCallbackItem& operator=(const NCursesMenuCallbackItem& rhs)
  168.   {
  169.     if (this != &rhs) {
  170.       *this = rhs;
  171.     }
  172.     return *this;
  173.   }
  174.  
  175.   NCursesMenuCallbackItem(const NCursesMenuCallbackItem& rhs)
  176.     : NCursesMenuItem(rhs),
  177.       p_fct(0)
  178.   {
  179.   }
  180.  
  181.   virtual ~NCursesMenuCallbackItem();
  182.  
  183.   bool action();
  184. };
  185.  
  186.   // This are the built-in hook functions in this C++ binding. In C++ we use
  187.   // virtual member functions (see below On_..._Init and On_..._Termination)
  188.   // to provide this functionality in an object oriented manner.
  189. extern "C" {
  190.   void _nc_xx_mnu_init(MENU *);
  191.   void _nc_xx_mnu_term(MENU *);
  192.   void _nc_xx_itm_init(MENU *);
  193.   void _nc_xx_itm_term(MENU *);
  194. }
  195.  
  196. //
  197. // -------------------------------------------------------------------------
  198. // This wraps the MENU type of <menu.h>
  199. // -------------------------------------------------------------------------
  200. //
  201. class NCURSES_IMPEXP NCursesMenu : public NCursesPanel
  202. {
  203. protected:
  204.   MENU *menu;
  205.  
  206. private:
  207.   NCursesWindow* sub;   // the subwindow object
  208.   bool b_sub_owner;     // is this our own subwindow?
  209.   bool b_framed;        // has the menu a border?
  210.   bool b_autoDelete;    // Delete items when deleting menu?
  211.  
  212.   NCursesMenuItem** my_items; // The array of items for this menu
  213.  
  214.   // This structure is used for the menu's user data field to link the
  215.   // MENU* to the C++ object and to provide extra space for a user pointer.
  216.   typedef struct {
  217.     void*              m_user;      // the pointer for the user's data
  218.     const NCursesMenu* m_back;      // backward pointer to C++ object
  219.     const MENU*        m_owner;
  220.   } UserHook;
  221.  
  222.   // Get the backward pointer to the C++ object from a MENU
  223.   static inline NCursesMenu* getHook(const MENU *m) {
  224.     UserHook* hook = STATIC_CAST(UserHook*)(::menu_userptr(m));
  225.     assert(hook != 0 && hook->m_owner==m);
  226.     return const_cast<NCursesMenu*>(hook->m_back);
  227.   }
  228.  
  229.   friend void _nc_xx_mnu_init(MENU *);
  230.   friend void _nc_xx_mnu_term(MENU *);
  231.   friend void _nc_xx_itm_init(MENU *);
  232.   friend void _nc_xx_itm_term(MENU *);
  233.  
  234.   // Calculate ITEM* array for the menu
  235.   ITEM** mapItems(NCursesMenuItem* nitems[]);
  236.  
  237. protected:
  238.   // internal routines
  239.   inline void set_user(void *user) {
  240.     UserHook* uptr = STATIC_CAST(UserHook*)(::menu_userptr (menu));
  241.     assert (uptr != 0 && uptr->m_back==this && uptr->m_owner==menu);
  242.     uptr->m_user = user;
  243.   }
  244.  
  245.   inline void *get_user() {
  246.     UserHook* uptr = STATIC_CAST(UserHook*)(::menu_userptr (menu));
  247.     assert (uptr != 0 && uptr->m_back==this && uptr->m_owner==menu);
  248.     return uptr->m_user;
  249.   }
  250.  
  251.   void InitMenu (NCursesMenuItem* menu[],
  252.          bool with_frame,
  253.          bool autoDeleteItems);
  254.  
  255.   inline void OnError (int err) const THROWS(NCursesMenuException) {
  256.     if (err != E_OK)
  257.       THROW(new NCursesMenuException (this, err));
  258.   }
  259.  
  260.   // this wraps the menu_driver call.
  261.   virtual int driver (int c) ;
  262.  
  263.   // 'Internal' constructor to create a menu without association to
  264.   // an array of items.
  265.   NCursesMenu( int  nlines,
  266.            int  ncols,
  267.            int  begin_y = 0,
  268.            int  begin_x = 0)
  269.     : NCursesPanel(nlines,ncols,begin_y,begin_x),
  270.       menu (STATIC_CAST(MENU*)(0)),
  271.       sub(0),
  272.       b_sub_owner(0),
  273.       b_framed(0),
  274.       b_autoDelete(0),
  275.       my_items(0)
  276.   {
  277.   }
  278.  
  279. public:
  280.   // Make a full window size menu
  281.   NCursesMenu (NCursesMenuItem* Items[],
  282.            bool with_frame=FALSE,        // Reserve space for a frame?
  283.            bool autoDelete_Items=FALSE)  // Autocleanup of Items?
  284.     : NCursesPanel(),
  285.       menu(0),
  286.       sub(0),
  287.       b_sub_owner(0),
  288.       b_framed(0),
  289.       b_autoDelete(0),
  290.       my_items(0)
  291.   {
  292.       InitMenu(Items, with_frame, autoDelete_Items);
  293.   }
  294.  
  295.   // Make a menu with a window of this size.
  296.   NCursesMenu (NCursesMenuItem* Items[],
  297.            int  nlines,
  298.            int  ncols,
  299.            int  begin_y = 0,
  300.            int  begin_x = 0,
  301.            bool with_frame=FALSE,        // Reserve space for a frame?
  302.            bool autoDelete_Items=FALSE)  // Autocleanup of Items?
  303.     : NCursesPanel(nlines, ncols, begin_y, begin_x),
  304.       menu(0),
  305.       sub(0),
  306.       b_sub_owner(0),
  307.       b_framed(0),
  308.       b_autoDelete(0),
  309.       my_items(0)
  310.   {
  311.       InitMenu(Items, with_frame, autoDelete_Items);
  312.   }
  313.  
  314.   NCursesMenu& operator=(const NCursesMenu& rhs)
  315.   {
  316.     if (this != &rhs) {
  317.       *this = rhs;
  318.       NCursesPanel::operator=(rhs);
  319.     }
  320.     return *this;
  321.   }
  322.  
  323.   NCursesMenu(const NCursesMenu& rhs)
  324.     : NCursesPanel(rhs),
  325.       menu(rhs.menu),
  326.       sub(rhs.sub),
  327.       b_sub_owner(rhs.b_sub_owner),
  328.       b_framed(rhs.b_framed),
  329.       b_autoDelete(rhs.b_autoDelete),
  330.       my_items(rhs.my_items)
  331.   {
  332.   }
  333.  
  334.   virtual ~NCursesMenu ();
  335.  
  336.   // Retrieve the menus subwindow
  337.   inline NCursesWindow& subWindow() const {
  338.     assert(sub!=NULL);
  339.     return *sub;
  340.   }
  341.  
  342.   // Set the menus subwindow
  343.   void setSubWindow(NCursesWindow& sub);
  344.  
  345.   // Set these items for the menu
  346.   inline void setItems(NCursesMenuItem* Items[]) {
  347.     OnError(::set_menu_items(menu,mapItems(Items)));
  348.   }
  349.  
  350.   // Remove the menu from the screen
  351.   inline void unpost (void) {
  352.     OnError (::unpost_menu (menu));
  353.   }
  354.  
  355.   // Post the menu to the screen if flag is true, unpost it otherwise
  356.   inline void post(bool flag = TRUE) {
  357.     flag ? OnError (::post_menu(menu)) : OnError (::unpost_menu (menu));
  358.   }
  359.  
  360.   // Get the numer of rows and columns for this menu
  361.   inline void scale (int& mrows, int& mcols) const  {
  362.     OnError (::scale_menu (menu, &mrows, &mcols));
  363.   }
  364.  
  365.   // Set the format of this menu
  366.   inline void set_format(int mrows, int mcols) {
  367.     OnError (::set_menu_format(menu, mrows, mcols));
  368.   }
  369.  
  370.   // Get the format of this menu
  371.   inline void menu_format(int& rows,int& ncols) {
  372.     ::menu_format(menu,&rows,&ncols);
  373.   }
  374.  
  375.   // Items of the menu
  376.   inline NCursesMenuItem* items() const {
  377.     return *my_items;
  378.   }
  379.  
  380.   // Get the number of items in this menu
  381.   inline int count() const {
  382.     return ::item_count(menu);
  383.   }
  384.  
  385.   // Get the current item (i.e. the one the cursor is located)
  386.   inline NCursesMenuItem* current_item() const {
  387.     return my_items[::item_index(::current_item(menu))];
  388.   }
  389.  
  390.   // Get the marker string
  391.   inline const char* mark() const {
  392.     return ::menu_mark(menu);
  393.   }
  394.  
  395.   // Set the marker string
  396.   inline void set_mark(const char *marker) {
  397.     OnError (::set_menu_mark (menu, marker));
  398.   }
  399.  
  400.   // Get the name of the request code c
  401.   inline static const char* request_name(int c) {
  402.     return ::menu_request_name(c);
  403.   }
  404.  
  405.   // Get the current pattern
  406.   inline char* pattern() const {
  407.     return ::menu_pattern(menu);
  408.   }
  409.  
  410.   // true if there is a pattern match, false otherwise.
  411.   bool set_pattern (const char *pat);
  412.  
  413.   // set the default attributes for the menu
  414.   // i.e. set fore, back and grey attribute
  415.   virtual void setDefaultAttributes();
  416.  
  417.   // Get the menus background attributes
  418.   inline chtype back() const {
  419.     return ::menu_back(menu);
  420.   }
  421.  
  422.   // Get the menus foreground attributes
  423.   inline chtype fore() const {
  424.     return ::menu_fore(menu);
  425.   }
  426.  
  427.   // Get the menus grey attributes (used for unselectable items)
  428.   inline chtype grey() const {
  429.     return ::menu_grey(menu);
  430.   }
  431.  
  432.   // Set the menus background attributes
  433.   inline chtype set_background(chtype a) {
  434.     return ::set_menu_back(menu,a);
  435.   }
  436.  
  437.   // Set the menus foreground attributes
  438.   inline chtype set_foreground(chtype a) {
  439.     return ::set_menu_fore(menu,a);
  440.   }
  441.  
  442.   // Set the menus grey attributes (used for unselectable items)
  443.   inline chtype set_grey(chtype a) {
  444.     return ::set_menu_grey(menu,a);
  445.   }
  446.  
  447.   inline void options_on (Menu_Options opts) {
  448.     OnError (::menu_opts_on (menu,opts));
  449.   }
  450.  
  451.   inline void options_off(Menu_Options opts) {
  452.     OnError (::menu_opts_off(menu,opts));
  453.   }
  454.  
  455.   inline Menu_Options options() const {
  456.     return ::menu_opts(menu);
  457.   }
  458.  
  459.   inline void set_options (Menu_Options opts) {
  460.     OnError (::set_menu_opts (menu,opts));
  461.   }
  462.  
  463.   inline int pad() const {
  464.     return ::menu_pad(menu);
  465.   }
  466.  
  467.   inline void set_pad (int padch) {
  468.     OnError (::set_menu_pad (menu, padch));
  469.   }
  470.  
  471.   // Position the cursor to the current item
  472.   inline void position_cursor () const {
  473.     OnError (::pos_menu_cursor (menu));
  474.   }
  475.  
  476.   // Set the current item
  477.   inline void set_current(NCursesMenuItem& I) {
  478.     OnError (::set_current_item(menu, I.item));
  479.   }
  480.  
  481.   // Get the current top row of the menu
  482.   inline int top_row (void) const {
  483.     return ::top_row (menu);
  484.   }
  485.  
  486.   // Set the current top row of the menu
  487.   inline void set_top_row (int row) {
  488.     OnError (::set_top_row (menu, row));
  489.   }
  490.  
  491.   // spacing control
  492.   // Set the spacing for the menu
  493.   inline void setSpacing(int spc_description,
  494.              int spc_rows,
  495.              int spc_columns) {
  496.     OnError(::set_menu_spacing(menu,
  497.                    spc_description,
  498.                    spc_rows,
  499.                    spc_columns));
  500.   }
  501.  
  502.   // Get the spacing info for the menu
  503.   inline void Spacing(int& spc_description,
  504.               int& spc_rows,
  505.               int& spc_columns) const {
  506.     OnError(::menu_spacing(menu,
  507.                &spc_description,
  508.                &spc_rows,
  509.                &spc_columns));
  510.   }
  511.  
  512.   // Decorations
  513.   inline void frame(const char *title=NULL, const char* btitle=NULL) {
  514.     if (b_framed)
  515.       NCursesPanel::frame(title,btitle);
  516.     else
  517.       OnError(E_SYSTEM_ERROR);
  518.   }
  519.  
  520.   inline void boldframe(const char *title=NULL, const char* btitle=NULL) {
  521.     if (b_framed)
  522.       NCursesPanel::boldframe(title,btitle);
  523.     else
  524.       OnError(E_SYSTEM_ERROR);
  525.   }
  526.  
  527.   inline void label(const char *topLabel, const char *bottomLabel) {
  528.     if (b_framed)
  529.       NCursesPanel::label(topLabel,bottomLabel);
  530.     else
  531.       OnError(E_SYSTEM_ERROR);
  532.   }
  533.  
  534.   // -----
  535.   // Hooks
  536.   // -----
  537.  
  538.   // Called after the menu gets repositioned in its window.
  539.   // This is especially true if the menu is posted.
  540.   virtual void On_Menu_Init();
  541.  
  542.   // Called before the menu gets repositioned in its window.
  543.   // This is especially true if the menu is unposted.
  544.   virtual void On_Menu_Termination();
  545.  
  546.   // Called after the item became the current item
  547.   virtual void On_Item_Init(NCursesMenuItem& item);
  548.  
  549.   // Called before this item is left as current item.
  550.   virtual void On_Item_Termination(NCursesMenuItem& item);
  551.  
  552.   // Provide a default key virtualization. Translate the keyboard
  553.   // code c into a menu request code.
  554.   // The default implementation provides a hopefully straightforward
  555.   // mapping for the most common keystrokes and menu requests.
  556.   virtual int virtualize(int c);
  557.  
  558.  
  559.   // Operators
  560.   inline NCursesMenuItem* operator[](int i) const {
  561.     if ( (i < 0) || (i >= ::item_count (menu)) )
  562.       OnError (E_BAD_ARGUMENT);
  563.     return (my_items[i]);
  564.   }
  565.  
  566.   // Perform the menu's operation
  567.   // Return the item where you left the selection mark for a single
  568.   // selection menu, or NULL for a multivalued menu.
  569.   virtual NCursesMenuItem* operator()(void);
  570.  
  571.   // --------------------
  572.   // Exception handlers
  573.   // Called by operator()
  574.   // --------------------
  575.  
  576.   // Called if the request is denied
  577.   virtual void On_Request_Denied(int c) const;
  578.  
  579.   // Called if the item is not selectable
  580.   virtual void On_Not_Selectable(int c) const;
  581.  
  582.   // Called if pattern doesn't match
  583.   virtual void On_No_Match(int c) const;
  584.  
  585.   // Called if the command is unknown
  586.   virtual void On_Unknown_Command(int c) const;
  587.  
  588. };
  589. //
  590. // -------------------------------------------------------------------------
  591. // This is the typical C++ typesafe way to allow to attach
  592. // user data to an item of a menu. Its assumed that the user
  593. // data belongs to some class T. Use T as template argument
  594. // to create a UserItem.
  595. // -------------------------------------------------------------------------
  596. //
  597. template<class T> class NCURSES_IMPEXP NCursesUserItem : public NCursesMenuItem
  598. {
  599. public:
  600.   NCursesUserItem (const char* p_name,
  601.            const char* p_descript = NULL,
  602.            const T* p_UserData    = STATIC_CAST(T*)(0))
  603.     : NCursesMenuItem (p_name, p_descript) {
  604.       if (item)
  605.     OnError (::set_item_userptr (item, const_cast<void *>(reinterpret_cast<const void*>(p_UserData))));
  606.   }
  607.  
  608.   virtual ~NCursesUserItem() {}
  609.  
  610.   inline const T* UserData (void) const {
  611.     return reinterpret_cast<const T*>(::item_userptr (item));
  612.   };
  613.  
  614.   inline virtual void setUserData(const T* p_UserData) {
  615.     if (item)
  616.       OnError (::set_item_userptr (item, const_cast<void *>(reinterpret_cast<const void *>(p_UserData))));
  617.   }
  618. };
  619. //
  620. // -------------------------------------------------------------------------
  621. // The same mechanism is used to attach user data to a menu
  622. // -------------------------------------------------------------------------
  623. //
  624. template<class T> class NCURSES_IMPEXP NCursesUserMenu : public NCursesMenu
  625. {
  626. protected:
  627.   NCursesUserMenu( int  nlines,
  628.            int  ncols,
  629.            int  begin_y = 0,
  630.            int  begin_x = 0,
  631.            const T* p_UserData = STATIC_CAST(T*)(0))
  632.     : NCursesMenu(nlines,ncols,begin_y,begin_x) {
  633.       if (menu)
  634.     set_user (const_cast<void *>(p_UserData));
  635.   }
  636.  
  637. public:
  638.   NCursesUserMenu (NCursesMenuItem Items[],
  639.            const T* p_UserData = STATIC_CAST(T*)(0),
  640.            bool with_frame=FALSE,
  641.            bool autoDelete_Items=FALSE)
  642.     : NCursesMenu (Items, with_frame, autoDelete_Items) {
  643.       if (menu)
  644.     set_user (const_cast<void *>(p_UserData));
  645.   };
  646.  
  647.   NCursesUserMenu (NCursesMenuItem Items[],
  648.            int nlines,
  649.            int ncols,
  650.            int begin_y = 0,
  651.            int begin_x = 0,
  652.            const T* p_UserData = STATIC_CAST(T*)(0),
  653.            bool with_frame=FALSE)
  654.     : NCursesMenu (Items, nlines, ncols, begin_y, begin_x, with_frame) {
  655.       if (menu)
  656.     set_user (const_cast<void *>(p_UserData));
  657.   };
  658.  
  659.   virtual ~NCursesUserMenu() {
  660.   };
  661.  
  662.   inline T* UserData (void) const {
  663.     return reinterpret_cast<T*>(get_user ());
  664.   };
  665.  
  666.   inline virtual void setUserData (const T* p_UserData) {
  667.     if (menu)
  668.       set_user (const_cast<void *>(p_UserData));
  669.   }
  670. };
  671.  
  672. #endif /* NCURSES_CURSESM_H_incl */
  673.