18 |
along with this program; if not, write to the Free Software |
along with this program; if not, write to the Free Software |
19 |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ |
20 |
|
|
21 |
|
#include <stddef.h> |
22 |
#include <errno.h> |
#include <errno.h> |
23 |
#include <fcntl.h> |
#include <fcntl.h> |
24 |
#include <unistd.h> |
#include <unistd.h> |
37 |
#include <hurd.h> |
#include <hurd.h> |
38 |
#include <hurd/pager.h> |
#include <hurd/pager.h> |
39 |
|
|
40 |
|
#include "ourfs_notify_U.h" |
41 |
|
|
42 |
#ifndef __STDC_ISO_10646__ |
#ifndef __STDC_ISO_10646__ |
43 |
#error It is required that wchar_t is UCS-4. |
#error It is required that wchar_t is UCS-4. |
44 |
#endif |
#endif |
49 |
|
|
50 |
struct cursor |
struct cursor |
51 |
{ |
{ |
52 |
u_int32_t saved_x; |
uint32_t saved_x; |
53 |
u_int32_t saved_y; |
uint32_t saved_y; |
54 |
}; |
}; |
55 |
typedef struct cursor *cursor_t; |
typedef struct cursor *cursor_t; |
56 |
|
|
117 |
struct pager *p; |
struct pager *p; |
118 |
}; |
}; |
119 |
|
|
120 |
|
/* Pending directory and file modification requests. */ |
121 |
|
struct modreq |
122 |
|
{ |
123 |
|
mach_port_t port; |
124 |
|
struct modreq *next; |
125 |
|
}; |
126 |
|
|
127 |
struct display |
struct display |
128 |
{ |
{ |
129 |
/* The lock for the virtual console display structure. */ |
/* The lock for the virtual console display structure. */ |
143 |
struct user_pager_info *upi; |
struct user_pager_info *upi; |
144 |
memory_object_t memobj; |
memory_object_t memobj; |
145 |
size_t memobj_size; |
size_t memobj_size; |
146 |
|
|
147 |
|
/* A list of ports to send file change notifications to. */ |
148 |
|
struct modreq *filemod_reqs; |
149 |
}; |
}; |
150 |
|
|
151 |
|
|
172 |
free (upi); |
free (upi); |
173 |
} |
} |
174 |
|
|
|
/* XXX This is not good enough. We actually need to provide a backing |
|
|
store. */ |
|
175 |
error_t |
error_t |
176 |
pager_read_page (struct user_pager_info *pager, vm_offset_t page, |
pager_read_page (struct user_pager_info *pager, vm_offset_t page, |
177 |
vm_address_t *buf, int *writelock) |
vm_address_t *buf, int *writelock) |
189 |
vm_offset_t page, |
vm_offset_t page, |
190 |
vm_address_t buf) |
vm_address_t buf) |
191 |
{ |
{ |
192 |
/* XXX Implement me. */ |
/* XXX Implement me. Just store away the page, and release it when |
193 |
|
releasing the pager. */ |
194 |
assert (0); |
assert (0); |
195 |
} |
} |
196 |
|
|
232 |
} |
} |
233 |
|
|
234 |
|
|
235 |
|
/* Free the list of modification requests MR */ |
236 |
|
static void |
237 |
|
free_modreqs (struct modreq *mr) |
238 |
|
{ |
239 |
|
struct modreq *tmp; |
240 |
|
for (; mr; mr = tmp) |
241 |
|
{ |
242 |
|
mach_port_deallocate (mach_task_self (), mr->port); |
243 |
|
tmp = mr->next; |
244 |
|
free (mr); |
245 |
|
} |
246 |
|
} |
247 |
|
|
248 |
|
error_t |
249 |
|
display_notice_changes (display_t display, mach_port_t notify) |
250 |
|
{ |
251 |
|
error_t err; |
252 |
|
struct modreq *req; |
253 |
|
|
254 |
|
mutex_lock (&display->lock); |
255 |
|
err = nowait_file_changed (notify, FILE_CHANGED_NULL, 0, 0); |
256 |
|
if (err) |
257 |
|
{ |
258 |
|
mutex_unlock (&display->lock); |
259 |
|
return err; |
260 |
|
} |
261 |
|
req = malloc (sizeof (struct modreq)); |
262 |
|
if (!req) |
263 |
|
{ |
264 |
|
mutex_unlock (&display->lock); |
265 |
|
return errno; |
266 |
|
} |
267 |
|
req->port = notify; |
268 |
|
req->next = display->filemod_reqs; |
269 |
|
display->filemod_reqs = req; |
270 |
|
mutex_unlock (&display->lock); |
271 |
|
return 0; |
272 |
|
} |
273 |
|
|
274 |
|
/* Requires DISPLAY to be locked. */ |
275 |
|
void |
276 |
|
display_notice_filechange (display_t display, enum file_changed_type type, |
277 |
|
off_t start, off_t end) |
278 |
|
{ |
279 |
|
error_t err; |
280 |
|
struct modreq **preq; |
281 |
|
|
282 |
|
preq = &display->filemod_reqs; |
283 |
|
while (*preq) |
284 |
|
{ |
285 |
|
struct modreq *req = *preq; |
286 |
|
err = nowait_file_changed (req->port, type, start, end); |
287 |
|
if (err) |
288 |
|
{ |
289 |
|
/* Remove notify port. */ |
290 |
|
*preq = req->next; |
291 |
|
mach_port_deallocate (mach_task_self (), req->port); |
292 |
|
free (req); |
293 |
|
} |
294 |
|
else |
295 |
|
preq = &req->next; |
296 |
|
} |
297 |
|
} |
298 |
|
|
299 |
|
|
300 |
static error_t |
static error_t |
301 |
user_create (display_t display, u_int32_t width, u_int32_t height, |
user_create (display_t display, uint32_t width, uint32_t height, |
302 |
u_int32_t lines) |
uint32_t lines) |
303 |
{ |
{ |
304 |
error_t err; |
error_t err; |
305 |
struct cons_display *user; |
struct cons_display *user; |
306 |
display->memobj_size = round_page (sizeof (struct cons_display) + |
display->memobj_size = round_page (sizeof (struct cons_display) + |
307 |
sizeof (u_int32_t) * width * lines); |
sizeof (uint32_t) * width * lines); |
308 |
|
|
309 |
display->upi = malloc (sizeof (struct user_pager_info)); |
display->upi = malloc (sizeof (struct user_pager_info)); |
310 |
if (!display->upi) |
if (!display->upi) |
347 |
user->screen.lines = lines; |
user->screen.lines = lines; |
348 |
user->screen.cur_line = 0; |
user->screen.cur_line = 0; |
349 |
user->screen.scr_lines = 0; |
user->screen.scr_lines = 0; |
350 |
user->screen.matrix = sizeof (struct cons_display) / sizeof (u_int32_t); |
user->screen.matrix = sizeof (struct cons_display) / sizeof (uint32_t); |
351 |
user->cursor.col = 0; |
user->cursor.col = 0; |
352 |
user->cursor.row = 0; |
user->cursor.row = 0; |
353 |
user->cursor.status = CONS_CURSOR_NORMAL; |
user->cursor.status = CONS_CURSOR_NORMAL; |
366 |
} |
} |
367 |
|
|
368 |
|
|
|
#define MATRIX_POS(user,x,y) ((user)->_matrix \ |
|
|
+ (((user)->screen.cur_line + (y)) % (user)->screen.height) \ |
|
|
* (user)->screen.width + (x)) |
|
|
|
|
369 |
static void |
static void |
370 |
screen_fill (display_t display, size_t x, size_t y, size_t w, size_t h, |
screen_fill (display_t display, size_t col1, size_t row1, size_t col2, |
371 |
wchar_t chr, char attr) |
size_t row2, wchar_t chr, char attr) |
372 |
{ |
{ |
373 |
struct cons_display *user = display->user; |
struct cons_display *user = display->user; |
374 |
wchar_t *matrixp = MATRIX_POS (user, x, y); |
off_t start = (user->screen.cur_line + row1) * user->screen.width + col1; |
375 |
|
off_t end = (user->screen.cur_line + row2) * user->screen.width + col2; |
376 |
|
off_t size = user->screen.width * user->screen.lines; |
377 |
|
|
378 |
while (h--) |
if (start >= size && end >= size) |
379 |
{ |
{ |
380 |
/* XXX Set attribute flags. */ |
start -= size; |
381 |
wmemset (matrixp, L' ', w); |
end -= size; |
|
matrixp += user->screen.width; |
|
382 |
} |
} |
383 |
|
|
384 |
/* XXX Flag screen change, but here or where else? */ |
if (end < size) |
|
} |
|
|
|
|
|
static void |
|
|
screen_scroll_up (display_t display, size_t x, size_t y, size_t w, size_t h, |
|
|
int amt, wchar_t chr, char attr) |
|
|
{ |
|
|
struct cons_display *user = display->user; |
|
|
wchar_t *matrixp = MATRIX_POS (user, x, y); |
|
|
|
|
|
if (amt < 0) |
|
|
return; |
|
|
|
|
|
while (h-- > amt) |
|
385 |
{ |
{ |
386 |
wmemcpy (matrixp, matrixp + amt * user->screen.width, w); |
wmemset (user->_matrix + start, chr, end - start + 1); |
387 |
matrixp += user->screen.width; |
display_notice_filechange (display, FILE_CHANGED_WRITE, |
388 |
|
sizeof (struct cons_display) |
389 |
|
+ start * sizeof (wchar_t), |
390 |
|
sizeof (struct cons_display) |
391 |
|
+ (end + 1) * sizeof (wchar_t) - 1); |
392 |
} |
} |
393 |
screen_fill (display, x, y, w, h, chr, attr); |
else |
|
} |
|
|
|
|
|
static void |
|
|
screen_scroll_down (display_t display, size_t x, size_t y, size_t w, size_t h, |
|
|
int amt, wchar_t chr, char attr) |
|
|
{ |
|
|
struct cons_display *user = display->user; |
|
|
wchar_t *matrixp = MATRIX_POS (user, x, y + h - 1); |
|
|
|
|
|
if (amt < 0) |
|
|
return; |
|
|
|
|
|
while (h-- > amt) |
|
394 |
{ |
{ |
395 |
wmemcpy (matrixp, matrixp - amt * user->screen.width, w); |
wmemset (user->_matrix + start, chr, size - start); |
396 |
matrixp -= user->screen.width; |
wmemset (user->_matrix, chr, end - size + 1); |
397 |
|
display_notice_filechange (display, FILE_CHANGED_WRITE, |
398 |
|
sizeof (struct cons_display) |
399 |
|
+ start * sizeof (wchar_t), |
400 |
|
sizeof (struct cons_display) |
401 |
|
+ (end - size + 1) * sizeof (wchar_t) - 1); |
402 |
} |
} |
|
screen_fill (display, x, y, w, h, chr, attr); |
|
403 |
} |
} |
404 |
|
|
405 |
static void |
static void |
406 |
screen_scroll_left (display_t display, size_t x, size_t y, size_t w, size_t h, |
screen_shift_left (display_t display, size_t row1, size_t col1, size_t row2, |
407 |
int amt, wchar_t chr, char attr) |
size_t col2, size_t shift, wchar_t chr, char attr) |
408 |
{ |
{ |
409 |
struct cons_display *user = display->user; |
struct cons_display *user = display->user; |
410 |
wchar_t *matrixp = MATRIX_POS (user, x, y); |
off_t start = (user->screen.cur_line + row1) * user->screen.width + col1; |
411 |
int i; |
off_t end = (user->screen.cur_line + row2) * user->screen.width + col2; |
412 |
|
off_t size = user->screen.width * user->screen.lines; |
413 |
|
|
414 |
if (amt < 0) |
if (start >= size && end >= size) |
415 |
return; |
{ |
416 |
if (amt > w) |
start -= size; |
417 |
amt = w; |
end -= size; |
418 |
|
} |
419 |
|
|
420 |
for (i = 0; i < y + h; i++) |
if (start + shift <= end) |
421 |
{ |
{ |
422 |
wmemmove (matrixp, matrixp + amt, w - amt); |
/* Use a loop to copy the data. Using wmemmove and wmemset on |
423 |
matrixp += user->screen.width; |
the chunks is tiresome, as there are many cases. */ |
424 |
|
off_t src = start + shift; |
425 |
|
off_t dst = start; |
426 |
|
|
427 |
|
while (src <= end) |
428 |
|
user->_matrix[dst++ % size] = user->_matrix[src++ % size]; |
429 |
|
while (dst <= end) |
430 |
|
user->_matrix[dst++ % size] = chr; |
431 |
|
|
432 |
|
display_notice_filechange (display, FILE_CHANGED_TRUNCATE, |
433 |
|
sizeof (struct cons_display) |
434 |
|
+ start * sizeof (wchar_t), |
435 |
|
sizeof (struct cons_display) |
436 |
|
+ (start + shift) * sizeof (wchar_t) - 1); |
437 |
|
display_notice_filechange (display, FILE_CHANGED_EXTEND, |
438 |
|
sizeof (struct cons_display) |
439 |
|
+ (end - shift + 1) * sizeof (wchar_t), |
440 |
|
sizeof (struct cons_display) |
441 |
|
+ (end + 1) * sizeof (wchar_t) - 1); |
442 |
} |
} |
443 |
screen_fill (display, x + w - amt, y, amt, h, chr, attr); |
else |
444 |
|
screen_fill (display, col1, row1, col2, row2, chr, attr); |
445 |
} |
} |
446 |
|
|
447 |
static void |
static void |
448 |
screen_scroll_right (display_t display, size_t x, size_t y, size_t w, size_t h, |
screen_shift_right (display_t display, size_t row1, size_t col1, size_t row2, |
449 |
int amt, wchar_t chr, char attr) |
size_t col2, size_t shift, wchar_t chr, char attr) |
450 |
{ |
{ |
451 |
struct cons_display *user = display->user; |
struct cons_display *user = display->user; |
452 |
wchar_t *matrixp = MATRIX_POS (user, x, y); |
off_t start = (user->screen.cur_line + row1) * user->screen.width + col1; |
453 |
int i; |
off_t end = (user->screen.cur_line + row2) * user->screen.width + col2; |
454 |
|
off_t size = user->screen.width * user->screen.lines; |
455 |
|
|
456 |
if (amt < 0) |
if (start >= size && end >= size) |
457 |
return; |
{ |
458 |
if (amt > w) |
start -= size; |
459 |
amt = w; |
end -= size; |
460 |
|
} |
461 |
|
|
462 |
for (i = 0; i < y + h; i++) |
if (start + shift <= end) |
463 |
{ |
{ |
464 |
wmemmove (matrixp + amt, matrixp, w - amt); |
/* Use a loop to copy the data. Using wmemmove and wmemset on |
465 |
matrixp += user->screen.width; |
the chunks is tiresome, as there are many cases. */ |
466 |
|
off_t src = end - shift; |
467 |
|
off_t dst = end; |
468 |
|
|
469 |
|
while (src >= start) |
470 |
|
user->_matrix[dst-- % size] = user->_matrix[src-- % size]; |
471 |
|
while (dst >= start) |
472 |
|
user->_matrix[dst-- % size] = chr; |
473 |
|
|
474 |
|
display_notice_filechange (display, FILE_CHANGED_EXTEND, |
475 |
|
sizeof (struct cons_display) |
476 |
|
+ start * sizeof (wchar_t), |
477 |
|
sizeof (struct cons_display) |
478 |
|
+ (start + shift) * sizeof (wchar_t) - 1); |
479 |
|
display_notice_filechange (display, FILE_CHANGED_TRUNCATE, |
480 |
|
sizeof (struct cons_display) |
481 |
|
+ (end - shift + 1) * sizeof (wchar_t), |
482 |
|
sizeof (struct cons_display) |
483 |
|
+ (end + 1) * sizeof (wchar_t) - 1); |
484 |
} |
} |
485 |
screen_fill (display, x, y, amt, h, chr, attr); |
else |
486 |
|
screen_fill (display, col1, row1, col2, row2, chr, attr); |
487 |
} |
} |
488 |
|
|
489 |
|
|
705 |
case 0: |
case 0: |
706 |
/* Clear to end of screen: <ed>. */ |
/* Clear to end of screen: <ed>. */ |
707 |
screen_fill (display, user->cursor.col, user->cursor.row, |
screen_fill (display, user->cursor.col, user->cursor.row, |
708 |
user->screen.width - user->cursor.col, 1, L' ', |
user->screen.width - 1, user->screen.height - 1, |
709 |
display->attr.current); |
L' ', display->attr.current); |
|
screen_fill (display, 0, user->cursor.row + 1, |
|
|
user->screen.width, |
|
|
user->screen.height - user->cursor.row, |
|
|
L' ', display->attr.current); |
|
710 |
break; |
break; |
711 |
case 1: |
case 1: |
712 |
/* Clear to beginning of screen. */ |
/* Clear to beginning of screen. */ |
713 |
screen_fill (display, 0, 0, |
screen_fill (display, 0, 0, |
714 |
user->screen.width, user->cursor.row, |
user->cursor.col, user->cursor.row, |
|
L' ', display->attr.current); |
|
|
screen_fill (display, 0, user->cursor.row, |
|
|
user->cursor.col + 1, 1, |
|
715 |
L' ', display->attr.current); |
L' ', display->attr.current); |
716 |
break; |
break; |
717 |
case 2: |
case 2: |
718 |
/* Clear entire screen. */ |
/* Clear entire screen. */ |
719 |
screen_fill (display, 0, 0, |
screen_fill (display, 0, 0, |
720 |
user->screen.width, user->screen.height, |
user->screen.width - 1, user->screen.height - 1, |
721 |
L' ', display->attr.current); |
L' ', display->attr.current); |
722 |
break; |
break; |
723 |
} |
} |
728 |
case 0: |
case 0: |
729 |
/* Clear to end of line: <el>. */ |
/* Clear to end of line: <el>. */ |
730 |
screen_fill (display, user->cursor.col, user->cursor.row, |
screen_fill (display, user->cursor.col, user->cursor.row, |
731 |
user->screen.width - user->cursor.col, 1, |
user->screen.width - 1, user->cursor.row, |
732 |
L' ', display->attr.current); |
L' ', display->attr.current); |
733 |
break; |
break; |
734 |
case 1: |
case 1: |
735 |
/* Clear to beginning of line: <el1>. */ |
/* Clear to beginning of line: <el1>. */ |
736 |
screen_fill (display, 0, user->cursor.row, |
screen_fill (display, 0, user->cursor.row, |
737 |
user->cursor.col + 1, 1, |
user->cursor.col, user->cursor.row, |
738 |
L' ', display->attr.current); |
L' ', display->attr.current); |
739 |
break; |
break; |
740 |
case 2: |
case 2: |
741 |
/* Clear entire line. */ |
/* Clear entire line. */ |
742 |
screen_fill (display, 0, user->cursor.row, |
screen_fill (display, 0, user->cursor.row, |
743 |
user->screen.width, 1, |
user->screen.width - 1, user->cursor.row, |
744 |
L' ', display->attr.current); |
L' ', display->attr.current); |
745 |
break; |
break; |
746 |
} |
} |
747 |
break; |
break; |
748 |
case 'L': |
case 'L': |
749 |
/* Insert line(s): <il1>, <il>. */ |
/* Insert line(s): <il1>, <il>. */ |
750 |
screen_scroll_down (display, 0, user->cursor.row, |
screen_shift_right (display, 0, user->cursor.row, |
751 |
user->screen.width, |
user->screen.width - 1, user->screen.height - 1, |
752 |
user->screen.height - user->cursor.row, |
(parse->params[0] ?: 1) * user->screen.width, |
|
parse->params[0] ?: 1, |
|
753 |
L' ', display->attr.current); |
L' ', display->attr.current); |
754 |
break; |
break; |
755 |
case 'M': |
case 'M': |
756 |
/* Delete line(s): <dl1>, <dl>. */ |
/* Delete line(s): <dl1>, <dl>. */ |
757 |
screen_scroll_up (display, 0, user->cursor.row, |
screen_shift_left (display, 0, user->cursor.row, |
758 |
user->screen.width, |
user->screen.width - 1, user->screen.height - 1, |
759 |
user->screen.height - user->cursor.row, |
(parse->params[0] ?: 1) * user->screen.width, |
760 |
parse->params[0] ?: 1, |
L' ', display->attr.current); |
|
L' ', display->attr.current); |
|
761 |
break; |
break; |
762 |
case '@': |
case '@': |
763 |
/* Insert character(s): <ich1>, <ich>. */ |
/* Insert character(s): <ich1>, <ich>. */ |
764 |
screen_scroll_right (display, user->cursor.col, |
screen_shift_right (display, user->cursor.col, user->cursor.row, |
765 |
user->cursor.row, |
user->screen.width - 1, user->cursor.row, |
766 |
user->screen.width - user->cursor.col, 1, |
parse->params[0] ?: 1, |
767 |
parse->params[0] ?: 1, |
L' ', display->attr.current); |
|
L' ', display->attr.current); |
|
768 |
break; |
break; |
769 |
case 'P': |
case 'P': |
770 |
/* Delete character(s): <dch1>, <dch>. */ |
/* Delete character(s): <dch1>, <dch>. */ |
771 |
screen_scroll_left (display, user->cursor.col, |
screen_shift_left (display, user->cursor.col, user->cursor.row, |
772 |
user->cursor.row, |
user->screen.width - 1, user->cursor.row, |
773 |
user->screen.width - user->cursor.col, 1, |
parse->params[0] ?: 1, |
774 |
parse->params[0] ?: 1, |
L' ', display->attr.current); |
|
L' ', display->attr.current); |
|
775 |
break; |
break; |
776 |
case 'S': |
case 'S': |
777 |
/* Scroll up: <ind>, <indn>. */ |
/* Scroll up: <ind>, <indn>. */ |
778 |
screen_scroll_up (display, 0, 0, |
screen_shift_left (display, 0, 0, |
779 |
user->screen.width, user->screen.height, |
user->screen.width - 1, user->screen.height - 1, |
780 |
parse->params[0] ?: 1, |
(parse->params[0] ?: 1) * user->screen.width, |
781 |
L' ', display->attr.current); |
L' ', display->attr.current); |
782 |
break; |
break; |
783 |
case 'T': |
case 'T': |
784 |
/* Scroll down: <ri>, <rin>. */ |
/* Scroll down: <ri>, <rin>. */ |
785 |
screen_scroll_down (display, 0, 0, |
screen_shift_right (display, 0, 0, |
786 |
user->screen.width, user->screen.height, |
user->screen.width, user->screen.height, |
787 |
parse->params[0] ?: 1, |
(parse->params[0] ?: 1) * user->screen.width, |
788 |
L' ', display->attr.current); |
L' ', display->attr.current); |
789 |
break; |
break; |
790 |
case 'X': |
case 'X': |
791 |
/* Erase character(s): <ech>. */ |
/* Erase character(s): <ech>. */ |
792 |
screen_fill (display, user->cursor.col, user->cursor.row, |
screen_fill (display, user->cursor.col, user->cursor.row, |
793 |
parse->params[0] ?: 1, 1, |
/* XXX limit ? */user->cursor.col + parse->params[0] ?: 1, |
794 |
|
user->cursor.row, |
795 |
L' ', display->attr.current); |
L' ', display->attr.current); |
796 |
break; |
break; |
797 |
} |
} |
842 |
struct cons_display *user = display->user; |
struct cons_display *user = display->user; |
843 |
parse_t parse = &display->output.parse; |
parse_t parse = &display->output.parse; |
844 |
|
|
845 |
|
uint32_t old_cursor_col = user->cursor.col; |
846 |
|
uint32_t old_cursor_row = user->cursor.row; |
847 |
|
uint32_t old_cursor_status = user->cursor.status; |
848 |
|
uint32_t old_cur_line = user->screen.cur_line; |
849 |
|
uint32_t old_scr_lines = user->screen.scr_lines; |
850 |
|
|
851 |
void newline (void) |
void newline (void) |
852 |
{ |
{ |
853 |
if (user->cursor.row < user->screen.height - 1) |
if (user->cursor.row < user->screen.height - 1) |
862 |
|
|
863 |
/* XXX Set attribute flags. */ |
/* XXX Set attribute flags. */ |
864 |
screen_fill (display, 0, user->screen.height - 1, |
screen_fill (display, 0, user->screen.height - 1, |
865 |
user->screen.width, 1, L' ', user->screen.width); |
user->screen.width - 1, user->screen.height - 1, |
866 |
|
L' ', user->screen.width); |
867 |
if (user->screen.scr_lines < |
if (user->screen.scr_lines < |
868 |
user->screen.lines - user->screen.height) |
user->screen.lines - user->screen.height) |
869 |
user->screen.scr_lines++; |
user->screen.scr_lines++; |
870 |
/* XXX Flag current line change. */ |
/* XXX Flag current line change. */ |
|
/* XXX Flag change of last line. */ |
|
871 |
/* XXX Possibly flag change of length of scroll back buffer. */ |
/* XXX Possibly flag change of length of scroll back buffer. */ |
872 |
} |
} |
873 |
} |
} |
925 |
{ |
{ |
926 |
int line = (user->screen.cur_line + user->cursor.row) |
int line = (user->screen.cur_line + user->cursor.row) |
927 |
% user->screen.lines; |
% user->screen.lines; |
928 |
|
int idx = line * user->screen.width + user->cursor.col; |
929 |
/* XXX Set attribute flags. */ |
/* XXX Set attribute flags. */ |
930 |
user->_matrix[line * user->screen.width |
user->_matrix[idx] = chr; |
931 |
+ user->cursor.col] = chr; |
|
932 |
|
display_notice_filechange (display, FILE_CHANGED_WRITE, |
933 |
|
sizeof (struct cons_display) |
934 |
|
+ idx * sizeof (wchar_t), |
935 |
|
sizeof (struct cons_display) |
936 |
|
+ (idx + 1) * sizeof (wchar_t) - 1); |
937 |
|
|
938 |
user->cursor.col++; |
user->cursor.col++; |
939 |
if (user->cursor.col == user->screen.width) |
if (user->cursor.col == user->screen.width) |
955 |
case L'c': |
case L'c': |
956 |
/* Clear screen and home cursor: <clear>. */ |
/* Clear screen and home cursor: <clear>. */ |
957 |
screen_fill (display, 0, 0, |
screen_fill (display, 0, 0, |
958 |
user->screen.width, user->screen.height, |
user->screen.width - 1, user->screen.height - 1, |
959 |
L' ', display->attr.current); |
L' ', display->attr.current); |
960 |
user->cursor.col = user->cursor.row = 0; |
user->cursor.col = user->cursor.row = 0; |
961 |
/* XXX Flag cursor change. */ |
/* XXX Flag cursor change. */ |
1002 |
default: |
default: |
1003 |
abort (); |
abort (); |
1004 |
} |
} |
1005 |
|
|
1006 |
|
if (old_cursor_col != user->cursor.col || old_cursor_row != user->cursor.row) |
1007 |
|
display_notice_filechange (display, FILE_CHANGED_WRITE, |
1008 |
|
offsetof (struct cons_display, cursor.col), |
1009 |
|
(old_cursor_status == user->cursor.status |
1010 |
|
? offsetof (struct cons_display, cursor.row) |
1011 |
|
: offsetof (struct cons_display, cursor.row)) |
1012 |
|
+ sizeof (wchar_t) - 1); |
1013 |
|
else if (old_cursor_status != user->cursor.status) |
1014 |
|
display_notice_filechange (display, FILE_CHANGED_WRITE, |
1015 |
|
offsetof (struct cons_display, cursor.status), |
1016 |
|
offsetof (struct cons_display, cursor.status) |
1017 |
|
+ sizeof (wchar_t) - 1); |
1018 |
|
if (old_cur_line != user->screen.cur_line) |
1019 |
|
display_notice_filechange (display, FILE_CHANGED_WRITE, |
1020 |
|
offsetof (struct cons_display, screen.cur_line), |
1021 |
|
(old_scr_lines == user->screen.scr_lines |
1022 |
|
? offsetof (struct cons_display, |
1023 |
|
screen.cur_line) |
1024 |
|
: offsetof (struct cons_display, |
1025 |
|
screen.scr_lines)) |
1026 |
|
+ sizeof (wchar_t) - 1); |
1027 |
|
else if (old_scr_lines != user->screen.scr_lines) |
1028 |
|
display_notice_filechange (display, FILE_CHANGED_WRITE, |
1029 |
|
offsetof (struct cons_display, |
1030 |
|
screen.scr_lines), |
1031 |
|
offsetof (struct cons_display, |
1032 |
|
screen.scr_lines) |
1033 |
|
+ sizeof (wchar_t) - 1); |
1034 |
} |
} |
1035 |
|
|
1036 |
/* Output LENGTH bytes starting from BUFFER in the system encoding. |
/* Output LENGTH bytes starting from BUFFER in the system encoding. |
1124 |
void |
void |
1125 |
display_destroy (display_t display) |
display_destroy (display_t display) |
1126 |
{ |
{ |
1127 |
|
if (display->filemod_reqs) |
1128 |
|
free_modreqs (display->filemod_reqs); |
1129 |
output_deinit (&display->output); |
output_deinit (&display->output); |
1130 |
user_destroy (display); |
user_destroy (display); |
1131 |
free (display); |
free (display); |