/* io.c */ #include "\yossi\common.h" #include #include #include #include #include #include #define SET_CHAR(x,y,c) (gotoxy(x+1,y+1), putch(c)) int set_char_indx; #define STATUS_LINE (SCR_ERROR_LINE-2) #define SCROLL_TOP 10 #define SCROLL_BOTTOM 19 char scr_msg_on = NO, scr_cursor_on = YES; char scr_languege = HEBREW; char scr_attribute=0x07; int scr_x=0, scr_y=0; int scr_left_margin=0, scr_right_margin=SCR_WIDTH-1; int scr_top_margin=0, scr_bottom_margin=SCR_HEIGHT-2; float scr_unit_size; int scr_unit_x; long scr_unit_chars, scr_unit_sum; FILE *scr_in_file; int scr_c=0, scr_old_c=0; int scroll_line=SCROLL_TOP; int scr_break(void); void scr_error_line_msg(char *line, char *severity, char confirm); /****************************************************************************** SCR_DRAW_LOGO ============= Draws the first screen with title which is passed as parameter ******************************************************************************/ void scr_draw_logo(char *title) { int i; scr_left_margin=0; scr_right_margin=SCR_WIDTH-1; scr_top_margin=0; scr_bottom_margin=SCR_HEIGHT-2; window(scr_left_margin, scr_top_margin, scr_right_margin, scr_bottom_margin); setcbrk(1); ctrlbrk(scr_break); scr_attrib(SCR_NORMAL); clrscr(); scr_hide_cursor(); /* draw box */ SET_CHAR(0, 0, ''); SET_CHAR(0, scr_bottom_margin, ''); SET_CHAR(scr_right_margin, 0, ''); SET_CHAR(scr_right_margin, scr_bottom_margin, ''); for (i=1; i >", title); scr_attrib(SCR_NORMAL); scr_left_margin=1; scr_right_margin=SCR_WIDTH-2; scr_top_margin=1; scr_bottom_margin=SCR_HEIGHT-2; } #define INPUT_MSG ": " #define OUTPUT_MSG ": " /****************************************************************************** SCR_OPEN_FILES ==> Delete in future ============== Prompts for file names and opens the files ******************************************************************************/ void scr_open_files(void **infile, void **outfile, char b_mode_in, char b_mode_out) { char infile_name[MAX_FILE_NAME+1], outfile_name[MAX_FILE_NAME+1]; char s[2], del, save_lang=scr_languege; of1: scr_goto(SCR_WIDTH-9, 6); del = scr_prompt_input(INPUT_MSG, infile_name, MAX_FILE_NAME, HEBREW, ENGLISH, NO); if (del == ESC) scr_finish(0); else if (del != CR && del != LF) goto of1; *infile = fopen(infile_name, b_mode_in ? "rb" : "r"); if (*infile == NULL) { scr_error(NO, "\"%s\" : ", infile_name); goto of1; } of2: scr_goto(SCR_WIDTH-10, 9); del = scr_prompt_input(OUTPUT_MSG, outfile_name, MAX_FILE_NAME, HEBREW, ENGLISH, NO); if (del == ESC) { fclose(*infile); goto of1; } else if (del != LF && del != CR) goto of2; else if (*outfile_name == NULL) { strmfe(outfile_name, infile_name, "out"); scr_lang(ENGLISH); scr_out(outfile_name); } *outfile = fopen(outfile_name, b_mode_out ? "wb" : "w"); if (*outfile == NULL) { scr_error(NO, "\"%s\" : ", outfile_name); goto of2; } of3: scr_goto(SCR_WIDTH-20, SCR_HEIGHT-5); del = scr_prompt_input(" ", s, 1, HEBREW, HEBREW, YES); scr_del_line(SCR_HEIGHT-5); if (del == ESC) { fclose(*outfile); goto of2; } else if (del != 10 && del != 13) goto of3; scr_languege = save_lang; } char *scr_open_next_file(char *title) { static char file_name[MAXPATH], drive[MAXDRIVE], dir[MAXDIR]; static struct ffblk ffblk; static char in_list=NO; char file_list[30], name[MAXFILE], ext[MAXEXT], del, more; char *out_name; if (in_list == NO || findnext(&ffblk) != NULL) { l1: scr_goto(75, 8); del = scr_prompt_input(title, file_list, sizeof file_list, HEBREW, ENGLISH, NO); if (del != ESC) { fnsplit(file_list, drive, dir, NULL, NULL); if (findfirst(file_list, &ffblk, 0) != 0) { scr_error(NO, " "); goto l1; } else in_list = YES; more = YES; } else more = NO; } if (more) { fnsplit(ffblk.ff_name, NULL, NULL, name, ext); fnmerge(file_name, drive, dir, name, ext); out_name = file_name; } else { out_name = NULL; in_list = NO; } return out_name; } void scr_close_file_with_scroll(char *msg) { if (scroll_line != SCROLL_TOP) { if (msg) { scr_goto(scr_right_margin-2, scroll_line); scr_out(msg); SCR_BEEP; } fclose(scr_in_file); } } char scr_open_file_with_scroll(char *name, char *msg, char bin) { struct ffblk ffblk; if (name) { scr_in_file = fopen(name, bin ? "rb" : "r"); if (scr_in_file == NULL) { scr_error(YES, "%s ", name); return NO; } } if (name && scr_in_file) { if (findfirst(name, &ffblk, 0) != 0) scr_fatal(YES, "open_file_with_scroll- "); if (msg) { if (scroll_line < SCROLL_BOTTOM) scroll_line++; else scr_scroll(scr_left_margin, scr_right_margin, SCROLL_TOP, SCROLL_BOTTOM, -1); scr_goto (scr_right_margin-2, scroll_line); scr_out ("( %ld) %s %s", ffblk.ff_fsize, name, msg); } scr_del_line (STATUS_LINE-1); scr_del_line (STATUS_LINE); scr_goto (scr_left_margin, STATUS_LINE-1); scr_lang (HEBREW); scr_out (" 0"); scr_goto (scr_right_margin, STATUS_LINE-1); scr_out (" %ld", ffblk.ff_fsize); scr_unit_size = scr_unit_sum = (float)ffblk.ff_fsize / (scr_right_margin-scr_left_margin+1); scr_unit_x = 0; scr_unit_chars = 0; } return YES; } int scr_get_char (void) { if (scr_old_c) { scr_c = scr_old_c; scr_old_c = 0; } else { scr_c = fgetc (scr_in_file); if (++scr_unit_chars > scr_unit_sum) { scr_unit_sum = scr_unit_size*(++scr_unit_x); scr_goto (scr_unit_x, STATUS_LINE); scr_out (""); scr_hide_cursor(); } } return scr_c; } void scr_unget_char (void) { scr_old_c = scr_c; } /****************************************************************************** SCR_OUT ======== Displayes text on the screen according to given coordinates and scr_attribs. ******************************************************************************/ void scr_out(char *format,...) { char line[SCR_WIDTH*2], *txt=line; int i, len; va_list argptr; va_start (argptr, format); if (vsprintf (line, format, argptr) >= sizeof line) scr_fatal (YES, "scr_out- "); va_end (argptr); len = strlen (txt); if (scr_languege == HEBREW) scr_x -= (len-1); if (scr_x+len-1 > scr_right_margin) len = scr_right_margin - scr_x; if (scr_x < scr_left_margin) scr_x = scr_left_margin; for (i=scr_x; *txt && i <= scr_right_margin; i++, txt++) SET_CHAR (i, scr_y, *txt); if (scr_languege == ENGLISH) scr_x += len; else scr_x--; } /****************************************************************************** SCR_LANG ======== Sets languege for next text or input ******************************************************************************/ void scr_lang (int lang) { scr_languege = lang; } /****************************************************************************** SCR_GOTO ======== Sets screen location (X, Y). Locations start from 0 ******************************************************************************/ void scr_goto (int x, int y) { if (x < scr_left_margin) scr_x = scr_left_margin; else if (x > scr_right_margin) scr_x = scr_right_margin; else scr_x = x; if (y < scr_top_margin) scr_y = scr_top_margin; else if (y > scr_bottom_margin) scr_y = scr_bottom_margin; else scr_y = y; if (scr_cursor_on) SCR_GOTO (scr_x+1, scr_y+1); } /****************************************************************************** SCR_ATTRIB ========== Sets screen scr_attribs which can be combined from: SCR_NORMAL, SCR_BOLD, SCR_UNDERLINE, SCR_BLINK, SCR_REVERSE ******************************************************************************/ void scr_attrib(int attrib) { int color = ((attrib & SCR_UNDERLINE) ? BLUE : LIGHTGRAY); int color_rev = BLACK; if (attrib & SCR_BOLD) { color += 8; color_rev += 8; } if (attrib & SCR_REVERSE) { textattr(color_rev + ((attrib & SCR_BLINK) ? BLINK : 0)); textbackground(color); } else { textattr(color + ((attrib & SCR_BLINK) ? BLINK : 0)); textbackground(color_rev); } } /****************************************************************************** SCR_PROMPT_INPUT ================ Displayes prompt and read input string. INPUTS: msg - prompt to display str - string to read len - length of input msg_lang - languege of msg str_lang - languege of input string auto_len - automaticly finish input when string length reaches len ******************************************************************************/ char scr_prompt_input(char *msg, char *str, int len, int msg_lang, int str_lang, int auto_len) { int x, input_x; char del, save_lang=scr_languege, save_attrib=scr_attribute; x = scr_x; scr_attrib (SCR_UNDERLINE | SCR_BOLD); scr_lang (msg_lang); scr_out(msg); if (msg_lang == HEBREW) input_x = (str_lang == ENGLISH ? scr_x-1-len : scr_x-1); else input_x = (str_lang == HEBREW ? scr_x+1+len : scr_x+1); scr_goto(input_x, scr_y); len -= abs(input_x - scr_x); scr_lang(str_lang); del = scr_read_str (str, len, auto_len, NULL); scr_goto (x, scr_y); scr_attrib (SCR_NORMAL); scr_lang (msg_lang); scr_out(msg); scr_goto (input_x, scr_y); scr_lang (str_lang); scr_out(str); scr_languege = save_lang; scr_attribute = save_attrib; return del; } /****************************************************************************** SCR_READ_STR ============ Reads string from consule ******************************************************************************/ char scr_read_str (char *str, int len, int auto_len, char *def) { char c, *p, *p1; signed char dir; int x, end_x, cur_x; int save_attrib=scr_attribute; static char *english_set = "abcdefghijklmnopqrstuvwxyz`;',./"; static char *hebrew_set = "/';,."; x = cur_x = scr_x; if (scr_languege == HEBREW) { end_x = max (scr_left_margin - 1, x - len); dir = -1; } else { end_x = min (scr_right_margin + 1, x + len); dir = 1; } len = abs (end_x - x); scr_attrib (SCR_REVERSE); if (def) { scr_out (def); strncpy (str, def, len); str[len] = NULL; if (scr_languege == HEBREW) p = str + strlen (str); else p = str; } else { p = str; *p = NULL; } if (scr_x != end_x) do scr_out (" "); while (scr_x != end_x); scr_show_cursor(); scr_goto (cur_x, scr_y); c = getch(); /* Get first chr. */ if (scr_msg_on) /* If there is an error massage - clear it */ scr_del_line (SCR_ERROR_LINE); while (c != CR && c != LF && c != ESC) { if ( c > 31 && c < 155 ) /* If printable chr... */ { if (strlen(str) < len) { if (scr_languege == HEBREW) { if ((p1=(char *)strchr(english_set, c)) != NULL) c = hebrew_set[(int)(p1-english_set)]; } for (p1=p+strlen(p); p1 >= p; p1--) *(p1+1) = *p1; *p = c; if (scr_languege == ENGLISH) p++; cur_x += dir; scr_goto (x, scr_y); scr_out (str); } else SCR_BEEP; } else if (c == 8) /* Backspace */ { if (scr_languege == ENGLISH && p > str && p-- || *p) { strcpy (p, p+1); cur_x -= dir; scr_goto (x, scr_y); scr_out (str); scr_out (" "); } else SCR_BEEP; } else if (c == 0) { c = getch(); if (c == 75) /* Left arrow */ { if (p > str) { cur_x--; p--; } else SCR_BEEP; } else if (c == 77) /* Right arrow */ { if (*p) { cur_x++; p++; } else SCR_BEEP; } } if (auto_len && strlen(str) >= len) break; SCR_GOTO(cur_x+1, scr_y+1); c = getch(); /* Get next chr. */ } scr_attrib (SCR_NORMAL); scr_goto (x, scr_y); scr_out ("%s", str); if (scr_x != end_x) do scr_out (" "); while (scr_x != end_x); scr_hide_cursor(); scr_attribute = save_attrib; return (char)c; } /****************************************************************************** SCR_FINISH ========== Close files and do screen cleanups ******************************************************************************/ void scr_finish(int rc) { scr_show_cursor(); scr_goto (SCR_WIDTH+1, SCR_HEIGHT+1); fcloseall(); exit(rc); } int scr_break(void) { scr_finish(1); return 0; } void scr_informatory(char confirm, char *format,...) { char line[SCR_WIDTH+1]; va_list argptr; va_start (argptr, format); if (vsprintf (line, format, argptr) >= sizeof line) scr_fatal (YES, "scr_informatory- "); va_end (argptr); scr_error_line_msg (line, "", confirm); } void scr_warning(char confirm, char *format,...) { char line[SCR_WIDTH+1]; va_list argptr; va_start (argptr, format); if (vsprintf (line, format, argptr) >= sizeof line) scr_fatal (YES, "scr_warning- "); va_end (argptr); scr_error_line_msg (line, "", confirm); } void scr_error(char confirm, char *format,...) { char line[SCR_WIDTH+1]; va_list argptr; va_start (argptr, format); if (vsprintf (line, format, argptr) >= sizeof line) scr_fatal (YES, "scr_error- "); va_end (argptr); scr_error_line_msg (line, "", confirm); } void scr_fatal (char confirm, char *format,...) { char line[SCR_WIDTH+1]; va_list argptr; va_start (argptr, format); if (vsprintf (line, format, argptr) >= sizeof line) scr_fatal (YES, "scr_fatal- "); va_end (argptr); scr_error_line_msg (line, " ", confirm); scr_finish(2); } void scr_error_line_msg (char *line, char *severity, char confirm) { char ext_line[2*SCR_WIDTH]; char save_lang=scr_languege, save_attrib=scr_attribute; int save_x=scr_x, save_y=scr_y; if (scr_msg_on) scr_del_line (SCR_ERROR_LINE); if (line && *line) { if (sprintf (ext_line, "%s%s :%s", confirm ? "SPACE -- " : "", line, severity) >= sizeof ext_line) scr_fatal (YES, "scr_error_line_msg- "); scr_x = SCR_WIDTH-(SCR_WIDTH-strlen(ext_line))/2+2; scr_y = SCR_ERROR_LINE; scr_lang (HEBREW); scr_attrib (SCR_BOLD | SCR_BLINK); scr_out (" "); scr_attrib (SCR_BOLD); scr_out (ext_line); scr_attrib (SCR_BOLD | SCR_BLINK); scr_out (" "); if (confirm) while (getch() != ' '); /* Get space */ scr_msg_on = YES; } else scr_msg_on = NO; scr_languege = save_lang; scr_attribute = save_attrib; scr_goto (save_x, save_y); } void scr_del_line(int line) { int i; char save_attrib=scr_attribute; scr_attrib (SCR_NORMAL); for (i=scr_left_margin; i <= scr_right_margin; i++) SET_CHAR (i, line, ' '); scr_attribute = save_attrib; } void scr_hide_cursor (void) { union REGS regs; regs.h.ah = 1; /* Set cursor type */ regs.h.ch = 0x10; regs.h.cl = 0x00; int86 (0x10, ®s, ®s); scr_cursor_on = NO; } void scr_show_cursor (void) { union REGS regs; regs.h.ah = 1; /* Set cursor type */ regs.h.ch = 0x0c; regs.h.cl = 0x0c; int86 (0x10, ®s, ®s); scr_cursor_on = YES; SCR_GOTO (scr_x, scr_y); } void scr_scroll(int x_min, int x_max, int y_min, int y_max, int n) { if (n < 0) movetext(x_min, y_min-n+2, x_max, y_max+2, x_min, y_min+2); else if (n > 0) movetext(x_min, y_min+2, x_max, y_max-n+2, x_min, y_min+n+2); }