Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /* PDCurses */
  2.  
  3. #include <curspriv.h>
  4.  
  5. /*man-start**************************************************************
  6.  
  7. slk
  8. ---
  9.  
  10. ### Synopsis
  11.  
  12.     int slk_init(int fmt);
  13.     int slk_set(int labnum, const char *label, int justify);
  14.     int slk_refresh(void);
  15.     int slk_noutrefresh(void);
  16.     char *slk_label(int labnum);
  17.     int slk_clear(void);
  18.     int slk_restore(void);
  19.     int slk_touch(void);
  20.     int slk_attron(const chtype attrs);
  21.     int slk_attr_on(const attr_t attrs, void *opts);
  22.     int slk_attrset(const chtype attrs);
  23.     int slk_attr_set(const attr_t attrs, short color_pair, void *opts);
  24.     int slk_attroff(const chtype attrs);
  25.     int slk_attr_off(const attr_t attrs, void *opts);
  26.     int slk_color(short color_pair);
  27.  
  28.     int slk_wset(int labnum, const wchar_t *label, int justify);
  29.  
  30.     int PDC_mouse_in_slk(int y, int x);
  31.     void PDC_slk_free(void);
  32.     void PDC_slk_initialize(void);
  33.  
  34.     wchar_t *slk_wlabel(int labnum)
  35.  
  36. ### Description
  37.  
  38.    These functions manipulate a window that contain Soft Label Keys
  39.    (SLK). To use the SLK functions, a call to slk_init() must be made
  40.    BEFORE initscr() or newterm(). slk_init() removes 1 or 2 lines from
  41.    the useable screen, depending on the format selected.
  42.  
  43.    The line(s) removed from the screen are used as a separate window, in
  44.    which SLKs are displayed.
  45.  
  46.    slk_init() requires a single parameter which describes the format of
  47.    the SLKs as follows:
  48.  
  49.    0       3-2-3 format
  50.    1       4-4 format
  51.    2       4-4-4 format (ncurses extension)
  52.    3       4-4-4 format with index line (ncurses extension)
  53.    2 lines used
  54.    55      5-5 format (pdcurses format)
  55.  
  56.    slk_refresh(), slk_noutrefresh() and slk_touch() are analogous to
  57.    refresh(), noutrefresh() and touch().
  58.  
  59. ### Return Value
  60.  
  61.    All functions return OK on success and ERR on error.
  62.  
  63. ### Portability
  64.                              X/Open  ncurses  NetBSD
  65.     slk_init                    Y       Y       Y
  66.     slk_set                     Y       Y       Y
  67.     slk_refresh                 Y       Y       Y
  68.     slk_noutrefresh             Y       Y       Y
  69.     slk_label                   Y       Y       Y
  70.     slk_clear                   Y       Y       Y
  71.     slk_restore                 Y       Y       Y
  72.     slk_touch                   Y       Y       Y
  73.     slk_attron                  Y       Y       Y
  74.     slk_attrset                 Y       Y       Y
  75.     slk_attroff                 Y       Y       Y
  76.     slk_attr_on                 Y       Y       Y
  77.     slk_attr_set                Y       Y       Y
  78.     slk_attr_off                Y       Y       Y
  79.     slk_wset                    Y       Y       Y
  80.     PDC_mouse_in_slk            -       -       -
  81.     PDC_slk_free                -       -       -
  82.     PDC_slk_initialize          -       -       -
  83.     slk_wlabel                  -       -       -
  84.  
  85. **man-end****************************************************************/
  86.  
  87. #include <stdlib.h>
  88.  
  89. enum { LABEL_NORMAL = 8, LABEL_EXTENDED = 10, LABEL_NCURSES_EXTENDED = 12 };
  90.  
  91. static int label_length = 0;
  92. static int labels = 0;
  93. static int label_fmt = 0;
  94. static int label_line = 0;
  95. static bool hidden = FALSE;
  96.  
  97. static struct SLK {
  98.     chtype label[32];
  99.     int len;
  100.     int format;
  101.     int start_col;
  102. } *slk = (struct SLK *)NULL;
  103.  
  104. /* slk_init() is the slk initialization routine.
  105.    This must be called before initscr().
  106.  
  107.    label_fmt = 0, 1 or 55.
  108.        0 = 3-2-3 format
  109.        1 = 4 - 4 format
  110.        2 = 4-4-4 format (ncurses extension for PC 12 function keys)
  111.        3 = 4-4-4 format (ncurses extension for PC 12 function keys -
  112.     with index line)
  113.       55 = 5 - 5 format (extended for PC, 10 function keys) */
  114.  
  115. int slk_init(int fmt)
  116. {
  117.     PDC_LOG(("slk_init() - called\n"));
  118.  
  119.     if (SP)
  120.         return ERR;
  121.  
  122.     switch (fmt)
  123.     {
  124.     case 0:  /* 3 - 2 - 3 */
  125.         labels = LABEL_NORMAL;
  126.         break;
  127.  
  128.     case 1:   /* 4 - 4 */
  129.         labels = LABEL_NORMAL;
  130.         break;
  131.  
  132.     case 2:   /* 4 4 4 */
  133.         labels = LABEL_NCURSES_EXTENDED;
  134.         break;
  135.  
  136.     case 3:   /* 4 4 4  with index */
  137.         labels = LABEL_NCURSES_EXTENDED;
  138.         break;
  139.  
  140.     case 55:  /* 5 - 5 */
  141.         labels = LABEL_EXTENDED;
  142.         break;
  143.  
  144.     default:
  145.         return ERR;
  146.     }
  147.  
  148.     label_fmt = fmt;
  149.  
  150.     slk = calloc(labels, sizeof(struct SLK));
  151.  
  152.     if (!slk)
  153.         labels = 0;
  154.  
  155.     return slk ? OK : ERR;
  156. }
  157.  
  158. /* draw a single button */
  159.  
  160. static void _drawone(int num)
  161. {
  162.     int i, col, slen;
  163.  
  164.     if (hidden)
  165.         return;
  166.  
  167.     slen = slk[num].len;
  168.  
  169.     switch (slk[num].format)
  170.     {
  171.     case 0:  /* LEFT */
  172.         col = 0;
  173.         break;
  174.  
  175.     case 1:  /* CENTER */
  176.         col = (label_length - slen) / 2;
  177.  
  178.         if (col + slen > label_length)
  179.             --col;
  180.         break;
  181.  
  182.     default:  /* RIGHT */
  183.         col = label_length - slen;
  184.     }
  185.  
  186.     wmove(SP->slk_winptr, label_line, slk[num].start_col);
  187.  
  188.     for (i = 0; i < label_length; ++i)
  189.         waddch(SP->slk_winptr, (i >= col && i < (col + slen)) ?
  190.                slk[num].label[i - col] : ' ');
  191. }
  192.  
  193. /* redraw each button */
  194.  
  195. static void _redraw(void)
  196. {
  197.     int i;
  198.  
  199.     for (i = 0; i < labels; ++i)
  200.         _drawone(i);
  201. }
  202.  
  203. /* slk_set() Used to set a slk label to a string.
  204.  
  205.    labnum  = 1 - 8 (or 10) (number of the label)
  206.    label   = string (8 or 7 bytes total), or NULL
  207.    justify = 0 : left, 1 : center, 2 : right  */
  208.  
  209. int slk_set(int labnum, const char *label, int justify)
  210. {
  211. #ifdef PDC_WIDE
  212.     wchar_t wlabel[32];
  213.  
  214.     PDC_mbstowcs(wlabel, label, 31);
  215.     return slk_wset(labnum, wlabel, justify);
  216. #else
  217.     PDC_LOG(("slk_set() - called\n"));
  218.  
  219.     if (labnum < 1 || labnum > labels || justify < 0 || justify > 2)
  220.         return ERR;
  221.  
  222.     labnum--;
  223.  
  224.     if (!label || !(*label))
  225.     {
  226.         /* Clear the label */
  227.  
  228.         *slk[labnum].label = 0;
  229.         slk[labnum].format = 0;
  230.         slk[labnum].len = 0;
  231.     }
  232.     else
  233.     {
  234.         int i, j = 0;
  235.  
  236.         /* Skip leading spaces */
  237.  
  238.         while (label[j] == ' ')
  239.             j++;
  240.  
  241.         /* Copy it */
  242.  
  243.         for (i = 0; i < label_length; i++)
  244.         {
  245.             chtype ch = label[i + j];
  246.  
  247.             slk[labnum].label[i] = ch;
  248.  
  249.             if (!ch)
  250.                 break;
  251.         }
  252.  
  253.         /* Drop trailing spaces */
  254.  
  255.         while ((i + j) && (label[i + j - 1] == ' '))
  256.             i--;
  257.  
  258.         slk[labnum].label[i] = 0;
  259.         slk[labnum].format = justify;
  260.         slk[labnum].len = i;
  261.     }
  262.  
  263.     _drawone(labnum);
  264.  
  265.     return OK;
  266. #endif
  267. }
  268.  
  269. int slk_refresh(void)
  270. {
  271.     PDC_LOG(("slk_refresh() - called\n"));
  272.  
  273.     return (slk_noutrefresh() == ERR) ? ERR : doupdate();
  274. }
  275.  
  276. int slk_noutrefresh(void)
  277. {
  278.     PDC_LOG(("slk_noutrefresh() - called\n"));
  279.  
  280.     if (!SP)
  281.         return ERR;
  282.  
  283.     return wnoutrefresh(SP->slk_winptr);
  284. }
  285.  
  286. char *slk_label(int labnum)
  287. {
  288.     static char temp[33];
  289. #ifdef PDC_WIDE
  290.     wchar_t *wtemp = slk_wlabel(labnum);
  291.  
  292.     PDC_wcstombs(temp, wtemp, 32);
  293. #else
  294.     chtype *p;
  295.     int i;
  296.  
  297.     PDC_LOG(("slk_label() - called\n"));
  298.  
  299.     if (labnum < 1 || labnum > labels)
  300.         return (char *)0;
  301.  
  302.     for (i = 0, p = slk[labnum - 1].label; *p; i++)
  303.         temp[i] = *p++;
  304.  
  305.     temp[i] = '\0';
  306. #endif
  307.     return temp;
  308. }
  309.  
  310. int slk_clear(void)
  311. {
  312.     PDC_LOG(("slk_clear() - called\n"));
  313.  
  314.     if (!SP)
  315.         return ERR;
  316.  
  317.     hidden = TRUE;
  318.     werase(SP->slk_winptr);
  319.     return wrefresh(SP->slk_winptr);
  320. }
  321.  
  322. int slk_restore(void)
  323. {
  324.     PDC_LOG(("slk_restore() - called\n"));
  325.  
  326.     if (!SP)
  327.         return ERR;
  328.  
  329.     hidden = FALSE;
  330.     _redraw();
  331.     return wrefresh(SP->slk_winptr);
  332. }
  333.  
  334. int slk_touch(void)
  335. {
  336.     PDC_LOG(("slk_touch() - called\n"));
  337.  
  338.     if (!SP)
  339.         return ERR;
  340.  
  341.     return touchwin(SP->slk_winptr);
  342. }
  343.  
  344. int slk_attron(const chtype attrs)
  345. {
  346.     int rc;
  347.  
  348.     PDC_LOG(("slk_attron() - called\n"));
  349.  
  350.     if (!SP)
  351.         return ERR;
  352.  
  353.     rc = wattron(SP->slk_winptr, attrs);
  354.     _redraw();
  355.  
  356.     return rc;
  357. }
  358.  
  359. int slk_attr_on(const attr_t attrs, void *opts)
  360. {
  361.     PDC_LOG(("slk_attr_on() - called\n"));
  362.  
  363.     return slk_attron(attrs);
  364. }
  365.  
  366. int slk_attroff(const chtype attrs)
  367. {
  368.     int rc;
  369.  
  370.     PDC_LOG(("slk_attroff() - called\n"));
  371.  
  372.     if (!SP)
  373.         return ERR;
  374.  
  375.     rc = wattroff(SP->slk_winptr, attrs);
  376.     _redraw();
  377.  
  378.     return rc;
  379. }
  380.  
  381. int slk_attr_off(const attr_t attrs, void *opts)
  382. {
  383.     PDC_LOG(("slk_attr_off() - called\n"));
  384.  
  385.     return slk_attroff(attrs);
  386. }
  387.  
  388. int slk_attrset(const chtype attrs)
  389. {
  390.     int rc;
  391.  
  392.     PDC_LOG(("slk_attrset() - called\n"));
  393.  
  394.     if (!SP)
  395.         return ERR;
  396.  
  397.     rc = wattrset(SP->slk_winptr, attrs);
  398.     _redraw();
  399.  
  400.     return rc;
  401. }
  402.  
  403. int slk_color(short color_pair)
  404. {
  405.     int rc;
  406.  
  407.     PDC_LOG(("slk_color() - called\n"));
  408.  
  409.     if (!SP)
  410.         return ERR;
  411.  
  412.     rc = wcolor_set(SP->slk_winptr, color_pair, NULL);
  413.     _redraw();
  414.  
  415.     return rc;
  416. }
  417.  
  418. int slk_attr_set(const attr_t attrs, short color_pair, void *opts)
  419. {
  420.     PDC_LOG(("slk_attr_set() - called\n"));
  421.  
  422.     return slk_attrset(attrs | COLOR_PAIR(color_pair));
  423. }
  424.  
  425. static void _slk_calc(void)
  426. {
  427.     int i, center, col = 0;
  428.     label_length = COLS / labels;
  429.  
  430.     if (label_length > 31)
  431.         label_length = 31;
  432.  
  433.     switch (label_fmt)
  434.     {
  435.     case 0:     /* 3 - 2 - 3 F-Key layout */
  436.  
  437.         --label_length;
  438.  
  439.         slk[0].start_col = col;
  440.         slk[1].start_col = (col += label_length);
  441.         slk[2].start_col = (col += label_length);
  442.  
  443.         center = COLS / 2;
  444.  
  445.         slk[3].start_col = center - label_length + 1;
  446.         slk[4].start_col = center + 1;
  447.  
  448.         col = COLS - (label_length * 3) + 1;
  449.  
  450.         slk[5].start_col = col;
  451.         slk[6].start_col = (col += label_length);
  452.         slk[7].start_col = (col += label_length);
  453.         break;
  454.  
  455.     case 1:     /* 4 - 4 F-Key layout */
  456.  
  457.         for (i = 0; i < 8; i++)
  458.         {
  459.             slk[i].start_col = col;
  460.             col += label_length;
  461.  
  462.             if (i == 3)
  463.                 col = COLS - (label_length * 4) + 1;
  464.         }
  465.  
  466.         break;
  467.  
  468.     case 2:     /* 4 4 4 F-Key layout */
  469.     case 3:     /* 4 4 4 F-Key layout with index */
  470.  
  471.         for (i = 0; i < 4; i++)
  472.         {
  473.             slk[i].start_col = col;
  474.             col += label_length;
  475.         }
  476.  
  477.         center = COLS / 2;
  478.  
  479.         slk[4].start_col = center - (label_length * 2) + 1;
  480.         slk[5].start_col = center - label_length + 1;
  481.         slk[6].start_col = center + 1;
  482.         slk[7].start_col = center + label_length + 1;
  483.  
  484.         col = COLS - (label_length * 4) + 1;
  485.  
  486.         for (i = 8; i < 12; i++)
  487.         {
  488.             slk[i].start_col = col;
  489.             col += label_length;
  490.         }
  491.  
  492.         break;
  493.  
  494.     default:    /* 5 - 5 F-Key layout */
  495.  
  496.         for (i = 0; i < 10; i++)
  497.         {
  498.             slk[i].start_col = col;
  499.             col += label_length;
  500.  
  501.             if (i == 4)
  502.                 col = COLS - (label_length * 5) + 1;
  503.         }
  504.     }
  505.  
  506.     --label_length;
  507.  
  508.     /* make sure labels are all in window */
  509.  
  510.     _redraw();
  511. }
  512.  
  513. void PDC_slk_initialize(void)
  514. {
  515.     if (slk)
  516.     {
  517.         if (label_fmt == 3)
  518.         {
  519.             SP->slklines = 2;
  520.             label_line = 1;
  521.         }
  522.         else
  523.             SP->slklines = 1;
  524.  
  525.         if (!SP->slk_winptr)
  526.         {
  527.             SP->slk_winptr = newwin(SP->slklines, COLS,
  528.                                     LINES - SP->slklines, 0);
  529.             if (!SP->slk_winptr)
  530.                 return;
  531.  
  532.             wattrset(SP->slk_winptr, A_REVERSE);
  533.         }
  534.  
  535.         _slk_calc();
  536.  
  537.         /* if we have an index line, display it now */
  538.  
  539.         if (label_fmt == 3)
  540.         {
  541.             chtype save_attr;
  542.             int i;
  543.  
  544.             save_attr = SP->slk_winptr->_attrs;
  545.             wattrset(SP->slk_winptr, A_NORMAL);
  546.             wmove(SP->slk_winptr, 0, 0);
  547.             whline(SP->slk_winptr, 0, COLS);
  548.  
  549.             for (i = 0; i < labels; i++)
  550.                 mvwprintw(SP->slk_winptr, 0, slk[i].start_col, "F%d", i + 1);
  551.  
  552.             SP->slk_winptr->_attrs = save_attr;
  553.         }
  554.  
  555.         touchwin(SP->slk_winptr);
  556.     }
  557. }
  558.  
  559. void PDC_slk_free(void)
  560. {
  561.     if (slk)
  562.     {
  563.         if (SP->slk_winptr)
  564.         {
  565.             delwin(SP->slk_winptr);
  566.             SP->slk_winptr = (WINDOW *)NULL;
  567.         }
  568.  
  569.         free(slk);
  570.         slk = (struct SLK *)NULL;
  571.  
  572.         label_length = 0;
  573.         labels = 0;
  574.         label_fmt = 0;
  575.         label_line = 0;
  576.         hidden = FALSE;
  577.     }
  578. }
  579.  
  580. int PDC_mouse_in_slk(int y, int x)
  581. {
  582.     int i;
  583.  
  584.     PDC_LOG(("PDC_mouse_in_slk() - called: y->%d x->%d\n", y, x));
  585.  
  586.     /* If the line on which the mouse was clicked is NOT the last line
  587.        of the screen, we are not interested in it. */
  588.  
  589.     if (!slk || !SP->slk_winptr || (y != SP->slk_winptr->_begy + label_line))
  590.         return 0;
  591.  
  592.     for (i = 0; i < labels; i++)
  593.         if (x >= slk[i].start_col && x < (slk[i].start_col + label_length))
  594.             return i + 1;
  595.  
  596.     return 0;
  597. }
  598.  
  599. #ifdef PDC_WIDE
  600. int slk_wset(int labnum, const wchar_t *label, int justify)
  601. {
  602.     PDC_LOG(("slk_wset() - called\n"));
  603.  
  604.     if (labnum < 1 || labnum > labels || justify < 0 || justify > 2)
  605.         return ERR;
  606.  
  607.     labnum--;
  608.  
  609.     if (!label || !(*label))
  610.     {
  611.         /* Clear the label */
  612.  
  613.         *slk[labnum].label = 0;
  614.         slk[labnum].format = 0;
  615.         slk[labnum].len = 0;
  616.     }
  617.     else
  618.     {
  619.         int i, j = 0;
  620.  
  621.         /* Skip leading spaces */
  622.  
  623.         while (label[j] == L' ')
  624.             j++;
  625.  
  626.         /* Copy it */
  627.  
  628.         for (i = 0; i < label_length; i++)
  629.         {
  630.             chtype ch = label[i + j];
  631.  
  632.             slk[labnum].label[i] = ch;
  633.  
  634.             if (!ch)
  635.                 break;
  636.         }
  637.  
  638.         /* Drop trailing spaces */
  639.  
  640.         while ((i + j) && (label[i + j - 1] == L' '))
  641.             i--;
  642.  
  643.         slk[labnum].label[i] = 0;
  644.         slk[labnum].format = justify;
  645.         slk[labnum].len = i;
  646.     }
  647.  
  648.     _drawone(labnum);
  649.  
  650.     return OK;
  651. }
  652.  
  653. wchar_t *slk_wlabel(int labnum)
  654. {
  655.     static wchar_t temp[33];
  656.     chtype *p;
  657.     int i;
  658.  
  659.     PDC_LOG(("slk_wlabel() - called\n"));
  660.  
  661.     if (labnum < 1 || labnum > labels)
  662.         return (wchar_t *)0;
  663.  
  664.     for (i = 0, p = slk[labnum - 1].label; *p; i++)
  665.         temp[i] = *p++;
  666.  
  667.     temp[i] = '\0';
  668.  
  669.     return temp;
  670. }
  671. #endif
  672.