/* * FIELD.C - Kentt„toiminnot WND-ikkunointikirjastoon / H. Talvitie 9.4.91 * * L„hdekoodi soveltuu sellaisenaan Turbo C:lle. * */ #include #include #include #include #include #include "wnd.h" void init_fields(WND *wnd) /* * Tyhjennet„„n kenttien puskurit ja kentt„lista * */ { FIELD *fld, *fl; fld = FHEAD; while (fld) { fl = fld->fnxt; strcpy(fld->buff, ""); /* tyhjennet„„n puskurit */ free(fld); fld = fl; } FHEAD = NULL; wnd->maxfield = 0; } FIELD *fdef(WND *wnd, int x, int y, int w, char *buffer) /* * M„„ritell„„n kentt„ ikkunaan wnd * */ { FIELD *fld; int i; if ( (fld = (FIELD *)malloc(sizeof(FIELD))) == NULL) { return NULL; } fld->x = x; /* x-koordinaati */ fld->y = y; /* y-koordinaati */ fld->w = w; /* leveys */ fld->buff = buffer; fld->fnxt = fld->fprv = NULL; addfield(wnd, fld); return fld; } static void addfield(WND *wnd, FIELD *fld) { if (FTAIL) { fld->fprv = FTAIL; FTAIL->fnxt = fld; } FTAIL = fld; if (!FHEAD) FHEAD = fld; wnd->maxfield++; } void upd_cursor(WND *wnd) { cursor(wnd->x+wnd->nx+2, wnd->y+wnd->ny+2); } int get_selection(WND *wnd) /* * K„sitell„„n ikkunan wnd kent„t * */ { FIELD *fld = FHEAD; int ch, i = 0, j = 0, bloc = 0, highest = 0, mode = OVERWRITE; bloc = highest = draw_field(wnd, fld); do { ch = get_char(); switch (ch) { /* K„sitell„„n n„pp„inpainallus ch: */ case ESC : case ENTER : break; case INS : mode = (mode == INSERT ? OVERWRITE : INSERT); upd_curtype(mode); break; case DOWN : erase_field(wnd, fld); fld = fld->fnxt; i++; if (fld == NULL) { fld = FHEAD; i = 0; } mode = OVERWRITE; upd_curtype(mode); bloc = highest = draw_field(wnd, fld); break; case UP : erase_field(wnd, fld); fld = fld->fprv; i--; mode = OVERWRITE; upd_curtype(mode); if (fld == NULL) { fld = FTAIL; i = wnd->maxfield-1; } bloc = highest = draw_field(wnd, fld); break; case PGUP : if (i == 0) break; erase_field(wnd, fld); fld = FHEAD; i = 0; mode = OVERWRITE; upd_curtype(mode); bloc = highest = draw_field(wnd, fld); break; case PGDN : if (i+1 >= wnd->maxfield) break; erase_field(wnd, fld); fld = FTAIL; i = wnd->maxfield-1; mode = OVERWRITE; upd_curtype(mode); bloc = highest = draw_field(wnd, fld); break; case HOME : wnd->nx = wnd->nx - bloc; bloc = 0; upd_cursor(wnd); break; case END : wnd->nx = wnd->nx + highest - bloc; bloc = highest; upd_cursor(wnd); break; case LEFT : if (bloc > 0) { bloc--; wnd->nx--; upd_cursor(wnd); } else printf("\a"); break; case RIGHT : if (bloc < fld->w) { bloc++; wnd->nx++; upd_cursor(wnd); } else printf("\a"); break; case BS : /* Backspace */ if (bloc > 0) { for (j = bloc; j <= highest; j++) { putfast(wnd->x+fld->x+j, wnd->y+fld->y+1, wnd->col[RVR], fld->buff[j]); fld->buff[j-1] = fld->buff[j]; } bloc--; wnd->nx--; } else { printf("\a"); } highest = get_highest(fld); fld->buff[highest] = '\0'; upd_cursor(wnd); break; case DELETE : if (highest > 0) { for (j = bloc; j < highest; j++) { putfast(wnd->x+fld->x+j+1, wnd->y+fld->y+1, wnd->col[RVR], fld->buff[j+1]); fld->buff[j] = fld->buff[j+1]; } } else { printf("\a"); } highest = get_highest(fld); fld->buff[highest] = '\0'; break; default : /* K„sitell„„n merkin sy”tt” */ if (bloc >= fld->w) { printf("\a"); /* Ei mahdu */ break; } if (mode == INSERT) { if (highest < fld->w) { for (j = highest; j > bloc; j--) { putfast(wnd->x+fld->x+j+1, wnd->y+fld->y+1, wnd->col[RVR], fld->buff[j-1]); fld->buff[j] = fld->buff[j-1]; } highest++; } else { printf("\a"); break; } } fld->buff[bloc++] = ch; /* Merkki puskuriin */ highest = get_highest(fld); fld->buff[highest] = '\0'; for (j = 0; j < highest; j++) if (fld->buff[j] == '\0') fld->buff[j] = ' '; putfast(wnd->x+wnd->nx+1, wnd->y+wnd->ny+1, wnd->col[RVR], ch); wnd->nx++; upd_cursor(wnd); /* Kohdistimelle uusi paikka */ break; } } while (ch != ESC && ch != ENTER); upd_curtype(OVERWRITE); erase_field(wnd, fld); return (ch == ESC ? -1 : i); } int get_highest(FIELD *fld) { int j; for (j = fld->w-1; j >= 0; j--) if (fld->buff[j] != ' ' && fld->buff[j] != '\0') break; return j+1; } static WND *fw; int draw_field(WND *wnd, FIELD *fld) /* * Piirret„„n kentt„ fld ikkunaan wnd * */ { int i, len = strlen(fld->buff); fw = wdef(fld->x+wnd->x+1, fld->y+wnd->y+1, fld->w, 1, FALSE); wcol(fw, TXT, wnd->col[RVR]+TRN); wopen(fw); wnd->nx = fld->x; wnd->ny = fld->y; if (fld->buff[0]) { wprint(fw, 0, 0, fw->col[TXT], fld->buff); wnd->nx = fld->x + len; } cursor(wnd->x+wnd->nx+2, wnd->y+wnd->ny+2); return len; } void erase_field(WND *wnd, FIELD *fld) { int oldx = fw->x-wnd->x, oldy = fw->y-wnd->y, oldcol = wnd->col[TXT], i; wclose(fw); for (i = fld->w-1; i >= 0; i--) if (fld->buff[i] != ' ' && fld->buff[i] != '\0') break; fld->buff[i+1] = '\0'; wprint(wnd, oldx, oldy, oldcol, fld->buff); for ( ; i < fld->w-1; i++) putfast(wnd->x+fld->x+i+2, wnd->y+fld->y+1, oldcol, ' '); } int get_char(void) /* * Haetaan n„pp„inpainallus k„ytt„j„lt„. * */ { int scan, asci, c; union REGS regs; while (1) { regs.h.ah = 1; int86(0x16, ®s, ®s); if (regs.x.flags & 0x40) { int86(0x28, ®s, ®s); continue; } regs.h.ah = 0; int86(0x16, ®s, ®s); scan = regs.h.ah; asci = regs.h.al; if (asci == 0) c = scan + 1000; else c = asci; break; } return c; } /* Asetetaan kursorin ulkon„k” vastaamaan vallitsevaa tilaa: */ void cursor(int x, int y) { union REGS regs; regs.x.ax = 0x0200; regs.x.bx = 0; regs.x.dx = ( ((y-1) << 8) & 0xff00 ) + x - 1; int86(16, ®s, ®s); } void upd_curtype(int type) { union REGS regs; regs.x.ax = 0x0100; regs.x.bx = 0; regs.x.cx = (type ? 0x0106 : 0x0607); int86(16, ®s, ®s); }