Subversion Repositories SvarDOS

Rev

Rev 1327 | Rev 1330 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1327 Rev 1328
Line 50... Line 50...
50
/* preload the mono scheme (to be overloaded at runtime if color adapter present) */
50
/* preload the mono scheme (to be overloaded at runtime if color adapter present) */
51
static unsigned char scheme[] = {0x07, 0x70, 0x70, 0x70, 0x70, 0xf0};
51
static unsigned char scheme[] = {0x07, 0x70, 0x70, 0x70, 0x70, 0xf0};
52
 
52
 
53
static unsigned char screenw, screenh;
53
static unsigned char screenw, screenh;
54
 
54
 
55
//static union {
-
 
56
static struct {
55
static struct {
57
    unsigned char from;
56
    unsigned char from;
58
    unsigned char to;
57
    unsigned char to;
59
//  };
-
 
60
//  unsigned short fromto;
-
 
61
} uidirty = {0, 0xff}; /* make sure to redraw entire UI at first run */
58
} uidirty = {0, 0xff}; /* make sure to redraw entire UI at first run */
62
//} uidirty = {0xff, 0};
-
 
63
 
59
 
64
#define SCROLL_CURSOR 0xB1
60
#define SCROLL_CURSOR 0xB1
65
 
61
 
66
struct line {
62
struct line {
67
  struct line far *prev;
63
  struct line far *prev;
Line 74... Line 70...
74
  int fd;
70
  int fd;
75
  struct line far *cursor;
71
  struct line far *cursor;
76
  unsigned short xoffset;
72
  unsigned short xoffset;
77
  unsigned char cursorposx;
73
  unsigned char cursorposx;
78
  unsigned char cursorposy;
74
  unsigned char cursorposy;
-
 
75
  unsigned short totlines;
-
 
76
  unsigned short curline;
79
  char lfonly; /* set if line endings are LF (CR/LF otherwise) */
77
  char lfonly; /* set if line endings are LF (CR/LF otherwise) */
80
  char fname[1]; /* dynamically sized */
78
  char fname[1]; /* dynamically sized */
81
};
79
};
82
 
80
 
83
 
81
 
84
/*****************************************************************************
82
/*****************************************************************************
85
 * functions                                                                 *
83
 * functions                                                                 *
86
 *****************************************************************************/
84
 *****************************************************************************/
87
 
85
 
88
/* adds a new line at cursor position into file linked list and dvance cursor
86
/* adds a new line at cursor position into file linked list and advance cursor
89
 * returns non-zero on error */
87
 * returns non-zero on error */
90
static int line_add(struct file *db, const char far *line) {
88
static int line_add(struct file *db, const char far *line, unsigned short slen) {
91
  unsigned short slen;
-
 
92
  struct line far *l;
89
  struct line far *l;
93
 
90
 
94
  /* slen = strlen(line) (but for far pointer) */
-
 
95
  for (slen = 0; line[slen] != 0; slen++);
-
 
96
 
-
 
97
  /* trim out CR/LF line endings */
-
 
98
  if ((slen >= 2) && (line[slen - 2] == '\r')) {
-
 
99
    slen -= 2;
-
 
100
  } else if ((slen >= 1) && (line[slen - 1] == '\n')) {
-
 
101
    slen--;
-
 
102
  }
-
 
103
 
-
 
104
  l = _fcalloc(1, sizeof(struct line) + slen + 1);
91
  l = _fcalloc(1, sizeof(struct line) + slen);
105
  if (l == NULL) return(-1);
92
  if (l == NULL) return(-1);
106
 
93
 
107
  l->prev = db->cursor;
94
  l->prev = db->cursor;
108
  if (db->cursor) {
95
  if (db->cursor) {
109
    l->next = db->cursor->next;
96
    l->next = db->cursor->next;
Line 112... Line 99...
112
  }
99
  }
113
  db->cursor = l;
100
  db->cursor = l;
114
  _fmemcpy(l->payload, line, slen);
101
  _fmemcpy(l->payload, line, slen);
115
  l->len = slen;
102
  l->len = slen;
116
 
103
 
-
 
104
  db->totlines += 1;
-
 
105
  db->curline += 1;
-
 
106
 
117
  return(0);
107
  return(0);
118
}
108
}
119
 
109
 
120
 
110
 
121
/* append a nul-terminated string to line at cursor position */
111
/* append a nul-terminated string to line at cursor position */
Line 137... Line 127...
137
 
127
 
138
 
128
 
139
static void db_rewind(struct file *db) {
129
static void db_rewind(struct file *db) {
140
  if (db->cursor == NULL) return;
130
  if (db->cursor == NULL) return;
141
  while (db->cursor->prev) db->cursor = db->cursor->prev;
131
  while (db->cursor->prev) db->cursor = db->cursor->prev;
-
 
132
  db->curline = 0;
142
}
133
}
143
 
134
 
144
 
135
 
145
static void load_colorscheme(void) {
136
static void load_colorscheme(void) {
146
  scheme[COL_TXT] = 0x17;
137
  scheme[COL_TXT] = 0x17;
Line 151... Line 142...
151
  scheme[COL_ERR] = 0x4f;
142
  scheme[COL_ERR] = 0x4f;
152
}
143
}
153
 
144
 
154
 
145
 
155
static void ui_basic(const struct file *db) {
146
static void ui_basic(const struct file *db) {
156
  unsigned char i;
-
 
157
  const char *s = svarlang_strid(0); /* HELP */
147
  const char *s = svarlang_strid(0); /* HELP */
158
  unsigned char helpcol = screenw - (strlen(s) + 4);
148
  unsigned char helpcol = screenw - (strlen(s) + 4);
159
 
149
 
160
  /* fill status bar with background */
150
  /* fill status bar with background */
161
  mdr_cout_char_rep(screenh - 1, 0, ' ', scheme[COL_STATUSBAR1], screenw);
151
  mdr_cout_char_rep(screenh - 1, 0, ' ', scheme[COL_STATUSBAR1], screenw);
Line 174... Line 164...
174
    mdr_cout_str(screenh - 1, helpcol - 5, "CRLF", scheme[COL_STATUSBAR1], 5);
164
    mdr_cout_str(screenh - 1, helpcol - 5, "CRLF", scheme[COL_STATUSBAR1], 5);
175
  }
165
  }
176
 
166
 
177
  mdr_cout_str(screenh - 1, helpcol, " F1=", scheme[COL_STATUSBAR2], 40);
167
  mdr_cout_str(screenh - 1, helpcol, " F1=", scheme[COL_STATUSBAR2], 40);
178
  mdr_cout_str(screenh - 1, helpcol + 4, s, scheme[COL_STATUSBAR2], 40);
168
  mdr_cout_str(screenh - 1, helpcol + 4, s, scheme[COL_STATUSBAR2], 40);
179
 
-
 
180
  /* scroll bar */
-
 
181
  for (i = 0; i < (screenh - 1); i++) {
-
 
182
    mdr_cout_char(i, screenw - 1, SCROLL_CURSOR, scheme[COL_SCROLLBAR]);
-
 
183
  }
-
 
184
}
169
}
185
 
170
 
186
 
171
 
187
static void ui_msg(const char *msg, unsigned char attr) {
172
static void ui_msg(const char *msg, unsigned char attr) {
188
  unsigned short x, y, msglen, i;
173
  unsigned short x, y, msglen, i;
Line 267... Line 252...
267
  if (l == NULL) {
252
  if (l == NULL) {
268
    while ((y < screenh - 1) && (y < uidirty.to)) {
253
    while ((y < screenh - 1) && (y < uidirty.to)) {
269
      mdr_cout_char_rep(y++, 0, ' ', scheme[COL_TXT], screenw - 1);
254
      mdr_cout_char_rep(y++, 0, ' ', scheme[COL_TXT], screenw - 1);
270
    }
255
    }
271
  }
256
  }
-
 
257
 
-
 
258
  /* scroll bar */
-
 
259
  for (y = 0; y < (screenh - 1); y++) {
-
 
260
    mdr_cout_char(y, screenw - 1, SCROLL_CURSOR, scheme[COL_SCROLLBAR]);
-
 
261
  }
-
 
262
 
-
 
263
  /* scroll cursor */
-
 
264
  if (db->totlines >= screenh) {
-
 
265
    unsigned short topline = db->curline - db->cursorposy;
-
 
266
    unsigned short col;
-
 
267
    unsigned short totlines = db->totlines - screenh + 1;
-
 
268
    if (db->totlines - screenh > screenh) {
-
 
269
      col = topline / (totlines / (screenh - 1));
-
 
270
    } else {
-
 
271
      col = topline * (screenh - 1) / totlines;
-
 
272
    }
-
 
273
    if (col >= screenh - 1) col = screenh - 2;
-
 
274
    mdr_cout_char(col, screenw - 1, ' ', scheme[COL_SCROLLBAR]);
-
 
275
  }
272
}
276
}
273
 
277
 
274
 
278
 
275
static void check_cursor_not_after_eol(struct file *db) {
279
static void check_cursor_not_after_eol(struct file *db) {
276
  if (db->xoffset + db->cursorposx <= db->cursor->len) return;
280
  if (db->xoffset + db->cursorposx <= db->cursor->len) return;
Line 286... Line 290...
286
}
290
}
287
 
291
 
288
 
292
 
289
static void cursor_up(struct file *db) {
293
static void cursor_up(struct file *db) {
290
  if (db->cursor->prev != NULL) {
294
  if (db->cursor->prev != NULL) {
-
 
295
    db->curline -= 1;
291
    db->cursor = db->cursor->prev;
296
    db->cursor = db->cursor->prev;
292
    if (db->cursorposy == 0) {
297
    if (db->cursorposy == 0) {
293
      uidirty.from = 0;
298
      uidirty.from = 0;
294
      uidirty.to = 0xff;
299
      uidirty.to = 0xff;
295
    } else {
300
    } else {
Line 316... Line 321...
316
}
321
}
317
 
322
 
318
 
323
 
319
static void cursor_down(struct file *db) {
324
static void cursor_down(struct file *db) {
320
  if (db->cursor->next != NULL) {
325
  if (db->cursor->next != NULL) {
-
 
326
    db->curline += 1;
321
    db->cursor = db->cursor->next;
327
    db->cursor = db->cursor->next;
322
    if (db->cursorposy < screenh - 2) {
328
    if (db->cursorposy < screenh - 2) {
323
      db->cursorposy += 1;
329
      db->cursorposy += 1;
324
    } else {
330
    } else {
325
      uidirty.from = 0;
331
      uidirty.from = 0;
Line 389... Line 395...
389
    db->cursor->next->prev = db->cursor;
395
    db->cursor->next->prev = db->cursor;
390
    if (db->cursor->prev != NULL) db->cursor->prev->next = db->cursor; /* in case realloc changed my pointer */
396
    if (db->cursor->prev != NULL) db->cursor->prev->next = db->cursor; /* in case realloc changed my pointer */
391
    _ffree(nextline);
397
    _ffree(nextline);
392
    uidirty.from = db->cursorposy;
398
    uidirty.from = db->cursorposy;
393
    uidirty.to = 0xff;
399
    uidirty.to = 0xff;
-
 
400
    db->totlines -= 1;
394
  }
401
  }
395
}
402
}
396
 
403
 
397
 
404
 
398
static void bkspc(struct file *db) {
405
static void bkspc(struct file *db) {
Line 460... Line 467...
460
  }
467
  }
461
 
468
 
462
  db->lfonly = 1;
469
  db->lfonly = 1;
463
 
470
 
464
  /* start by adding an empty line */
471
  /* start by adding an empty line */
465
  if (line_add(db, "") != 0) {
472
  if (line_add(db, NULL, 0) != 0) {
466
    /* TODO ERROR HANDLING */
473
    /* TODO ERROR HANDLING */
467
  }
474
  }
468
 
475
 
469
  for (eolfound = 0;;) {
476
  for (eolfound = 0;;) {
470
    unsigned short consumedbytes;
477
    unsigned short consumedbytes;
Line 505... Line 512...
505
      break;
512
      break;
506
    }
513
    }
507
 
514
 
508
    /* add a new line if necessary */
515
    /* add a new line if necessary */
509
    if (eolfound) {
516
    if (eolfound) {
510
      if (line_add(db, "") != 0) {
517
      if (line_add(db, NULL, 0) != 0) {
511
      /* TODO ERROR HANDLING */
518
      /* TODO ERROR HANDLING */
512
        mdr_coutraw_puts("out of memory");
519
        mdr_coutraw_puts("out of memory");
513
        free(db);
520
        free(db);
514
        db = NULL;
521
        db = NULL;
515
        break;
522
        break;
Line 530... Line 537...
530
 
537
 
531
  SKIPLOADING:
538
  SKIPLOADING:
532
 
539
 
533
  /* add an empty line at end if not present already, also rewind cursor to top of file */
540
  /* add an empty line at end if not present already, also rewind cursor to top of file */
534
  if (db != NULL) {
541
  if (db != NULL) {
535
    if ((db->cursor == NULL) || (db->cursor->len != 0)) line_add(db, "");
542
    if ((db->cursor == NULL) || (db->cursor->len != 0)) line_add(db, NULL, 0);
536
    db_rewind(db);
543
    db_rewind(db);
537
  }
544
  }
538
 
545
 
539
  return(db);
546
  return(db);
540
}
547
}
Line 632... Line 639...
632
 
639
 
633
    if (uidirty.from != 0xff) {
640
    if (uidirty.from != 0xff) {
634
      ui_refresh(db);
641
      ui_refresh(db);
635
      uidirty.from = 0xff;
642
      uidirty.from = 0xff;
636
    }
643
    }
-
 
644
#ifdef DBG_LINENUM
-
 
645
      {
-
 
646
        char ddd[10];
-
 
647
        db->curline += 1;
-
 
648
        ddd[0] = '0' + db->curline / 100;
-
 
649
        ddd[1] = '0' + (db->curline % 100) / 10;
-
 
650
        ddd[2] = '0' + (db->curline % 10);
-
 
651
        db->curline -= 1;
-
 
652
        ddd[3] = '/';
-
 
653
        ddd[4] = '0' + db->totlines / 100;
-
 
654
        ddd[5] = '0' + (db->totlines % 100) / 10;
-
 
655
        ddd[6] = '0' + (db->totlines % 10);
-
 
656
        ddd[7] = 0;
-
 
657
        mdr_cout_str(screenh - 1, 40, ddd, scheme[COL_STATUSBAR1], sizeof(ddd));
-
 
658
      }
-
 
659
#endif
637
 
660
 
638
    k = keyb_getkey();
661
    k = keyb_getkey();
639
 
662
 
640
    if (k == 0x150) { /* down */
663
    if (k == 0x150) { /* down */
641
      cursor_down(db);
664
      cursor_down(db);
Line 663... Line 686...
663
 
686
 
664
    } else if (k == 0x1B) { /* ESC */
687
    } else if (k == 0x1B) { /* ESC */
665
      break;
688
      break;
666
 
689
 
667
    } else if (k == 0x0D) { /* ENTER */
690
    } else if (k == 0x0D) { /* ENTER */
-
 
691
      unsigned short off = db->xoffset + db->cursorposx;
668
      /* add a new line */
692
      /* add a new line */
669
      if (line_add(db, db->cursor->payload + db->xoffset + db->cursorposx) == 0) {
693
      if (line_add(db, db->cursor->payload + off, db->cursor->len - off) == 0) {
-
 
694
        db->cursor = db->cursor->prev; /* back to original line */
-
 
695
        db->curline -= 1;
670
        /* trim the line above */
696
        /* trim the line above */
671
        db->cursor->prev->len = db->xoffset + db->cursorposx;
697
        db->cursor->len = off;
672
        db->cursor->prev->payload[db->cursor->prev->len] = 0;
-
 
673
        /* move cursor to the (new) line below */
698
        /* move cursor to the (new) line below */
674
        db->cursorposx = 0;
-
 
675
        if (db->cursorposy < screenh - 2) {
-
 
676
          uidirty.from = db->cursorposy;
699
        uidirty.from = db->cursorposy;
677
          db->cursorposy++;
-
 
678
        } else {
-
 
679
          uidirty.from = 0;
-
 
680
        }
-
 
681
        uidirty.to = 0xff;
700
        uidirty.to = 0xff;
-
 
701
        cursor_down(db);
-
 
702
        cursor_home(db);
682
      } else {
703
      } else {
683
        /* ERROR: OUT OF MEMORY */
704
        /* ERROR: OUT OF MEMORY */
684
      }
705
      }
685
 
706
 
686
    } else if (k == 0x153) {  /* DEL */
707
    } else if (k == 0x153) {  /* DEL */