G:/ScriptBasic/source/extensions/curses/interface.c

Go to the documentation of this file.
00001 /* FILE: curses.c
00002 
00003 This file implements the curses module for ScriptBasic. This module is
00004 an interface to the Unix curses library.
00005 
00006 --GNU LGPL
00007 This library is free software; you can redistribute it and/or
00008 modify it under the terms of the GNU Lesser General Public
00009 License as published by the Free Software Foundation; either
00010 version 2.1 of the License, or (at your option) any later version.
00011 
00012 This library is distributed in the hope that it will be useful,
00013 but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015 Lesser General Public License for more details.
00016 
00017 You should have received a copy of the GNU Lesser General Public
00018 License along with this library; if not, write to the Free Software
00019 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020 
00021 the next line tells the program setup.pl that this module can be installed only
00022 under UNIX.
00023 
00024 UXLIBS: -lcurses
00025 
00026 */
00027 #include <curses.h>
00028 #include <malloc.h>
00029 
00113 #include "../../basext.h"
00114 
00115 #define MAX_WINDOWS 16
00116 WINDOW *window_list[MAX_WINDOWS];
00117 WINDOW *current_window;
00118 
00119 /* This variable stores whether the module should issue a refresh() call
00120    after each operation that can potentially modify the screen
00121 */
00122 
00123 static int auto_refresh = -1;
00124 
00125 static int color_to_basic(int color)
00126 {
00127         switch (color) {
00128             case COLOR_BLACK: return 0;
00129             case COLOR_RED: return 1;
00130             case COLOR_GREEN: return 2;
00131             case COLOR_YELLOW: return 3;
00132             case COLOR_BLUE: return 4;
00133             case COLOR_MAGENTA: return 5;
00134             case COLOR_CYAN: return 6;
00135             case COLOR_WHITE: return 7;
00136             default:
00137                 return -1;
00138         }
00139 }
00140 
00141 static int color_to_curses(int sbcolor)
00142 {
00143         int colors[] = {
00144                 COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_YELLOW,
00145                 COLOR_BLUE, COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE
00146         };
00147 
00148         if (sbcolor < 0 || sbcolor > 7)
00149                 return -1;
00150 
00151         return colors[sbcolor];
00152 }
00153 
00154 static int attr_to_basic(int attr)
00155 {
00156         int sbattr = 0;
00157 
00158         if (attr & A_NORMAL)
00159                 sbattr |= 0x0001;
00160         if (attr & A_STANDOUT)
00161                 sbattr |= 0x0002;
00162         if (attr & A_UNDERLINE)
00163                 sbattr |= 0x0004;
00164         if (attr & A_REVERSE)
00165                 sbattr |= 0x0008;
00166         if (attr & A_BLINK)
00167                 sbattr |= 0x0010;
00168         if (attr & A_DIM)
00169                 sbattr |= 0x0020;
00170         if (attr & A_BOLD)
00171                 sbattr |= 0x0040;
00172         if (attr & A_PROTECT)
00173                 sbattr |= 0x0080;
00174         if (attr & A_INVIS)
00175                 sbattr |= 0x0100;
00176         if (attr & A_ALTCHARSET)
00177                 sbattr |= 0x0200;
00178         if (attr & A_CHARTEXT)
00179                 sbattr |= 0x0400;
00180 
00181         return sbattr;
00182 }
00183 
00184 static attr_t attr_to_curses(int sbattr)
00185 {
00186         attr_t attr = 0;
00187 
00188         if (sbattr & 0x0001)
00189                 attr |= A_NORMAL;
00190         if (sbattr & 0x0002)
00191                 attr |= A_STANDOUT;
00192         if (sbattr & 0x0004)
00193                 attr |= A_UNDERLINE;
00194         if (sbattr & 0x0008)
00195                 attr |= A_REVERSE;
00196         if (sbattr & 0x0010)
00197                 attr |= A_BLINK;
00198         if (sbattr & 0x0020)
00199                 attr |= A_DIM;
00200         if (sbattr & 0x0040)
00201                 attr |= A_BOLD;
00202         if (sbattr & 0x0080)
00203                 attr |= A_PROTECT;
00204         if (sbattr & 0x0100)
00205                 attr |= A_INVIS;
00206         if (sbattr & 0x0200)
00207                 attr |= A_ALTCHARSET;
00208         if (sbattr & 0x0400)
00209                 attr |= A_CHARTEXT;
00210 
00211         return attr;
00212 }
00213 
00214 #define AUTO_REFRESH do { if (auto_refresh) {  refresh(); } } while (0)
00215 #define HANDLE_ERR(cmd) \
00216         LONGVALUE(besRETURNVALUE) =  ((cmd) == ERR) ? 0 : -1;
00217 
00225 static int color_supported;
00226 besSUB_SHUTDOWN
00227   return 0;
00228 besEND
00229 
00230 besSUB_FINISH
00231 {
00232         endwin();
00233 }
00234 besEND
00235 
00236 besSUB_START
00237 {
00238         int i;
00239         
00240         initscr();
00241         current_window = stdscr;
00242         cbreak();
00243         noecho();
00244         if (start_color() == ERR)
00245                 color_supported = FALSE;
00246         else
00247                 color_supported = TRUE;
00248 
00249         for (i=0; i<MAX_WINDOWS; i++)
00250                 window_list[i] = NULL;
00251 
00252         window_list[0] = stdscr;
00253         return COMMAND_ERROR_SUCCESS;
00254 }  
00255 besEND
00256 
00270 besFUNCTION(sbsetwin)
00271 {
00272         int err, wn;
00273 
00274         besALLOC_RETURN_LONG;
00275         
00276         if (besARGNR < 1)
00277                 return COMMAND_ERROR_FEW_ARGS;
00278 
00279         err = besGETARGS "i", &wn besGETARGE;
00280         if (err)
00281                 return err;
00282         wn--;
00283         
00284         if (wn < 0 || wn >= MAX_WINDOWS || window_list[wn] == NULL) {
00285                 LONGVALUE(besRETURNVALUE) = 0;
00286         } else {
00287                 current_window = window_list[wn];
00288                 LONGVALUE(besRETURNVALUE) = -1;
00289         }
00290 }
00291 besEND
00292 
00303 besFUNCTION(sbborder)
00304 {
00305         wborder(current_window, 0, 0, 0, 0, 0, 0, 0, 0);
00306         AUTO_REFRESH;
00307 }
00308 besEND
00309 
00324 besFUNCTION(sbnewwin)
00325 {
00326         int i;
00327         WINDOW *wnd;
00328         int rows, cols, y, x;
00329         int err;
00330         
00331         besALLOC_RETURN_LONG;
00332         if (besARGNR < 4)
00333                 return COMMAND_ERROR_FEW_ARGS;
00334         err = besGETARGS "iiii", &x, &y, &cols, &rows besGETARGE;
00335         if (err)
00336                 return err;
00337         
00338         for (i=0; i<MAX_WINDOWS; i++)
00339                 if (window_list[i] == NULL)
00340                         break;
00341         
00342         if (i == MAX_WINDOWS) {
00343                 LONGVALUE(besRETURNVALUE) = 0;
00344                 return COMMAND_ERROR_SUCCESS;
00345         }
00346 
00347         wnd = newwin(rows, cols, y, x);
00348         if (wnd == NULL) {
00349                 LONGVALUE(besRETURNVALUE) = 0;
00350                 return COMMAND_ERROR_SUCCESS;
00351         }
00352         
00353         window_list[i] = wnd;
00354         current_window = wnd;
00355         LONGVALUE(besRETURNVALUE) = i+1;
00356 }
00357 besEND
00358 
00369 besFUNCTION(sbdelwin)
00370 {
00371         int i, err;
00372 
00373         besALLOC_RETURN_LONG;
00374                 
00375         if (besARGNR < 1)
00376                 return COMMAND_ERROR_FEW_ARGS;
00377 
00378         err = besGETARGS "i", &i besGETARGE;
00379         if (err)
00380                 return err;
00381         i--;
00382         
00383         if (i < 0 || i >= MAX_WINDOWS || window_list[i] == NULL)
00384                 return COMMAND_ERROR_BAD_CALL;
00385 
00386         err = delwin(window_list[i]);
00387         if (err == ERR) {
00388                 LONGVALUE(besRETURNVALUE) = 0;
00389         } else {
00390                 window_list[i] = NULL;
00391                 LONGVALUE(besRETURNVALUE) = -1;
00392         }
00393 }
00394 besEND
00395 
00413 besFUNCTION(sbautorefresh)
00414 {
00415         int err;
00416         int v;
00417 
00418         besALLOC_RETURN_LONG;
00419         if (besARGNR < 1)
00420                 return COMMAND_ERROR_FEW_ARGS;
00421 
00422         err = besGETARGS "i", &v besGETARGE;
00423         if (err)
00424                 return err;
00425         auto_refresh = v;
00426 }
00427 besEND
00428 
00439 besFUNCTION(sbbeep)
00440 {
00441         beep();
00442 }
00443 besEND
00444 
00457 besFUNCTION(sbflash)
00458 {
00459         flash();
00460 }
00461 besEND
00462 
00475 besFUNCTION(sberase)
00476 {
00477         erase();
00478         //      AUTO_REFRESH;
00479 }
00480 besEND
00481 
00493 besFUNCTION(sbrefresh)
00494 {
00495         wrefresh(current_window);
00496 }
00497 besEND
00498 
00499 
00513 besFUNCTION(sbmove)
00514 {
00515         int err;
00516         int x, y;
00517 
00518         besALLOC_RETURN_LONG;
00519         if (besARGNR < 2)
00520                 return COMMAND_ERROR_FEW_ARGS;
00521 
00522         err = besGETARGS "ii", &x, &y besGETARGE;
00523         if (err)
00524                 return err;
00525 
00526         HANDLE_ERR(wmove(current_window, y, x));
00527 }
00528 besEND
00529 
00541 besFUNCTION(sbgetx)
00542 {
00543         int x, y;
00544 
00545         besALLOC_RETURN_LONG;
00546 
00547         getyx(current_window, y, x);
00548         LONGVALUE(besRETURNVALUE) = x;
00549 }
00550 besEND
00551 
00563 besFUNCTION(sbgety)
00564 {
00565         int err;
00566         int x, y;
00567 
00568         besALLOC_RETURN_LONG;
00569 
00570         getyx(current_window, y, x);
00571         LONGVALUE(besRETURNVALUE) = y;
00572 }
00573 besEND
00574 
00585 besFUNCTION(sbgetsizex)
00586 {
00587         int err;
00588         int x, y;
00589 
00590         besALLOC_RETURN_LONG;
00591 
00592         getmaxyx(current_window, y, x);
00593         LONGVALUE(besRETURNVALUE) = x;
00594 }
00595 besEND
00596 
00607 besFUNCTION(sbgetsizey)
00608 {
00609         int err;
00610         int x, y;
00611 
00612         besALLOC_RETURN_LONG;
00613 
00614         getmaxyx(current_window, y, x);
00615         LONGVALUE(besRETURNVALUE) = y;
00616 }
00617 besEND
00618 
00630 besFUNCTION(sbaddstr)
00631 {
00632         int i, err;
00633         char *str;
00634         VARIABLE arg;
00635         
00636         besALLOC_RETURN_LONG;
00637         
00638         for (i=1; i<=besARGNR; i++) {
00639                 arg = besARGUMENT(i);
00640                 if (arg == NULL)
00641                         return COMMAND_ERROR_FEW_ARGS;
00642                 besDEREFERENCE(arg);
00643                 if (arg == NULL) 
00644                         return COMMAND_ERROR_ARGUMENT_RANGE;
00645                 arg = besCONVERT2STRING(arg);
00646                 besCONVERT2ZCHAR(arg, str);
00647                 err = waddstr(current_window, str);
00648                 if (err == ERR)
00649                         break;
00650         }
00651 
00652         AUTO_REFRESH;
00653         HANDLE_ERR(err);
00654 }
00655 besEND
00656 
00670 besFUNCTION(sbinsstr)
00671 {
00672         int err;
00673         char *str;
00674 
00675         besALLOC_RETURN_LONG;
00676         if (besARGNR < 1)
00677                 return COMMAND_ERROR_FEW_ARGS;
00678         
00679         err = besGETARGS "z", &str besGETARGE;
00680         if (err)
00681                 return err;
00682         
00683         err = winsstr(current_window, str);
00684         AUTO_REFRESH;
00685         HANDLE_ERR(err);
00686 }       
00687 besEND
00688 
00702 besFUNCTION(sbinsdelln)
00703 {
00704         int err;
00705         int n;
00706 
00707         besALLOC_RETURN_LONG;
00708         
00709         if (besARGNR < 1)
00710                 return COMMAND_ERROR_FEW_ARGS;
00711 
00712         err = besGETARGS "i", &n besGETARGE;
00713         if (err)
00714                 return err;
00715 
00716         err = winsdelln(current_window, n);
00717         AUTO_REFRESH;
00718         HANDLE_ERR(err);
00719 }
00720 besEND
00721 
00732 besFUNCTION(sbdelch)
00733 {
00734         wdelch(current_window);
00735 }
00736 besEND
00737 
00751 besFUNCTION(sbinstr)
00752 {
00753         char *buf;
00754         int err;
00755         int no;
00756 
00757         if (besARGNR < 1)
00758                 return COMMAND_ERROR_FEW_ARGS;
00759         err = besGETARGS "i", &no besGETARGE;
00760         if (err)
00761                 return err;
00762 
00763         buf = malloc(no+1);
00764         winnstr(current_window, buf, no);
00765         
00766         besALLOC_RETURN_STRING(strlen(buf));
00767         memcpy(STRINGVALUE(besRETURNVALUE), buf, STRLEN(besRETURNVALUE));
00768         free(buf);
00769 }
00770 besEND
00771 
00783 besFUNCTION(sbattron)
00784 {
00785         int err;
00786         int sbattr;
00787         attr_t attr;
00788         
00789         besALLOC_RETURN_LONG;
00790         if (besARGNR < 1)
00791                 return COMMAND_ERROR_FEW_ARGS;
00792 
00793         err = besGETARGS "i", &sbattr besGETARGE;
00794         if (err)
00795                 return err;
00796         attr = attr_to_curses(sbattr);
00797         wattron(current_window, attr);
00798 }
00799 besEND
00800 
00813 besFUNCTION(sbattroff)
00814 {
00815         int err;
00816         int sbattr;
00817         attr_t attr;
00818         
00819         besALLOC_RETURN_LONG;
00820         if (besARGNR < 1)
00821                 return COMMAND_ERROR_FEW_ARGS;
00822 
00823         err = besGETARGS "i", &sbattr besGETARGE;
00824         if (err)
00825                 return err;
00826         attr = attr_to_curses(sbattr);
00827         wattroff(current_window, attr);
00828 }
00829 besEND
00830 
00843 besFUNCTION(sbattrset)
00844 {
00845         int err;
00846         int sbattr;
00847         attr_t attr;
00848         
00849         besALLOC_RETURN_LONG;
00850         if (besARGNR < 1)
00851                 return COMMAND_ERROR_FEW_ARGS;
00852 
00853         err = besGETARGS "i", &sbattr besGETARGE;
00854         if (err)
00855                 return err;
00856         attr = attr_to_curses(sbattr);
00857         wattrset(current_window, attr);
00858 }
00859 besEND
00860 
00874 besFUNCTION(sbchgat)
00875 {
00876         int err;
00877         int no, col, attr;
00878 
00879         if (besARGNR < 3)
00880                 return COMMAND_ERROR_FEW_ARGS;
00881 
00882         err = besGETARGS "iii", &no, &col, &attr besGETARGE;
00883         if (err)
00884                 return err;
00885         
00886         attr = attr_to_curses(attr);
00887         wchgat(current_window, no, attr, col, NULL);
00888 }
00889 besEND
00890 
00901 besFUNCTION(sbmaxcolors)
00902 {
00903         besALLOC_RETURN_LONG;
00904         LONGVALUE(besRETURNVALUE) = COLOR_PAIRS - 1;
00905 }
00906 besEND
00907 
00920 besFUNCTION(sbinitpair)
00921 {
00922         int err;
00923         int c, f, b;
00924 
00925         besALLOC_RETURN_LONG;
00926         if (besARGNR < 3)
00927                 return COMMAND_ERROR_FEW_ARGS;
00928 
00929         err = besGETARGS "iii", &c, &f, &b besGETARGE;
00930         if (err)
00931                 return err;
00932 
00933         f = color_to_curses(f);
00934         b = color_to_curses(b);
00935 
00936         HANDLE_ERR(init_pair(c, f, b));
00937 }
00938 besEND
00939 
00952 besFUNCTION(sbsetcolor)
00953 {
00954         int err;
00955         int c;
00956 
00957         if (besARGNR < 1)
00958                 return COMMAND_ERROR_FEW_ARGS;
00959 
00960         err = besGETARGS "i", &c besGETARGE;
00961         if (err)
00962                 return err;
00963 
00964         /* disable all color attributes and enable color wished for */
00965         attroff(~attr_to_curses(0x07ff)); /* this is perhaps unnecessary */
00966         attron(COLOR_PAIR(c));
00967 }
00968 besEND
00969 
00984 besFUNCTION(sbsetbackground)
00985 {
00986         int err;
00987         int set, col, attr;
00988 
00989         besALLOC_RETURN_LONG;
00990         
00991         switch (besARGNR) {
00992             case 2:
00993                 err = besGETARGS "ii", &col, &attr besGETARGE;
00994                 if (err)
00995                         return err;
00996                 set = 0;
00997                 break;
00998             case 3:
00999                 err = besGETARGS "iii", &col, &attr, &set besGETARGE;
01000                 if (err)
01001                         return err;
01002                 break;
01003             default:
01004                 return COMMAND_ERROR_FEW_ARGS;
01005         }
01006 
01007         attr = attr_to_curses(attr) | COLOR_PAIR(col);
01008         if (set)
01009                 err = wbkgd(current_window,attr);
01010         else { 
01011                 wbkgdset(current_window, attr);
01012                 err = OK;
01013         }
01014 
01015         HANDLE_ERR(err);
01016 }
01017 besEND
01018 
01033 besFUNCTION(sbgetch)
01034 {
01035         int err, doecho = 0, dodelay = 1;
01036         int ch;
01037 
01038         besALLOC_RETURN_LONG;
01039 
01040         switch (besARGNR) {
01041             case 1:
01042                 err = besGETARGS "i", &doecho besGETARGE;
01043                 if (err)
01044                         return err;
01045             case 0:
01046                 break;
01047             default:
01048                 err = besGETARGS "ii", &doecho, &dodelay besGETARGE;
01049                 break;
01050                 
01051         }
01052 
01053         if (doecho)
01054                 echo();
01055         if (!dodelay) {
01056                 nodelay(current_window, 1);
01057         }
01058         ch = wgetch(current_window);
01059         noecho();
01060         nodelay(current_window, 0);
01061 
01062         if (ch == ERR)
01063                 LONGVALUE(besRETURNVALUE) = -1;
01064         else
01065                 LONGVALUE(besRETURNVALUE) = ch;
01066 }
01067 besEND
01068 
01081 besFUNCTION(sbgetstr)
01082 {
01083         char *buf;
01084         int err;
01085         int no;
01086 
01087         if (besARGNR < 1)
01088                 return COMMAND_ERROR_FEW_ARGS;
01089         err = besGETARGS "i", &no besGETARGE;
01090         if (err)
01091                 return err;
01092 
01093         buf = malloc(no+1);
01094         echo();
01095         wgetnstr(current_window, buf, no);
01096         noecho();
01097         
01098         besALLOC_RETURN_STRING(strlen(buf));
01099         memcpy(STRINGVALUE(besRETURNVALUE), buf, STRLEN(besRETURNVALUE));
01100         free(buf);
01101 }
01102 besEND
01103 
01115 besFUNCTION(sbkeyname)
01116 {
01117         int err, key;
01118         const char *kn;
01119         
01120         if (besARGNR < 1)
01121                 return COMMAND_ERROR_FEW_ARGS;
01122         err = besGETARGS "i", &key besGETARGE;
01123         if (err)
01124                 return err;
01125 
01126         kn = keyname(key);
01127         
01128         besALLOC_RETURN_STRING(strlen(kn));
01129         memcpy(STRINGVALUE(besRETURNVALUE), kn, STRLEN(besRETURNVALUE));
01130 }
01131 besEND
01132 
01133 besVERSION_NEGOTIATE
01134 
01135   return (int)INTERFACE_VERSION;
01136 
01137 besEND
01138 
01139 SLFST CURSES_SLFST[] ={
01140 
01141 { "shutmodu" , shutmodu },
01142 { "bootmodu" , bootmodu },
01143 { "versmodu" , versmodu },
01144 { "finimodu" , finimodu },
01145         
01146 { "beep" , sbbeep },
01147 { "flash", sbflash },
01148 { "erase", sberase },
01149 { "refresh", sbrefresh },
01150 { "autorefresh", sbautorefresh },
01151         
01152 { "move", sbmove },
01153 { "getx", sbgetx },
01154 { "gety", sbgety },
01155 { "getsizex", sbgetsizex },
01156 { "getsizey", sbgetsizey },
01157 
01158 { "addstr", sbaddstr },
01159 { "insstr", sbinsstr },
01160 { "insdelln", sbinsdelln },
01161 { "delch", sbdelch },
01162 { "instr", sbinstr },
01163         
01164 { "attron", sbattron },
01165 { "attroff", sbattroff },
01166 { "attrset", sbattrset },
01167 { "chgat", sbchgat },
01168         
01169 { "maxcolors", sbmaxcolors },
01170 { "initpair", sbinitpair },
01171 { "setcolor", sbsetcolor },
01172 { "setbackground", sbsetbackground },
01173         
01174 { "getch", sbgetch },
01175 { "getstr", sbgetstr },
01176 
01177 { "keyname", sbkeyname },
01178 
01179 { "setwin", sbsetwin },
01180 { "newwin", sbnewwin },
01181 { "delwin", sbdelwin },
01182 { "border", sbborder },
01183 { NULL , NULL }
01184 };

Generated on Sun Mar 12 23:56:28 2006 for ScriptBasic by  doxygen 1.4.6-NO