3 Minimum Profit - Programmer Text Editor
7 Copyright (C) 1991-2012 Angel Ortega <angel@triptico.com>
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License
11 as published by the Free Software Foundation; either version 2
12 of the License, or (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 http://www.triptico.com
39 #include <sys/ioctl.h>
41 #include <ncursesw/ncurses.h>
50 /* the curses attributes */
53 /* code for the 'normal' attribute */
54 static int normal_attr
= 0;
57 static WINDOW
*cw
= NULL
;
59 /* stack of windows */
60 static int n_stack
= 0;
61 static WINDOW
**w_stack
= NULL
;
64 static int last_attr
= 0;
67 static int timer_msecs
= 0;
68 static mpdm_t timer_func
= NULL
;
72 static void set_attr(void)
73 /* set the current and fill attributes */
75 wattrset(cw
, nc_attrs
[last_attr
]);
76 wbkgdset(cw
, ' ' | nc_attrs
[last_attr
]);
80 #ifndef NCURSES_VERSION
82 static void nc_sigwinch(int s
)
83 /* SIGWINCH signal handler */
87 /* invalidate main window */
91 /* re-set dimensions */
92 v
= mpdm_hget_s(mp
, L
"window");
93 mpdm_hset_s(v
, L
"tx", MPDM_I(COLS
));
94 mpdm_hset_s(v
, L
"ty", MPDM_I(LINES
));
97 signal(SIGWINCH
, nc_sigwinch
);
103 #ifdef CONFOPT_WGET_WCH
104 int wget_wch(WINDOW
* w
, wint_t * ch
);
107 static wchar_t *nc_getwch(void)
108 /* gets a key as a wchar_t */
112 #ifdef CONFOPT_WGET_WCH
114 /* set timer period */
116 timeout(timer_msecs
);
118 if (wget_wch(stdscr
, (wint_t *) c
) == -1)
119 c
[0] = (wchar_t) - 1;
122 char tmp
[MB_CUR_MAX
+ 1];
132 /* set to non-blocking */
135 /* read all possible following characters */
137 while (n
< sizeof(tmp
) - 1 && (cc
= getch()) != ERR
)
140 /* sets input as blocking */
152 #define ctrl(k) ((k) & 31)
154 static mpdm_t
nc_getkey(mpdm_t args
, mpdm_t ctxt
)
155 /* reads a key and converts to an action */
157 static int shift
= 0;
161 /* any pending key? return it */
162 if ((k
= mp_pending_key()) != NULL
)
168 mpdm_void(mpdm_exec(timer_func
, NULL
, NULL
));
205 f
= L
"alt-cursor-left";
208 f
= L
"alt-cursor-right";
211 f
= L
"alt-cursor-down";
214 f
= L
"alt-cursor-up";
491 /* handle ncurses resizing */
494 mpdm_t v
= mpdm_hget_s(mp
, L
"window");
495 mpdm_hset_s(v
, L
"tx", MPDM_I(COLS
));
496 mpdm_hset_s(v
, L
"ty", MPDM_I(LINES
));
510 k
= mpdm_ref(MPDM_S(f
));
512 if ((t
= mp_process_keyseq(k
)) != k
) {
524 static mpdm_t
nc_addwstr(mpdm_t str
)
527 wchar_t *wptr
= mpdm_string(str
);
529 #ifndef CONFOPT_ADDWSTR
532 cptr
= mpdm_wcstombs(wptr
, NULL
);
538 #endif /* CONFOPT_ADDWSTR */
544 static mpdm_t
nc_doc_draw(mpdm_t args
, mpdm_t ctxt
)
545 /* draws the document part */
552 d
= mpdm_aget(args
, 0);
553 d
= mpdm_ref(mp_draw(d
, 0));
555 for (n
= 0; n
< mpdm_size(d
); n
++) {
556 mpdm_t l
= mpdm_aget(d
, n
);
560 for (m
= 0; m
< mpdm_size(l
); m
++) {
564 /* get the attribute and the string */
565 attr
= mpdm_ival(mpdm_aget(l
, m
++));
568 wattrset(cw
, nc_attrs
[attr
]);
579 static void build_colors(void)
580 /* builds the colors */
588 #ifdef CONFOPT_TRANSPARENCY
589 use_default_colors();
591 #define DEFAULT_INK -1
592 #define DEFAULT_PAPER -1
594 #else /* CONFOPT_TRANSPARENCY */
596 #define DEFAULT_INK COLOR_BLACK
597 #define DEFAULT_PAPER COLOR_WHITE
601 /* gets the color definitions and attribute names */
602 colors
= mpdm_hget_s(mp
, L
"colors");
603 color_names
= mpdm_hget_s(mp
, L
"color_names");
604 l
= mpdm_ref(mpdm_keys(colors
));
607 /* redim the structures */
608 nc_attrs
= realloc(nc_attrs
, sizeof(int) * s
);
610 /* loop the colors */
611 for (n
= 0; n
< s
&& (c
= mpdm_aget(l
, n
)) != NULL
; n
++) {
612 mpdm_t d
= mpdm_hget(colors
, c
);
613 mpdm_t v
= mpdm_hget_s(d
, L
"text");
616 /* store the 'normal' attribute */
617 if (wcscmp(mpdm_string(c
), L
"normal") == 0)
621 mpdm_hset_s(d
, L
"attr", MPDM_I(n
));
623 /* get color indexes */
624 if ((c0
= mpdm_seek(color_names
, mpdm_aget(v
, 0), 1)) == -1 ||
625 (c1
= mpdm_seek(color_names
, mpdm_aget(v
, 1), 1)) == -1)
628 init_pair(n
+ 1, c0
- 1, c1
- 1);
629 cp
= COLOR_PAIR(n
+ 1);
632 v
= mpdm_hget_s(d
, L
"flags");
633 if (mpdm_seek_s(v
, L
"reverse", 1) != -1)
635 if (mpdm_seek_s(v
, L
"bright", 1) != -1)
637 if (mpdm_seek_s(v
, L
"underline", 1) != -1)
643 /* set the background filler */
644 wbkgdset(cw
, ' ' | nc_attrs
[normal_attr
]);
650 /** driver functions **/
652 static mpdm_t
ncursesw_drv_timer(mpdm_t a
, mpdm_t ctxt
)
654 mpdm_t func
= mpdm_aget(a
, 1);
656 timer_msecs
= mpdm_ival(mpdm_aget(a
, 0));
659 mpdm_unref(timer_func
);
666 static mpdm_t
ncursesw_drv_shutdown(mpdm_t a
, mpdm_t ctxt
)
672 if ((v
= mpdm_hget_s(mp
, L
"exit_message")) != NULL
) {
673 mpdm_write_wcs(stdout
, mpdm_string(v
));
683 static mpdm_t
tui_addstr(mpdm_t a
, mpdm_t ctxt
)
684 /* TUI: add a string */
686 return nc_addwstr(mpdm_aget(a
, 0));
690 static mpdm_t
tui_move(mpdm_t a
, mpdm_t ctxt
)
691 /* TUI: move to a screen position */
693 /* curses' move() use y, x */
694 wmove(cw
, mpdm_ival(mpdm_aget(a
, 1)), mpdm_ival(mpdm_aget(a
, 0)));
696 /* if third argument is not NULL, clear line */
697 if (mpdm_aget(a
, 2) != NULL
)
704 static mpdm_t
tui_attr(mpdm_t a
, mpdm_t ctxt
)
705 /* TUI: set attribute for next string */
707 last_attr
= mpdm_ival(mpdm_aget(a
, 0));
715 static mpdm_t
tui_refresh(mpdm_t a
, mpdm_t ctxt
)
716 /* TUI: refresh the screen */
723 static mpdm_t
tui_getxy(mpdm_t a
, mpdm_t ctxt
)
724 /* TUI: returns the x and y cursor position */
734 mpdm_aset(v
, MPDM_I(x
), 0);
735 mpdm_aset(v
, MPDM_I(y
), 1);
743 static mpdm_t
tui_openpanel(mpdm_t a
, mpdm_t ctxt
)
744 /* opens a panel (creates new window) */
747 w_stack
= realloc(w_stack
, n_stack
* sizeof(WINDOW
*));
748 cw
= w_stack
[n_stack
- 1] = newwin(mpdm_ival(mpdm_aget(a
, 3)),
749 mpdm_ival(mpdm_aget(a
, 2)),
750 mpdm_ival(mpdm_aget(a
, 1)),
751 mpdm_ival(mpdm_aget(a
, 0)));
761 static mpdm_t
tui_closepanel(mpdm_t a
, mpdm_t ctxt
)
762 /* closes a panel (deletes last window) */
765 delwin(w_stack
[n_stack
]);
767 w_stack
= realloc(w_stack
, n_stack
* sizeof(WINDOW
*));
768 cw
= n_stack
== 0 ? stdscr
: w_stack
[n_stack
- 1];
777 static void register_functions(void)
782 drv
= mpdm_hget_s(mp
, L
"drv");
783 mpdm_hset_s(drv
, L
"timer", MPDM_X(ncursesw_drv_timer
));
784 mpdm_hset_s(drv
, L
"shutdown", MPDM_X(ncursesw_drv_shutdown
));
786 tui
= mpsl_eval(MPDM_LS(L
"load('mp_tui.mpsl');"), NULL
, NULL
);
788 /* FIXME: if tui failed, a fatal error must be shown */
790 /* if((e = mpdm_hget_s(mpdm_root(), L"ERROR")) != NULL)
792 mpdm_write_wcs(stdout, mpdm_string(e));
799 mpdm_hset_s(tui
, L
"getkey", MPDM_X(nc_getkey
));
800 mpdm_hset_s(tui
, L
"addstr", MPDM_X(tui_addstr
));
801 mpdm_hset_s(tui
, L
"move", MPDM_X(tui_move
));
802 mpdm_hset_s(tui
, L
"attr", MPDM_X(tui_attr
));
803 mpdm_hset_s(tui
, L
"refresh", MPDM_X(tui_refresh
));
804 mpdm_hset_s(tui
, L
"getxy", MPDM_X(tui_getxy
));
805 mpdm_hset_s(tui
, L
"openpanel", MPDM_X(tui_openpanel
));
806 mpdm_hset_s(tui
, L
"closepanel", MPDM_X(tui_closepanel
));
807 mpdm_hset_s(tui
, L
"doc_draw", MPDM_X(nc_doc_draw
));
811 static mpdm_t
ncursesw_drv_startup(mpdm_t a
)
815 register_functions();
819 keypad(stdscr
, TRUE
);
826 v
= mpdm_hget_s(mp
, L
"window");
827 mpdm_hset_s(v
, L
"tx", MPDM_I(COLS
));
828 mpdm_hset_s(v
, L
"ty", MPDM_I(LINES
));
830 #ifndef NCURSES_VERSION
831 signal(SIGWINCH
, nc_sigwinch
);
840 int ncursesw_drv_detect(int *argc
, char ***argv
)
844 drv
= mpdm_hget_s(mp
, L
"drv");
845 mpdm_hset_s(drv
, L
"id", MPDM_LS(L
"curses"));
846 mpdm_hset_s(drv
, L
"startup", MPDM_X(ncursesw_drv_startup
));
851 #endif /* CONFOPT_CURSES */