13 #define MS_MAGIC 0x131948dd
34 struct hist_node
*hist_list
;
35 struct hist_node
*hist_curr
;
46 add_hist(struct hist_node
**head
, const char *val
)
49 struct hist_node
*c
, *f
= NULL
;
52 if (val
[0] == 0 || val
[0] == '\n')
55 list_for(head
, c
, len
) {
56 if (len
>= HIST_SIZE
) {
63 if (!strcmp(c
->hist
, val
)) {
71 list_prepend(head
, f
);
81 f
= malloc(sizeof(*f
));
88 list_prepend(head
, f
);
93 pmc_buffer(void *s
, const char *data
, size_t len
)
95 struct mcl_screen
*scr
= (struct mcl_screen
*)s
;
96 if (scr
->magic
!= MS_MAGIC
)
99 cb_append(scr
->buffer
, data
, len
);
105 pmc_get_scrollback(void *s
)
107 struct mcl_screen
*scr
= (struct mcl_screen
*)s
;
108 if (scr
->magic
!= MS_MAGIC
)
111 return scr
->scrollback
;
115 /* Zaps the contents of a bar */
117 pmc_write_bar(void *sp
, int bar
, const char *str
)
119 struct mcl_screen
*scr
= (struct mcl_screen
*)sp
;
124 if (scr
->magic
!= MS_MAGIC
)
127 /* only go until first newline */
128 s
= strchr(str
, '\n');
135 //debug_print("Writing %d bytes to window\n", len);
136 /* XXX TODO internal function below here */
143 /* zero out the rest */
146 mvwaddnstr(w
, 0, 0, str
, len
);
148 for (x
= len
; x
< wx
; x
++)
149 mvwaddch(w
, 0, x
, ' ');
156 pmc_copyout(void *s
, char *circbuf
)
158 struct mcl_screen
*scr
= (struct mcl_screen
*)s
;
159 if (scr
->magic
!= MS_MAGIC
)
162 cb_append(circbuf
, scr
->ibuf
, cb_length(scr
->ibuf
));
169 check_triggers(struct mcl_screen
*scr
, char *line
)
173 //debug_print("Line: %s", line);
175 if (!strcmp(line
,"+=--------------------------------------------------------------------------=+\n")) {
176 for (c
= line
- 3; c
>= scr
->scrollback
; c
--) {
180 while (*c
== '\n' || *c
== '\r' || *c
== ' ' || *c
== '\t')
183 pmc_write_bar(scr
, BAR_TOP
, c
);
196 struct mcl_screen
*scr
= (struct mcl_screen
*)s
;
197 size_t len
, olen
, slen
;
202 if (scr
->magic
!= MS_MAGIC
)
205 while ((len
= cb_length(scr
->buffer
))) {
209 for (x
= 0; x
< len
; x
++) {
210 if (scr
->buffer
[x
] == '\n') {
220 slen
= ansi_strip(scr
->scrollback
, scr
->buffer
, olen
);
221 line
= &scr
->scrollback
[cb_length(scr
->scrollback
) - slen
];
222 check_triggers(scr
, line
);
223 olen
= ansi_waddnstr(scr
->output
, scr
->buffer
, olen
);
224 cb_discard(scr
->buffer
, olen
);
228 /* add trailing non-line */
229 len
= cb_length(scr
->buffer
);
232 olen
= ansi_waddnstr(scr
->output
, scr
->buffer
, len
);
233 cb_discard(scr
->buffer
, olen
);
237 wnoutrefresh(scr
->output
);
238 wnoutrefresh(scr
->bar_bot
);
239 wnoutrefresh(scr
->bar_top
);
241 /* Hack to keep the cursor in the input box */
242 getyx(scr
->input
, y
, x
);
243 mvwaddch(scr
->input
, y
, x
,' ');
244 wmove(scr
->input
, y
, x
);
245 wnoutrefresh(scr
->input
);
254 struct mcl_screen
*scr
= (struct mcl_screen
*)s
;
257 if (scr
->magic
!= MS_MAGIC
)
263 getmaxyx(scr
->background
, scr
->ysize
, scr
->xsize
);
265 wresize(scr
->bar_top
, 1, scr
->xsize
);
266 mvwin(scr
->bar_top
, 0, 0);
267 for (x
= 0; x
< scr
->xsize
; x
++)
268 mvwaddch(scr
->bar_top
, 0, x
, ' ');
270 wresize(scr
->output
, scr
->ysize
- 3, scr
->xsize
);
271 mvwin(scr
->output
, 1, 0);
273 wresize(scr
->bar_bot
, 1, scr
->xsize
);
274 mvwin(scr
->bar_bot
, scr
->ysize
- 2, 0);
275 for (x
= 0; x
< scr
->xsize
; x
++)
276 mvwaddch(scr
->bar_bot
, 0, x
, ' ');
278 wresize(scr
->input
, 1, scr
->xsize
);
279 mvwin(scr
->input
, scr
->ysize
- 1, 0);
288 struct mcl_screen
*s
;
293 s
= malloc(sizeof(*s
));
294 memset(s
, 0, sizeof(*s
));
298 s
->background
= initscr();
299 clearok(s
->background
, FALSE
);
305 getmaxyx(s
->background
, s
->ysize
, s
->xsize
);
306 s
->bar_top
= newwin(1, s
->xsize
, 0, 0);
307 idlok(s
->bar_top
, TRUE
);
309 wattr_get(s
->bar_top
, &attr
, &pair
, NULL
);
310 attr
&= ~(A_UNDERLINE
| A_BLINK
);
311 pair
= BG(C_BLUE
)|C_WHITE
;
312 wattr_set(s
->bar_top
, attr
, pair
, NULL
);
314 for (x
= 0; x
< s
->xsize
; x
++)
315 mvwaddch(s
->bar_top
, 0, x
, ' ');
317 s
->output
= newwin(s
->ysize
- 3, s
->xsize
, 1, 0);
318 scrollok(s
->output
, TRUE
);
319 idlok(s
->output
, TRUE
);
321 s
->bar_bot
= newwin(1, s
->xsize
, s
->ysize
-2, 0);
323 wattr_get(s
->bar_bot
, &attr
, &pair
, NULL
);
325 attr
&= ~(A_UNDERLINE
| A_BLINK
);
326 pair
= BG(C_BLUE
)|C_WHITE
;
327 wattr_set(s
->bar_bot
, attr
, pair
, NULL
);
329 for (x
= 0; x
< s
->xsize
; x
++)
330 mvwaddch(s
->bar_bot
, 0, x
, ' ');
332 s
->input
= newwin(1, s
->xsize
, s
->ysize
-1, 0);
333 leaveok(s
->input
, FALSE
);
334 keypad(s
->input
, TRUE
);
336 s
->buffer
= malloc(4096);
337 s
->buffer
= cb_init(s
->buffer
, 4096, NULL
);
338 s
->scrollback
= malloc(16384);
339 s
->scrollback
= cb_init(s
->scrollback
, 16384, NULL
);
341 s
->ibuf
= malloc(1024);
342 s
->ibuf
= cb_init(s
->ibuf
, 1024, NULL
);
351 _erase_word(char *buff
)
359 while (x
>= 0 && (buff
[x
] == ' ' || buff
[x
] == '\t'))
361 while (x
>= 0 && (buff
[x
] != ' ' && buff
[x
] != '\t'))
367 cb_delete(buff
, &buff
[x
+1], y
-x
);
371 /* This prevents a full screen refresh */
373 zap_line(WINDOW
*w
, int line
)
381 /* Wait for keyboard input */
386 struct mcl_screen
*scr
= (struct mcl_screen
*)s
;
390 if (scr
->magic
!= MS_MAGIC
)
393 keystroke
= wgetch(scr
->input
);
394 key
= (char)(keystroke
& 0x0ff);
400 scr
->hist_curr
= NULL
;
402 /* ^/ = local command; don't send */
403 zap_line(scr
->input
, 0);
405 /* add or move history to LRU */
406 add_hist(&scr
->hist_list
, scr
->ibuf
);
408 cb_append(scr
->ibuf
, &key
, 1);
409 if (*scr
->buffer
!= '/')
410 cb_append(scr
->buffer
, &key
, 1);
416 if (scr
->hist_curr
) {
417 scr
->hist_curr
= (void *)(le(scr
->hist_curr
)->le_next
);
419 if (scr
->hist_list
) {
420 scr
->hist_curr
= scr
->hist_list
;
427 cb_strcat(scr
->ibuf
, scr
->hist_curr
->hist
);
428 zap_line(scr
->input
, 0);
429 mvwaddstr(scr
->input
, 0, 0, scr
->ibuf
);
435 if (scr
->hist_curr
) {
436 scr
->hist_curr
= (void *)(le(scr
->hist_curr
)->le_prev
);
438 if (scr
->hist_list
) {
439 scr
->hist_curr
= (void *)(le(scr
->hist_list
)->le_prev
);
446 cb_strcat(scr
->ibuf
, scr
->hist_curr
->hist
);
447 zap_line(scr
->input
, 0);
448 mvwaddstr(scr
->input
, 0, 0, scr
->ibuf
);
454 cb_backspace(scr
->ibuf
, 1);
455 /* optimization- draw a space over previous char */
456 getyx(scr
->input
, y
, x
);
457 mvwaddch(scr
->input
, y
, x
-1, ' ');
458 wmove(scr
->input
, y
, x
-1);
462 /* Erase to last space */
463 _erase_word(scr
->ibuf
);
464 zap_line(scr
->input
, 0);
465 mvwaddstr(scr
->input
, 0, 0, scr
->ibuf
);
470 zap_line(scr
->input
, 0);
474 key
= (char) keystroke
;
478 cb_append(scr
->ibuf
, &key
, 1);
479 waddch(scr
->input
, key
);
481 wnoutrefresh(scr
->input
);