1PDCurses Implementor's Guide 2============================ 3 4- Version 1.3 - 20??/??/?? - notes about official ports, new indentation 5 style; markdown 6- Version 1.2 - 2007/07/11 - added PDC_init_pair(), PDC_pair_content(), 7 version history; removed pdc_atrtab 8- Version 1.1 - 2007/06/06 - minor cosmetic change 9- Version 1.0 - 2007/04/01 - initial revision 10 11This document is for those wishing to port PDCurses to a new platform, 12or just wanting to better understand how it works. Nothing here should 13be needed for application programming; for that, refer to PDCurses.md, 14as built in doc/, or distributed as a file separate from this source 15package. This document assumes that you've read the user-level 16documentation and are very familiar with application-level curses 17programming. 18 19If you want to submit your port for possible inclusion into the main 20PDCurses distribution, please follow these guidelines: 21 22 - Don't modify anything in the pdcurses directory or in other port 23 directories. Don't modify curses.h or curspriv.h unless absolutely 24 necessary. (And prefer modifying curspriv.h over curses.h.) 25 26 - Use the same indentation style, naming and scope conventions as the 27 existing code. 28 29 - Release all your code to the public domain -- no copyright. Code 30 under GPL, BSD, etc. will not be accepted. 31 32 33Data Structures 34=============== 35 36A port of PDCurses must provide acs_map[], a 128-element array of 37chtypes, with values laid out based on the Alternate Character Set of 38the VT100 (see curses.h). PDC_transform_line() must use this table; when 39it encounters a chtype with the A_ALTCHARSET flag set, and an A_CHARTEXT 40value in the range 0-127, it must render it using the A_CHARTEXT portion 41of the corresponding value from this table, instead of the original 42value. Also, values may be read from this table by apps, and passed 43through functions such as waddch(), which does no special processing on 44control characters (0-31 and 127) when the A_ALTCHARSET flag is set. 45Thus, any control characters used in acs_map[] should also have the 46A_ALTCHARSET flag set. Implementations should provide suitable values 47for all the ACS_ macros defined in curses.h; other values in the table 48should be filled with their own indices (e.g., acs_map['E'] == 'E'). The 49table can be either hardwired, or filled by PDC_scr_open(). Existing 50ports define it in pdcdisp.c, but this is not required. 51 52 53Functions 54========= 55 56A port of PDCurses must implement the following functions, with extern 57scope. These functions are traditionally divided into several modules, 58as indicated below; this division is not required (only the functions 59are), but may make it easier to follow for someone familiar with the 60existing ports. 61 62Any other functions you create as part of your implementation should 63have static scope, if possible. If they can't be static, they should be 64named with the "PDC_" prefix. This minimizes the risk of collision with 65an application's choices. 66 67Current PDCurses style also uses a single leading underscore with the 68name of any static function; and modified BSD/Allman-style indentation, 69approximately equivalent to "indent -kr -nut -bl -bli0", with 70adjustments to keep every line under 80 columns. 71 72 73pdcdisp.c: 74---------- 75 76### void PDC_gotoyx(int y, int x); 77 78Move the physical cursor (as opposed to the logical cursor affected by 79wmove()) to the given location. This is called mainly from doupdate(). 80In general, this function need not compare the old location with the new 81one, and should just move the cursor unconditionally. 82 83### void PDC_transform_line(int lineno, int x, int len, const chtype *srcp); 84 85The core output routine. It takes len chtype entities from srcp (a 86pointer into curscr) and renders them to the physical screen at line 87lineno, column x. It must also translate characters 0-127 via acs_map[], 88if they're flagged with A_ALTCHARSET in the attribute portion of the 89chtype. 90 91 92pdcgetsc.c: 93----------- 94 95### int PDC_get_columns(void); 96 97Returns the size of the screen in columns. It's used in resize_term() to 98set the new value of COLS. (Some existing implementations also call it 99internally from PDC_scr_open(), but this is not required.) 100 101### int PDC_get_cursor_mode(void); 102 103Returns the size/shape of the cursor. The format of the result is 104unspecified, except that it must be returned as an int. This function is 105called from initscr(), and the result is stored in SP->orig_cursor, 106which is used by PDC_curs_set() to determine the size/shape of the 107cursor in normal visibility mode (curs_set(1)). 108 109### int PDC_get_rows(void); 110 111Returns the size of the screen in rows. It's used in resize_term() to 112set the new value of LINES. (Some existing implementations also call it 113internally from PDC_scr_open(), but this is not required.) 114 115 116pdckbd.c: 117--------- 118 119### bool PDC_check_key(void); 120 121Keyboard/mouse event check, called from wgetch(). Returns TRUE if 122there's an event ready to process. This function must be non-blocking. 123 124### void PDC_flushinp(void); 125 126This is the core of flushinp(). It discards any pending key or mouse 127events, removing them from any internal queue and from the OS queue, if 128applicable. 129 130### int PDC_get_key(void); 131 132Get the next available key, or mouse event (indicated by a return of 133KEY_MOUSE), and remove it from the OS' input queue, if applicable. This 134function is called from wgetch(). This function may be blocking, and 135traditionally is; but it need not be. If a valid key or mouse event 136cannot be returned, for any reason, this function returns -1. Valid keys 137are those that fall within the appropriate character set, or are in the 138list of special keys found in curses.h (KEY_MIN through KEY_MAX). When 139returning a special key code, this routine must also set SP->key_code to 140TRUE; otherwise it must set it to FALSE. If SP->return_key_modifiers is 141TRUE, this function may return modifier keys (shift, control, alt), 142pressed alone, as special key codes; if SP->return_key_modifiers is 143FALSE, it must not. If modifier keys are returned, it should only happen 144if no other keys were pressed in the meantime; i.e., the return should 145happen on key up. But if this is not possible, it may return the 146modifier keys on key down (if and only if SP->return_key_modifiers is 147TRUE). 148 149### int PDC_modifiers_set(void); 150 151Called from PDC_return_key_modifiers(). If your platform needs to do 152anything in response to a change in SP->return_key_modifiers, do it 153here. Returns OK or ERR, which is passed on by the caller. 154 155### int PDC_mouse_set(void); 156 157Called by mouse_set(), mouse_on(), and mouse_off() -- all the functions 158that modify SP->_trap_mbe. If your platform needs to do anything in 159response to a change in SP->_trap_mbe (for example, turning the mouse 160cursor on or off), do it here. Returns OK or ERR, which is passed on by 161the caller. 162 163### void PDC_set_keyboard_binary(bool on); 164 165Set keyboard input to "binary" mode. If you need to do something to keep 166the OS from processing ^C, etc. on your platform, do it here. TRUE turns 167the mode on; FALSE reverts it. This function is called from raw() and 168noraw(). 169 170 171pdcscrn.c: 172---------- 173 174### bool PDC_can_change_color(void); 175 176Returns TRUE if init_color() and color_content() give meaningful 177results, FALSE otherwise. Called from can_change_color(). 178 179### int PDC_color_content(short color, short *red, short *green, short *blue); 180 181The core of color_content(). This does all the work of that function, 182except checking for values out of range and null pointers. 183 184### int PDC_init_color(short color, short red, short green, short blue); 185 186The core of init_color(). This does all the work of that function, 187except checking for values out of range. 188 189### void PDC_init_pair(short pair, short fg, short bg); 190 191The core of init_pair(). This does all the work of that function, except 192checking for values out of range. The values passed to this function 193should be returned by a call to PDC_pair_content() with the same pair 194number. PDC_transform_line() should use the specified colors when 195rendering a chtype with the given pair number. 196 197### int PDC_pair_content(short pair, short *fg, short *bg); 198 199The core of pair_content(). This does all the work of that function, 200except checking for values out of range and null pointers. 201 202### void PDC_reset_prog_mode(void); 203 204The non-portable functionality of reset_prog_mode() is handled here -- 205whatever's not done in _restore_mode(). In current ports: In OS/2, this 206sets the keyboard to binary mode; in Win32, it enables or disables the 207mouse pointer to match the saved mode; in others it does nothing. 208 209### void PDC_reset_shell_mode(void); 210 211The same thing, for reset_shell_mode(). In OS/2 and Win32, it restores 212the default console mode; in others it does nothing. 213 214### int PDC_resize_screen(int nlines, int ncols); 215 216This does the main work of resize_term(). It may respond to non-zero 217parameters, by setting the screen to the specified size; to zero 218parameters, by setting the screen to a size chosen by the user at 219runtime, in an unspecified way (e.g., by dragging the edges of the 220window); or both. It may also do nothing, if there's no appropriate 221action for the platform. 222 223### void PDC_restore_screen_mode(int i); 224 225Called from _restore_mode() in kernel.c, this function does the actual 226mode changing, if applicable. Currently used only in DOS and OS/2. 227 228### void PDC_save_screen_mode(int i); 229 230Called from _save_mode() in kernel.c, this function saves the actual 231screen mode, if applicable. Currently used only in DOS and OS/2. 232 233### void PDC_scr_close(void); 234 235The platform-specific part of endwin(). It may restore the image of the 236original screen saved by PDC_scr_open(), if the PDC_RESTORE_SCREEN 237environment variable is set; either way, if using an existing terminal, 238this function should restore it to the mode it had at startup, and move 239the cursor to the lower left corner. (The X11 port does nothing.) 240 241### void PDC_scr_free(void); 242 243Frees the memory for SP allocated by PDC_scr_open(). Called by 244delscreen(). 245 246### int PDC_scr_open(int argc, char **argv); 247 248The platform-specific part of initscr(). It's actually called from 249Xinitscr(); the arguments, if present, correspond to those used with 250main(), and may be used to set the title of the terminal window, or for 251other, platform-specific purposes. (The arguments are currently used 252only in X11.) PDC_scr_open() must allocate memory for SP, and must 253initialize acs_map[] (unless it's preset) and several members of SP, 254including lines, cols, mouse_wait, orig_attr (and if orig_attr is TRUE, 255orig_fore and orig_back), mono, _restore and _preserve. (Although SP is 256used the same way in all ports, it's allocated here in order to allow 257the X11 port to map it to a block of shared memory.) If using an 258existing terminal, and the environment variable PDC_RESTORE_SCREEN is 259set, this function may also store the existing screen image for later 260restoration by PDC_scr_close(). 261 262 263pdcsetsc.c: 264----------- 265 266### int PDC_curs_set(int visibility); 267 268Called from curs_set(). Changes the appearance of the cursor -- 0 turns 269it off, 1 is normal (the terminal's default, if applicable, as 270determined by SP->orig_cursor), and 2 is high visibility. The exact 271appearance of these modes is not specified. 272 273 274pdcutil.c: 275---------- 276 277### void PDC_beep(void); 278 279Emits a short audible beep. If this is not possible on your platform, 280you must set SP->audible to FALSE during initialization (i.e., from 281PDC_scr_open() -- not here); otherwise, set it to TRUE. This function is 282called from beep(). 283 284### void PDC_napms(int ms); 285 286This is the core delay routine, called by napms(). It pauses for about 287(the X/Open spec says "at least") ms milliseconds, then returns. High 288degrees of accuracy and precision are not expected (though desirable, if 289you can achieve them). More important is that this function gives back 290the process' time slice to the OS, so that PDCurses idles at low CPU 291usage. 292 293### const char *PDC_sysname(void); 294 295Returns a short string describing the platform, such as "DOS" or "X11". 296This is used by longname(). It must be no more than 100 characters; it 297should be much, much shorter (existing platforms use no more than 5). 298 299 300More functions 301============== 302 303The following functions are implemented in the platform directories, but 304are accessed directly by apps. Refer to the user documentation for their 305descriptions: 306 307 308pdcclip.c: 309---------- 310 311### int PDC_clearclipboard(void); 312### int PDC_freeclipboard(char *contents); 313### int PDC_getclipboard(char **contents, long *length); 314### int PDC_setclipboard(const char *contents, long length); 315 316 317pdckbd.c: 318--------- 319 320### unsigned long PDC_get_input_fd(void); 321 322 323pdcsetsc.c: 324----------- 325 326### int PDC_set_blink(bool blinkon); 327### void PDC_set_title(const char *title); 328