Addons updated to new doc format
[io.git] / addons / Curses / source / IoCurses.c
blobf7e30f1bca67ba2003ac1289c078ee4f8bf5e383
2 //metadoc Curses copyright Steve Dekorte, 2004
3 //metadoc Curses license BSD revised
4 //metadoc Curses category Server
5 //metadoc Curses credits Original version by Edwin Zacharias. getCh method by Scott Dunlop.
6 /*metadoc Curses description
7 Curses allows writing and reading at arbitrary positions on the terminal. You have to call init to set the terminal to curses mode and end to end curses mode. The terminal is not updated until refresh is called. It is a bad idea to use the standard io's read and write methods when the terminal is in curses mode. The Curses primitive was written by Edwin Zacharias.
8 <BR><BR>
9 Here's an example that prints Hello at column 5 and row 7;
10 <PRE>
11 Curses init
12 Curses move(5, 7) print(\"Hello\")
13 Curses refresh
14 Curses end
15 <PRE>
18 #include "IoCurses.h"
19 #include "IoState.h"
20 #include "IoNumber.h"
21 #include "IoSeq.h"
23 #if defined(__CYGWIN__) || defined(__MINGW32__)
24 #include <curses.h>
25 #else
26 #include <ncurses.h>
27 #endif
29 #define IO_CURSES_INPUT_BUFFER_LENGTH 200
31 #define DATA(self) ((IoCursesData *)IoObject_dataPointer(self))
33 IoTag *IoCurses_newTag(void *state)
35 IoTag *tag = IoTag_newWithName_("Curses");
36 IoTag_state_(tag, state);
37 IoTag_freeFunc_(tag, (IoTagFreeFunc *)IoCurses_free);
38 IoTag_cloneFunc_(tag, (IoTagCloneFunc *)IoCurses_rawClone);
39 return tag;
42 IoCurses *IoCurses_proto(void *state)
44 IoObject *self = IoObject_new(state);
45 IoObject_tag_(self, IoCurses_newTag(state));
47 IoObject_setDataPointer_(self, calloc(1, sizeof(IoCursesData)));
48 IoState_registerProtoWithFunc_(state, self, IoCurses_proto);
51 IoMethodTable methodTable[] = {
52 {"begin", IoCurses_begin},
53 {"end", IoCurses_end},
55 //{"nodelay", IoCurses_nodelay},
56 //{"cBreak", IoCurses_cBreak},
57 //{"noCBreak", IoCurses_noCBreak},
58 //{"echo", IoCurses_echo},
59 //{"noEcho", IoCurses_noEcho},
60 {"move", IoCurses_move},
61 {"write", IoCurses_print},
62 {"writeCharacter", IoCurses_writeCharacter},
63 //{"insert", IoCurses_insert},
64 //{"delete", IoCurses_delete},
65 //{"get", IoCurses_get},
66 {"asyncReadCharacter", IoCurses_getCh},
67 //{"input", IoCurses_input},
68 //{"erase", IoCurses_erase},
69 {"clear", IoCurses_clear},
70 //{"clearToEndOfLine", IoCurses_clearToEndOfLine},
71 {"refresh", IoCurses_refresh},
73 {"x", IoCurses_x},
74 {"y", IoCurses_y},
76 {"width", IoCurses_width},
77 {"height", IoCurses_height},
79 {"hasColors", IoCurses_hasColors},
81 {"setBackgroundBlack", IoCurses_setBackgroundBlack},
82 {"setBackgroundBlue", IoCurses_setBackgroundBlue},
83 {"setBackgroundGreen", IoCurses_setBackgroundGreen},
84 {"setBackgroundCyan", IoCurses_setBackgroundCyan},
85 {"setBackgroundRed", IoCurses_setBackgroundRed},
86 {"setBackgroundMagenta", IoCurses_setBackgroundMagenta},
87 {"setBackgroundYellow", IoCurses_setBackgroundYellow},
88 {"setBackgroundWhite", IoCurses_setBackgroundWhite},
90 {"setForegroundBlack", IoCurses_setForegroundBlack},
91 {"setForegroundBlue", IoCurses_setForegroundBlue},
92 {"setForegroundGreen", IoCurses_setForegroundGreen},
93 {"setForegroundCyan", IoCurses_setForegroundCyan},
94 {"setForegroundRed", IoCurses_setForegroundRed},
95 {"setForegroundMagenta", IoCurses_setForegroundMagenta},
96 {"setForegroundYellow", IoCurses_setForegroundYellow},
97 {"setForegroundWhite", IoCurses_setForegroundWhite},
98 {NULL, NULL},
101 IoObject_addMethodTable_(self, methodTable);
103 return self;
106 IoCurses *IoCurses_rawClone(IoCurses *proto)
108 IoCurses *self = IoObject_rawClonePrimitive(proto);
109 IoObject_setDataPointer_(self, cpalloc(DATA(proto), sizeof(IoCursesData)));
110 return self;
113 /* ----------------------------------------------------------- */
115 IoCurses *IoCurses_new(void *state)
117 IoObject *proto = IoState_protoWithInitFunction_(state, IoCurses_proto);
118 return IOCLONE(proto);
121 void IoCurses_free(IoCurses *self)
123 free(IoObject_dataPointer(self));
126 /* ----------------------------------------------------------- */
128 void IoCurses_suspendCurses(IoCurses *self)
130 def_prog_mode();
131 endwin();
132 refresh();
135 void IoCurses_resumeCurses(IoCurses *self)
137 refresh();
140 IoObject *IoCurses_showError(IoCurses *self, IoMessage *m, const char *name, const char *description)
142 IoCurses_suspendCurses(self);
143 IoCurses_showError(self, m, name, description);
144 IoCurses_resumeCurses(self);
145 return self;
148 /* in curses y (the column) is listed before x (the row) */
150 IoObject *IoCurses_begin(IoCurses *self, IoObject *locals, IoMessage *m)
152 /*doc Curses begin
153 Sets the terminal to curses mode.
154 This should be called before any other curses methods.
155 Returns self.
158 initscr();
159 //start_color();
160 //DATA(self)->colorOn = 1;
162 intrflush(stdscr, FALSE);
163 keypad(stdscr, TRUE);
164 nodelay(stdscr, TRUE);
166 nonl();
167 noecho();
168 cbreak();
170 return self;
173 IoObject *IoCurses_end(IoCurses *self, IoObject *locals, IoMessage *m)
175 /*doc Curses end
176 Ends curses mode. This should be called before standard io's read
177 and write methods are used. Returs self.
179 printf("IoCurses_end\n");
181 //echo();
182 //nocbreak();
183 //nl();
185 //clear();
186 //refresh();
187 //reset_shell_mode();
188 endwin();
189 //reset_shell_mode();
190 return self;
194 IoObject *IoCurses_nodelay(IoCurses *self, IoObject *locals, IoMessage *m)
196 /*doc Curses nodelay(aBoolean)
197 Enables or disables block during read.
198 If aNumber is zero, nodelay is set to be false, otherwise it is set to be true.
201 int b = IoNumber_asInt(IoMessage_locals_numberArgAt_(m, locals, 0));
202 nodelay(stdscr, b);
203 return self;
207 IoObject *IoCurses_cBreak(IoCurses *self, IoObject *locals, IoMessage *m)
209 /*doc Curses cBreak(aString)
210 Disables line buffering and erase/kill character-processing.
211 cBreak should be on for most purposes. Returns self.
214 if (cbreak() == ERR)
216 IoCurses_showError(self, m, "Curses.cBreak", "Failed to enable cBreak.");
218 return self;
221 IoObject *IoCurses_noCBreak(IoCurses *self, IoObject *locals, IoMessage *m)
223 /*doc Curses noCBreak
224 Allows line buffering and erase/kill character-processing.
225 cBreak should be on for most purposes. Returns self.
228 if (nocbreak() == ERR)
230 IoCurses_showError(self, m, "Curses.noCBreak", "Failed to disable cBreak.");
232 return self;
235 IoObject *IoCurses_echo(IoCurses *self, IoObject *locals, IoMessage *m)
237 /*doc Curses echo
238 Echoes user input to terminal. Returns self.
241 if (echo() == ERR)
243 IoCurses_showError(self, m, "Curses.echo", "Failed to enable echo.");
245 return self;
248 IoObject *IoCurses_noEcho(IoCurses *self, IoObject *locals, IoMessage *m)
250 /*doc Curses noEcho
251 Does not echo user input to terminal. Returns self.
254 if (noecho() == ERR)
256 IoCurses_showError(self, m, "Curses.noecho", "Failed to disable echo.");
258 return self;
261 IoObject *IoCurses_move(IoCurses *self, IoObject *locals, IoMessage *m)
263 /*doc Curses move(x, y)
264 Moves the cursor to column y and row x on the terminal.
265 (0, 0) is at the top-left of the terminal. Returns self.
268 int x = IoNumber_asInt(IoMessage_locals_numberArgAt_(m, locals, 0));
269 int y = IoNumber_asInt(IoMessage_locals_numberArgAt_(m, locals, 1));
271 if (move(y, x) == ERR)
273 IoCurses_showError(self, m, "Curses.move", "Failed to move curser.");
276 return self;
279 IoObject *IoCurses_writeCharacter(IoCurses *self, IoObject *locals, IoMessage *m)
281 /*doc Curses writeCharacter(aCharacter)
282 Prints the aCharacter to the current position on the terminal,
283 overwriting existing text on the terminal. Returns self.
286 char c = IoMessage_locals_intArgAt_(m, locals, 0);
288 if (addch(c) == ERR)
290 /* IoCurses_showError(self, m, "Curses.print", "Failed to print string.");*/
292 return self;
295 IoObject *IoCurses_print(IoCurses *self, IoObject *locals, IoMessage *m)
297 /*doc Curses print(aString)
298 Prints the string to the current position on the terminal,
299 overwriting existing text on the terminal. Returns self.
302 char *string = IoSeq_asCString(IoMessage_locals_seqArgAt_(m, locals, 0));
304 if (addstr(string) == ERR)
306 /* IoCurses_showError(self, m, "Curses.print", "Failed to print string.");*/
308 return self;
311 IoObject *IoCurses_insert(IoCurses *self, IoObject *locals, IoMessage *m)
313 /*doc Curses insert(aString)
314 Inserts the string at the current position on the terminal,
315 pushing existing text to the right. Returns self.
318 char *string = IoSeq_asCString(IoMessage_locals_seqArgAt_(m, locals, 0));
320 if (insstr(string) == ERR)
322 IoCurses_showError(self, m, "Curses.insert", "Failed to insert string.");
324 return self;
327 IoObject *IoCurses_delete(IoCurses *self, IoObject *locals, IoMessage *m)
329 /*doc Curses delete(n)
330 Deletes n characters at the current position. Text to the right is shifted left.
331 n is optional and defaults to 1. Returns self.
334 int n = 1;
336 if (IoMessage_argCount(m) > 0)
338 n = IoNumber_asInt(IoMessage_locals_numberArgAt_(m, locals, 0));
341 for (n = n; n > 0; n--)
343 if (delch() == ERR)
345 IoCurses_showError(self, m, "Curses.delete", "Failed to delete string.");
348 return self;
351 IoObject *IoCurses_get(IoCurses *self, IoObject *locals, IoMessage *m)
353 /*doc Curses get(n)
354 Returns n characters from the terminal. n is optional and defaults to 1.
357 int inputCharacterLimit = IO_CURSES_INPUT_BUFFER_LENGTH;
358 char string[inputCharacterLimit];
360 if (IoMessage_argCount(m) > 0)
362 IoNumber *number = IoMessage_locals_numberArgAt_(m, locals, 0);
363 inputCharacterLimit = IoNumber_asInt(number);
366 if (getnstr(string, inputCharacterLimit) == ERR)
368 return IONIL(self);
371 return IoState_symbolWithCString_(IOSTATE, string);
374 IoObject *IoCurses_getCh(IoCurses *self, IoObject *locals, IoMessage *m)
376 /*doc Curses getCh
377 Reads a single-byte character from the terminal associated with the
378 current or specified window. Returns a Number containing the byte.
381 int key = getch();
383 if (key == ERR)
385 return IONIL(self);
388 return IONUMBER((double)key);
391 IoObject *IoCurses_input(IoCurses *self, IoObject *locals, IoMessage *m)
393 /*doc Curses input(n)
394 Returns user input up to a return, or a maximun of n characters.
397 int length = 1;
398 char string[length+1];
400 if (IoMessage_argCount(m) > 0)
402 length = IoNumber_asInt(IoMessage_locals_numberArgAt_(m, locals, 0));
405 if (innstr(string, length) == ERR)
407 return IONIL(self);
410 return IoState_symbolWithCString_(IOSTATE, string);
413 IoObject *IoCurses_clear(IoCurses *self, IoObject *locals, IoMessage *m)
415 /*doc Curses clear
416 Clears the terminal. Nicer than erase. Returns self.
419 clear();
420 return self;
423 IoObject *IoCurses_clearToEndOfLine(IoCurses *self, IoObject *locals, IoMessage *m)
425 /*doc Curses clearToEndOfLine
426 Clears the text from the cursor to the end of the line. Returns self.
429 clrtoeol();
430 return self;
433 IoObject *IoCurses_refresh(IoCurses *self, IoObject *locals, IoMessage *m)
435 /*doc Curses refresh
436 Copies the current buffer to the screen. This must be called to make
437 changes to the screen. Returns self.
440 if (refresh() == ERR)
442 IoCurses_showError(self, m, "Curses.refresh", "Failed to refresh screen.");
444 return self;
447 IoObject *IoCurses_width(IoCurses *self, IoObject *locals, IoMessage *m)
449 /*doc Curses width
450 Returns a Number containing the width of the current screen.
453 int w, h;
454 getmaxyx(stdscr, h, w);
455 return IONUMBER(w);
458 IoObject *IoCurses_height(IoCurses *self, IoObject *locals, IoMessage *m)
460 /*doc Curses height
461 Returns a Number containing the height of the current screen.
464 int w, h;
465 getmaxyx(stdscr, h, w);
466 return IONUMBER(h);
469 IoObject *IoCurses_hasColors(IoCurses *self, IoObject *locals, IoMessage *m)
471 /*doc Curses hasColors
472 Returns true if the terminal supports color, false otherwise.
475 return IOBOOL(self, has_colors());
478 void IoCurses_colorSet(IoCurses *self)
480 if (!DATA(self)->colorOn)
482 start_color();
483 DATA(self)->colorOn = 1;
484 /*pair_content(0, &(DATA(self)->fgColor), &(DATA(self)->bgColor));*/
486 init_pair(0, DATA(self)->fgColor, DATA(self)->bgColor);
487 #if ! defined(__PDCURSES__)
488 color_set(0, NULL);
489 #else
490 attrset(COLOR_PAIR(0));
491 #endif
494 /* --- Background --- */
496 IoObject *IoCurses_setBackgroundBlack(IoCurses *self, IoObject *locals, IoMessage *m)
498 /*doc Curses setBackgroundBlack
499 Sets the background color to black.
502 DATA(self)->bgColor = COLOR_BLACK;
503 IoCurses_colorSet(self);
504 return self;
507 IoObject *IoCurses_setBackgroundBlue(IoCurses *self, IoObject *locals, IoMessage *m)
509 /*doc Curses setBackgroundBlue
510 Sets the background color to blue.
513 DATA(self)->bgColor = COLOR_BLUE;
514 IoCurses_colorSet(self);
515 return self;
518 IoObject *IoCurses_setBackgroundGreen(IoCurses *self, IoObject *locals, IoMessage *m)
520 /*doc Curses setBackgroundGreen
521 Sets the background color to green.
524 DATA(self)->bgColor = COLOR_GREEN;
525 IoCurses_colorSet(self);
526 return self;
529 IoObject *IoCurses_setBackgroundCyan(IoCurses *self, IoObject *locals, IoMessage *m)
531 /*doc Curses setBackgroundCyan
532 Sets the background color to cyan.
535 DATA(self)->bgColor = COLOR_CYAN;
536 IoCurses_colorSet(self);
537 return self;
540 IoObject *IoCurses_setBackgroundRed(IoCurses *self, IoObject *locals, IoMessage *m)
542 /*doc Curses setBackgroundRed
543 Sets the background color to red.
546 DATA(self)->bgColor = COLOR_RED;
547 IoCurses_colorSet(self);
548 return self;
551 IoObject *IoCurses_setBackgroundMagenta(IoCurses *self, IoObject *locals, IoMessage *m)
553 /*doc Curses setBackgroundMagenta
554 Sets the background color to magenta.
557 DATA(self)->bgColor = COLOR_MAGENTA;
558 IoCurses_colorSet(self);
559 return self;
562 IoObject *IoCurses_setBackgroundYellow(IoCurses *self, IoObject *locals, IoMessage *m)
564 /*doc Curses setBackgroundYellow
565 Sets the background color to yellow.
568 DATA(self)->bgColor = COLOR_YELLOW;
569 IoCurses_colorSet(self);
570 return self;
573 IoObject *IoCurses_setBackgroundWhite(IoCurses *self, IoObject *locals, IoMessage *m)
575 /*doc Curses setBackgroundWhite
576 Sets the background color to white.
579 DATA(self)->bgColor = COLOR_WHITE;
580 IoCurses_colorSet(self);
581 return self;
584 /* --- Foreground --- */
586 IoObject *IoCurses_setForegroundBlack(IoCurses *self, IoObject *locals, IoMessage *m)
588 /*doc Curses setForegroundBlack
589 Sets the foreground color to black.
592 DATA(self)->fgColor = COLOR_BLACK;
593 IoCurses_colorSet(self);
594 return self;
597 IoObject *IoCurses_setForegroundBlue(IoCurses *self, IoObject *locals, IoMessage *m)
599 /*doc Curses setForegroundBlue
600 Sets the foreground color to blue.
603 DATA(self)->fgColor = COLOR_BLUE;
604 IoCurses_colorSet(self);
605 return self;
608 IoObject *IoCurses_setForegroundGreen(IoCurses *self, IoObject *locals, IoMessage *m)
610 /*doc Curses setForegroundGreen
611 Sets the foreground color to green.
614 DATA(self)->fgColor = COLOR_GREEN;
615 IoCurses_colorSet(self);
616 return self;
619 IoObject *IoCurses_setForegroundCyan(IoCurses *self, IoObject *locals, IoMessage *m)
621 /*doc Curses setForegroundCyan
622 Sets the foreground color to cyan.
625 DATA(self)->fgColor = COLOR_CYAN;
626 IoCurses_colorSet(self);
627 return self;
630 IoObject *IoCurses_setForegroundRed(IoCurses *self, IoObject *locals, IoMessage *m)
632 /*doc Curses setForegroundRed
633 Sets the foreground color to red.
636 DATA(self)->fgColor = COLOR_RED;
637 IoCurses_colorSet(self);
638 return self;
641 IoObject *IoCurses_setForegroundMagenta(IoCurses *self, IoObject *locals, IoMessage *m)
643 /*doc Curses setForegroundMagenta
644 Sets the foreground color to magenta.
647 DATA(self)->fgColor = COLOR_MAGENTA;
648 IoCurses_colorSet(self);
649 return self;
652 IoObject *IoCurses_setForegroundYellow(IoCurses *self, IoObject *locals, IoMessage *m)
654 /*doc Curses setForegroundYellow
655 Sets the foreground color to yellow.
658 DATA(self)->fgColor = COLOR_YELLOW;
659 IoCurses_colorSet(self);
660 return self;
663 IoObject *IoCurses_setForegroundWhite(IoCurses *self, IoObject *locals, IoMessage *m)
665 /*doc Curses setForegroundWhite
666 Sets the foreground color to white.
669 DATA(self)->fgColor = COLOR_WHITE;
670 IoCurses_colorSet(self);
671 return self;
674 IoObject *IoCurses_x(IoCurses *self, IoObject *locals, IoMessage *m)
676 /*doc Curses x
677 Returns the cursor x position.
680 int x, y;
682 getyx(stdscr, y, x);
684 return IONUMBER(x);
687 IoObject *IoCurses_y(IoCurses *self, IoObject *locals, IoMessage *m)
689 /*doc Curses y
690 Returns the cursor y position.
693 int x, y;
695 getyx(stdscr, y, x);
697 return IONUMBER(y);