3 Copyright (C) 2007-2009 Jörg Pfähler
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 #include <libOS/LIBUNIX_glue.h>
25 #include <libOS/LIBC_glue.h>
28 #include <libserver/console.h>
29 #include <libOS/lightOS/internal/curses.h>
31 // TODO: curses mode can be paused through endwin() and started again through a refresh
33 #define MAKE_COLOR_PAIR(foreground, background) (((background) << 4) | (foreground))
35 // Define the SCREEN modes
36 #define SCREEN_MODE_ECHO 0x01
37 #define SCREEN_MODE_CBREAK 0x02
38 #define SCREEN_MODE_KEYPAD 0x04
39 #define SCREEN_MODE_NEWLINE_TRANSLATION 0x08
41 // Define the WINDOW modes
42 #define WINDOW_MODE_NO_DELAY 0x01
44 struct _LIBUNIX_WINDOW
54 struct _LIBUNIX_WINDOW
*parent
;
55 struct _LIBUNIX_SCREEN
*screen
;
58 struct _LIBUNIX_SCREEN
72 WINDOW
*curscr
= NULL
;
73 WINDOW
*stdscr
= NULL
;
75 // File-local variables
76 static SCREEN
*_LIBUNIX_cur_screen
= NULL
;
80 // File-local functions
83 static int _LIBUNIX_move_cursor(int x
, int y
)
85 assert(_LIBUNIX_cur_screen
!= NULL
);
87 // Set the 'hardware' cursor
88 _LIBSERVER_CONSOLE_SET_CURSOR(_LIBUNIX_cur_screen
->outfile
, x
, y
);
94 // Initialization functions
97 SCREEN
*newterm(char *type
,
101 // NOTE: type is ignored
102 assert(outfile
!= NULL
);
103 assert(infile
!= NULL
);
105 // Allocate memory for the SCREEN
106 SCREEN
*Screen
= malloc(sizeof(SCREEN
));
110 // Initialize the SCREEN
113 Screen
->infile
= infile
;
114 Screen
->outfile
= outfile
;
115 Screen
->mode
= SCREEN_MODE_ECHO
| SCREEN_MODE_NEWLINE_TRANSLATION
;
117 // Allocate memory for stdscr
118 Screen
->stdscr
= malloc(sizeof(WINDOW
));
119 if (Screen
->stdscr
== NULL
)
121 if (_LIBOS_init_window(&Screen
->stdscr
->osdep
,
125 goto error_stdscr_init
;
127 // Initialize the stdscr
128 Screen
->stdscr
->x
= 0;
129 Screen
->stdscr
->y
= 0;
130 Screen
->stdscr
->width
= Screen
->width
;
131 Screen
->stdscr
->height
= Screen
->height
;
132 Screen
->stdscr
->cursor
= 0;
133 Screen
->stdscr
->color
= MAKE_COLOR_PAIR(COLOR_WHITE
, COLOR_BLACK
);
134 Screen
->stdscr
->mode
= 0;
135 Screen
->stdscr
->parent
= NULL
;
136 Screen
->stdscr
->screen
= Screen
;
138 // Allocate memory for curscr
139 Screen
->curscr
= malloc(sizeof(WINDOW
));
140 if (Screen
->curscr
== NULL
)goto error_curscr
;
141 if (_LIBOS_init_window(&Screen
->curscr
->osdep
,
145 goto error_curscr_init
;
147 // Initialize the curscr
148 Screen
->curscr
->x
= 0;
149 Screen
->curscr
->y
= 0;
150 Screen
->curscr
->width
= Screen
->width
;
151 Screen
->curscr
->height
= Screen
->height
;
152 Screen
->curscr
->cursor
= 0;
153 Screen
->curscr
->color
= MAKE_COLOR_PAIR(COLOR_WHITE
, COLOR_BLACK
);
154 Screen
->curscr
->mode
= 0;
155 Screen
->curscr
->parent
= NULL
;
156 Screen
->curscr
->screen
= Screen
;
158 // Disable 'hardware' echoing
160 _LIBSERVER_CONSOLE_HW_ECHO(Screen
->outfile
, false);
164 _LIBSERVER_CONSOLE_CLEAR(Screen
->outfile
);
166 // Set current SCREEN, stdscr & curscr
167 if (_LIBUNIX_cur_screen
== NULL
)
173 free(Screen
->curscr
);
175 _LIBOS_deinit_window(&Screen
->stdscr
->osdep
);
177 free(Screen
->stdscr
);
183 SCREEN
*set_term(SCREEN
*newterm
)
185 curscr
= newterm
->curscr
;
186 stdscr
= newterm
->stdscr
;
187 COLS
= newterm
->width
;
188 LINES
= newterm
->height
;
190 SCREEN
*tmp
= _LIBUNIX_cur_screen
;
191 _LIBUNIX_cur_screen
= newterm
;
197 if (newterm(NULL
, stdout
, stdin
) == NULL
)
199 // TODO: What should we do here?
200 _LIBOS_WARNING("libunix", "failed");
206 void _LIBUNIX_getyx(const WINDOW
*win
, int *y
, int *x
)
208 *y
= (win
->cursor
/ 2) / win
->width
;
209 *x
= (win
->cursor
/ 2) % win
->width
;
212 void _LIBUNIX_getbegyx(const WINDOW
*win
, int *y
, int *x
)
218 void _LIBUNIX_getmaxyx(const WINDOW
*win
, int *y
, int *x
)
232 assert(_LIBUNIX_cur_screen
!= NULL
);
233 _LIBUNIX_cur_screen
->mode
|= SCREEN_MODE_ECHO
;
239 assert(_LIBUNIX_cur_screen
!= NULL
);
240 _LIBUNIX_cur_screen
->mode
&= ~SCREEN_MODE_ECHO
;
246 assert(_LIBUNIX_cur_screen
!= NULL
);
247 _LIBUNIX_cur_screen
->mode
|= SCREEN_MODE_CBREAK
;
248 fflush(_LIBUNIX_cur_screen
->outfile
);
249 fprintf(_LIBUNIX_cur_screen
->outfile
, "\x1B]B");
250 fflush(_LIBUNIX_cur_screen
->outfile
);
256 assert(_LIBUNIX_cur_screen
!= NULL
);
257 _LIBUNIX_cur_screen
->mode
&= ~SCREEN_MODE_CBREAK
;
258 fflush(_LIBUNIX_cur_screen
->outfile
);
259 fprintf(_LIBUNIX_cur_screen
->outfile
, "\x1B[B");
260 fflush(_LIBUNIX_cur_screen
->outfile
);
266 _LIBOS_WARNING("libunix", "not implemented");
272 _LIBOS_WARNING("libunix", "not implemented");
278 assert(_LIBUNIX_cur_screen
!= NULL
);
279 _LIBUNIX_cur_screen
->mode
|= SCREEN_MODE_NEWLINE_TRANSLATION
;
285 assert(_LIBUNIX_cur_screen
!= NULL
);
286 _LIBUNIX_cur_screen
->mode
&= ~SCREEN_MODE_NEWLINE_TRANSLATION
;
290 int keypad(WINDOW
*win
, bool bf
)
293 if (bf
== true)win
->mode
|= SCREEN_MODE_KEYPAD
;
294 else win
->mode
&= ~SCREEN_MODE_KEYPAD
;
298 int nodelay(WINDOW
*win
, bool bf
)
303 win
->mode
|= WINDOW_MODE_NO_DELAY
;
305 win
->mode
&= ~WINDOW_MODE_NO_DELAY
;
312 // Control the cursor modes
315 int curs_set(int visibility
)
317 assert(_LIBUNIX_cur_screen
!= NULL
);
319 fflush(_LIBUNIX_cur_screen
->outfile
);
320 const char *string
= NULL
;
325 fprintf(_LIBUNIX_cur_screen
->outfile
, string
);
326 fflush(_LIBUNIX_cur_screen
->outfile
);
335 WINDOW
*newwin(int nlines
, int ncols
, int begin_y
, int begin_x
)
337 assert(_LIBUNIX_cur_screen
!= NULL
);
340 ncols
= COLS
- begin_x
;
342 nlines
= LINES
- begin_y
;
344 // Allocate memory for the window
345 WINDOW
*window
= malloc(sizeof(WINDOW
));
348 if (_LIBOS_init_window(&window
->osdep
, nlines
, ncols
, FALSE
) == FALSE
)
354 // Initialize the window
357 window
->width
= ncols
;
358 window
->height
= nlines
;
360 window
->color
= MAKE_COLOR_PAIR(COLOR_WHITE
, COLOR_BLACK
);
362 window
->parent
= stdscr
;
363 window
->screen
= _LIBUNIX_cur_screen
;
370 assert(_LIBUNIX_cur_screen
!= NULL
);
372 // Restore the cursor
373 if (curs_set(1) == ERR
)return ERR
;
375 // Enable 'hardware' echoing
377 fflush(_LIBUNIX_cur_screen
->outfile
);
378 fprintf(_LIBUNIX_cur_screen
->outfile
, "\x1B[E");
379 fflush(_LIBUNIX_cur_screen
->outfile
);
383 fprintf(_LIBUNIX_cur_screen
->outfile
, "\x1B[C");
384 fflush(_LIBUNIX_cur_screen
->outfile
);
386 // Deallocate memory for the SCREEN, curscr & stdscr
388 // free(_cur_screen->stdscr);
389 // free(_cur_screen->curscr);
390 // free(_cur_screen);
392 // Reset current SCREEN, stdscr & curscr
393 // _cur_screen = NULL;
402 int wclear(WINDOW
*win
)
408 memset(_LIBOS_window_data(&win
->osdep
),
410 win
->width
* win
->height
* 2);
415 int werase(WINDOW
*win
)
420 int wmove(WINDOW
*win
, int y
, int x
)
423 assert(x
< win
->width
);
424 assert(y
< win
->height
);
426 win
->cursor
= (win
->width
* y
+ x
) * 2;
430 int waddch(WINDOW
*win
, const chtype ch
)
434 // Get a pointer to the memory
435 char *Data
= _LIBOS_window_data(&win
->osdep
);
437 // Write the character to the memory
440 // NOTE: to static terminal size
441 win
->cursor
-= win
->cursor
% 160;
446 Data
[win
->cursor
] = (char)ch
;
447 Data
[win
->cursor
+ 1] = win
->color
;
453 // TODO: replace spaces with the background character (should be \0)
456 // TODO: Special character processing
460 int mvwaddch(WINDOW
*win
, int y
, int x
, const chtype ch
)
465 if (wmove(win
, y
, x
) != OK
)return ERR
;
468 return waddch(win
, ch
);
471 int waddstr(WINDOW
*win
, const char *str
)
473 return waddnstr(win
, str
, -1);
476 int waddnstr(WINDOW
*win
, const char *str
, int n
)
480 if (n
== -1)n
= strlen(str
);
482 for (int i
= 0;i
< n
;i
++)
484 if (str
[i
] == '\0')break;
491 int mvwaddstr(WINDOW
*win
, int y
, int x
, const char *str
)
493 return mvwaddnstr(win
, y
, x
, str
, -1);
496 int mvwaddnstr(WINDOW
*win
, int y
, int x
, const char *str
, int n
)
501 if (wmove(win
, y
, x
) != OK
)return ERR
;
504 return waddnstr(win
, str
, n
);
507 static int var_wprintw(WINDOW
*win
, const char *fmt
, va_list args
)
510 va_copy(argcopy
, args
);
511 int result
= vsnprintf(0, 0, fmt
, argcopy
);
513 if (result
< 0)return ERR
;
514 char *array
= malloc(result
+ 1);
515 result
= vsnprintf(array
, result
+ 1, fmt
, args
);
526 int printw(const char *fmt
, ...)
530 int result
= var_wprintw(stdscr
, fmt
, args
);
535 int wprintw(WINDOW
*win
, const char *fmt
, ...)
539 int result
= var_wprintw(win
, fmt
, args
);
544 static int var_mvwprintw(WINDOW
*win
, int y
, int x
, const char *fmt
, va_list args
)
547 va_copy(argcopy
, args
);
548 int result
= vsnprintf(0, 0, fmt
, argcopy
);
550 if (result
< 0)return ERR
;
551 char *array
= malloc(result
+ 1);
552 result
= vsnprintf(array
, result
+ 1, fmt
, args
);
558 mvwaddstr(win
, y
, x
, array
);
563 int mvprintw(int y
, int x
, const char *fmt
, ...)
567 int result
= var_mvwprintw(stdscr
, y
, x
, fmt
, args
);
572 int mvwprintw(WINDOW
*win
, int y
, int x
, const char *fmt
, ...)
576 int result
= var_mvwprintw(win
, y
, x
, fmt
, args
);
585 int wattroff(WINDOW
*win
, int attrs
)
589 if ((attrs
& A_REVERSE
) != 0)
591 win
->color
= MAKE_COLOR_PAIR(COLOR_WHITE
, COLOR_BLACK
);
594 if ((attrs
& (~(A_REVERSE
))) != 0)
596 _LIBOS_WARNING("libunix", "unimplemented attribute");
602 int wattron(WINDOW
*win
, int attrs
)
606 if ((attrs
& A_REVERSE
) != 0)
608 win
->color
= MAKE_COLOR_PAIR(COLOR_BLACK
, COLOR_WHITE
);
611 if ((attrs
& (~(A_REVERSE
))) != 0)
613 _LIBOS_WARNING("libunix", "unimplemented attribute");
621 int mvwgetch(WINDOW
*win
, int y
, int x
)
626 if (wmove(win
, y
, x
) != OK
)return ERR
;
630 int wgetch(WINDOW
*win
)
634 // TODO: Is window a Pad?
638 if ((win
->mode
& WINDOW_MODE_NO_DELAY
) != 0)
641 _LIBSERVER_key_t Key
;
647 int character
= fgetc(win
->screen
->infile
);
648 if (character
== EOF
)
651 tmp
[length
++] = (char)character
;
653 if ((win
->mode
& SCREEN_MODE_KEYPAD
) == SCREEN_MODE_KEYPAD
)
655 result
= _LIBSERVER_convert_from_ecma48(tmp
, length
, &Key
);
656 assert(result
!= _LIBSERVER_CONVERT_FAILED
);
660 Key
.character
= tmp
[0];
661 Key
.code
= _LIBSERVER_KEYCODE_NONE
;
662 result
= _LIBSERVER_CONVERT_OK
;
665 if (result
== _LIBSERVER_CONVERT_FAILED
)
667 } while (result
== _LIBSERVER_CONVERT_NEED_INPUT
);
669 int retval
= Key
.character
;
670 if (Key
.character
== L
'\0')
671 retval
= _LIBOS_KEYCODE_TO_LIBUNIX(Key
.code
);
673 // Newline translation disabled?
674 if ((win
->mode
& SCREEN_MODE_NEWLINE_TRANSLATION
) == 0 && retval
== '\n')
677 // Print the character
678 if ((_LIBUNIX_cur_screen
->mode
& SCREEN_MODE_ECHO
) != 0)
680 if (waddch(win
, (chtype
)retval
) == ERR
)
687 int wrefresh(WINDOW
*win
)
691 if (wnoutrefresh(win
) == ERR
)return ERR
;
695 int wnoutrefresh(WINDOW
*win
)
699 // Copy window data to curscr
701 size_t offdest
= (win
->y
* curscr
->width
+ win
->x
) * 2;
702 size_t cpywidth
= win
->width
;
703 if ((win
->width
+ win
->x
) > curscr
->width
)
704 cpywidth
= curscr
->width
- win
->x
;
705 size_t cpyheight
= win
->height
;
706 if ((win
->height
+ win
->y
) > curscr
->height
)
707 cpyheight
= curscr
->height
- win
->y
;
708 for (size_t i
= 0;i
< cpyheight
;i
++)
710 memcpy(_LIBOS_window_data(&curscr
->osdep
) + offdest
,
711 _LIBOS_window_data(&win
->osdep
) + offsrc
,
713 offdest
+= curscr
->width
* 2;
714 offsrc
+= win
->width
* 2;
717 size_t curx
= ((win
->cursor
/ 2) % win
->width
) + win
->x
;
718 size_t cury
= ((win
->cursor
/ 2) / win
->width
) + win
->y
;
719 curscr
->cursor
= ((cury
* curscr
->width
) + curx
) * 2;
726 _LIBOS_screen_update(&curscr
->osdep
, _LIBUNIX_cur_screen
->outfile
);
729 _LIBUNIX_move_cursor((curscr
->cursor
/ 2) % curscr
->width
,
730 (curscr
->cursor
/ 2) / curscr
->width
);
736 _LIBOS_WARNING("libunix", "not implemented");
740 int delwin(WINDOW
*win
)
742 _LIBOS_WARNING("libunix", "not implemented");
746 int scrollok(WINDOW
*win
, bool bf
)
748 _LIBOS_WARNING("libunix", "not implemented");
752 int wscrl(WINDOW
*win
, int n
)
754 _LIBOS_WARNING("libunix", "not implemented");
760 _LIBOS_WARNING("libunix", "not implemented");