/[hurd]/hurd/console/display.c
ViewVC logotype

Diff of /hurd/console/display.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.5 by marcus, Thu Jun 13 00:24:26 2002 UTC revision 1.6 by marcus, Thu Jun 13 23:13:10 2002 UTC
# Line 47  Line 47 
47  #include "display.h"  #include "display.h"
48    
49    
50    struct changes
51    {
52      struct
53      {
54        uint32_t col;
55        uint32_t row;
56        uint32_t status;
57      } cursor;
58      struct
59      {
60        uint32_t cur_line;
61        uint32_t scr_lines;
62      } screen;
63      off_t start;
64      off_t end;
65    
66    #define DISPLAY_CHANGE_CURSOR_POS 1
67    #define DISPLAY_CHANGE_CURSOR_STATUS 2
68    #define DISPLAY_CHANGE_SCREEN_CUR_LINE 4
69    #define DISPLAY_CHANGE_SCREEN_SCR_LINES 8
70    #define DISPLAY_CHANGE_MATRIX 16
71      int which;
72    };
73    
74  struct cursor  struct cursor
75  {  {
76    uint32_t saved_x;    uint32_t saved_x;
# Line 115  struct user_pager_info Line 139  struct user_pager_info
139  {  {
140    display_t display;    display_t display;
141    struct pager *p;    struct pager *p;
142      size_t memobj_npages;
143      vm_address_t memobj_pages[0];
144  };  };
145    
146  /* Pending directory and file modification requests.  */  /* Pending directory and file modification requests.  */
# Line 135  struct display Line 161  struct display
161       signal for this virtual console.  */       signal for this virtual console.  */
162    int owner_id;    int owner_id;
163    
164      struct changes changes;
165    
166    struct cursor cursor;    struct cursor cursor;
167    struct output output;    struct output output;
168    struct attr attr;    struct attr attr;
# Line 142  struct display Line 170  struct display
170    
171    struct user_pager_info *upi;      struct user_pager_info *upi;  
172    memory_object_t memobj;    memory_object_t memobj;
   size_t memobj_size;  
173    
174    /* A list of ports to send file change notifications to.  */    /* A list of ports to send file change notifications to.  */
175    struct modreq *filemod_reqs;    struct modreq *filemod_reqs;
# Line 169  display_get_filemap (display_t display, Line 196  display_get_filemap (display_t display,
196  void  void
197  pager_clear_user_data (struct user_pager_info *upi)  pager_clear_user_data (struct user_pager_info *upi)
198  {  {
199      int idx;
200    
201      for (idx = 0; idx < upi->memobj_npages; idx++)
202        if (upi->memobj_pages[idx])
203          vm_deallocate (mach_task_self (), upi->memobj_pages[idx], vm_page_size);
204    free (upi);    free (upi);
205  }  }
206    
207  error_t  error_t
208  pager_read_page (struct user_pager_info *pager, vm_offset_t page,  pager_read_page (struct user_pager_info *upi, vm_offset_t page,
209                   vm_address_t *buf, int *writelock)                   vm_address_t *buf, int *writelock)
210  {  {
211      assert (upi->memobj_pages[page / vm_page_size] == (vm_address_t) NULL);
212    
213    /* This is a read-only medium */    /* This is a read-only medium */
214    *writelock = 1;    *writelock = 1;
215      
216    *buf = (vm_address_t) mmap (0, vm_page_size, PROT_READ|PROT_WRITE,    *buf = (vm_address_t) mmap (0, vm_page_size, PROT_READ|PROT_WRITE,
217                                MAP_ANON, 0, 0);                                MAP_ANON, 0, 0);
218    return 0;    return 0;
219  }  }
220    
221  error_t  error_t
222  pager_write_page (struct user_pager_info *pager,  pager_write_page (struct user_pager_info *upi, vm_offset_t page,
                   vm_offset_t page,  
223                    vm_address_t buf)                    vm_address_t buf)
224  {  {
225    /* XXX Implement me.  Just store away the page, and release it when    assert (upi->memobj_pages[page / vm_page_size] == (vm_address_t) NULL);
226       releasing the pager.  */    upi->memobj_pages[page / vm_page_size] = buf;
227    assert (0);    return 0;
228  }  }
229    
230  error_t  error_t
# Line 209  pager_report_extent (struct user_pager_i Line 242  pager_report_extent (struct user_pager_i
242  {  {
243    display_t display = upi->display;    display_t display = upi->display;
244    *offset = 0;    *offset = 0;
245    *size = display->memobj_size;    *size = display->upi->memobj_npages * vm_page_size;
246    return 0;    return 0;
247  }  }
248    
# Line 296  display_notice_filechange (display_t dis Line 329  display_notice_filechange (display_t dis
329      }      }
330  }  }
331    
332    static void
333    display_flush_filechange (display_t display, int type)
334    {
335      struct cons_display *user = display->user;
336    
337      if (type & DISPLAY_CHANGE_CURSOR_POS
338          || type & DISPLAY_CHANGE_CURSOR_STATUS)
339        {
340          off_t start = -1;
341          off_t end = -1;
342    
343          if (type & DISPLAY_CHANGE_CURSOR_POS
344              || display->changes.cursor.col != user->cursor.col
345              || display->changes.cursor.row != user->cursor.row)
346            {
347              start = offsetof (struct cons_display, cursor.col);
348              end = start + 2 * sizeof (wchar_t) - 1;
349            }
350          if (type & DISPLAY_CHANGE_CURSOR_STATUS
351              || display->changes.cursor.status != user->cursor.status)
352            {
353              if (start == -1)
354                start = offsetof (struct cons_display, cursor.status);
355              end = start + 1 * sizeof (wchar_t) - 1;
356            }
357          if (start != -1)
358            display_notice_filechange (display, FILE_CHANGED_WRITE, start, end);
359        }
360    
361      if (type & DISPLAY_CHANGE_SCREEN_CUR_LINE
362          || type & DISPLAY_CHANGE_SCREEN_SCR_LINES)
363        {
364          off_t start = -1;
365          off_t end = -1;
366    
367          if (type & DISPLAY_CHANGE_SCREEN_CUR_LINE
368              || display->changes.screen.cur_line != user->screen.cur_line)
369            {
370              start = offsetof (struct cons_display, screen.cur_line);
371              end = start + 1 * sizeof (wchar_t) - 1;
372            }
373          if (type & DISPLAY_CHANGE_SCREEN_SCR_LINES
374              || display->changes.screen.scr_lines != user->screen.scr_lines)
375            {
376              if (start == -1)
377                start = offsetof (struct cons_display, screen.scr_lines);
378              end = start + 1 * sizeof (wchar_t) - 1;
379            }
380          if (start != -1)
381            display_notice_filechange (display, FILE_CHANGED_WRITE, start, end);
382        }
383    
384      if (type & DISPLAY_CHANGE_MATRIX)
385        {
386          display_notice_filechange (display, FILE_CHANGED_WRITE,
387                                     sizeof (struct cons_display)
388                                     + display->changes.start * sizeof (wchar_t),
389                                     sizeof (struct cons_display)
390                                     + (display->changes.end + 1)
391                                     * sizeof (wchar_t) - 1);
392          type &= ~DISPLAY_CHANGE_MATRIX;
393        }
394    }
395    
396    
397    /* Record a change in the matrix ringbuffer.  */
398    static void
399    display_record_filechange (display_t display, off_t start, off_t end)
400    {
401      if (!display->changes.which & DISPLAY_CHANGE_MATRIX)
402        {
403          display->changes.start = start;
404          display->changes.end = end;
405          display->changes.which |= DISPLAY_CHANGE_MATRIX;
406        }
407      else
408        {
409          off_t size = display->user->screen.width * display->user->screen.lines;
410          off_t rotate = display->changes.start;
411          off_t old_end = display->changes.end;
412          int disjunct = 0;
413    
414          /* First rotate the buffer to reduce the number of cases.  */
415          old_end -= rotate;
416          if (old_end < 0)
417            old_end += size;
418          start -= rotate;
419          if (start < 0)
420            start += size;
421          end -= rotate;
422          if (end < 0)
423            end += size;
424    
425          /* Now the old region starts at 0 and ends at OLD_END.  Try to
426             merge in the new region if it overlaps or touches the old
427             one.  */
428          if (start <= end)
429            {
430              if (start <= old_end + 1)
431                {
432                  start = 0;
433                  if (old_end > end)
434                    end = old_end;
435                }
436              else
437                {
438                  if (end == size - 1)
439                    end = old_end;
440                  else
441                    disjunct = 1;
442                }
443            }
444          else
445            {
446              if (start <= old_end + 1)
447                {
448                  start = 0;
449                  end = size - 1;
450                }
451              else
452                {
453                  if (old_end > end)
454                    end = old_end;
455                }
456            }
457          /* Now reverse the rotation.  */
458          start += rotate;
459          if (start > size)
460            start -= size;
461          end += rotate;
462          if (end > size)
463            end -= size;
464    
465          if (disjunct)
466            {
467              /* The regions are disjunct, so we have to flush the old
468               changes.  */
469              display_flush_filechange (display, DISPLAY_CHANGE_MATRIX);
470            }
471          display->changes.start = start;
472          display->changes.end = end;
473        }
474    }
475          
476                
477    
478  static error_t  static error_t
479  user_create (display_t display, uint32_t width, uint32_t height,  user_create (display_t display, uint32_t width, uint32_t height,
# Line 303  user_create (display_t display, uint32_t Line 481  user_create (display_t display, uint32_t
481  {  {
482    error_t err;    error_t err;
483    struct cons_display *user;    struct cons_display *user;
484    display->memobj_size = round_page (sizeof (struct cons_display) +    int npages = (round_page (sizeof (struct cons_display) +
485                                     sizeof (uint32_t) * width * lines);                             sizeof (uint32_t) * width * lines)) / vm_page_size;
486    
487    display->upi = malloc (sizeof (struct user_pager_info));    display->upi = calloc (1, sizeof (struct user_pager_info)
488                             + sizeof (vm_address_t) * npages);
489    if (!display->upi)    if (!display->upi)
490      return MACH_PORT_NULL;      return MACH_PORT_NULL;
491    display->upi->display = display;    display->upi->display = display;
492      display->upi->memobj_npages = npages;
493    /* 1 & MOCD correct? */    /* 1 & MOCD correct? */
494    display->upi->p = pager_create (display->upi, pager_bucket,    display->upi->p = pager_create (display->upi, pager_bucket,
495                                    1, MEMORY_OBJECT_COPY_DELAY);                                    1, MEMORY_OBJECT_COPY_DELAY);
# Line 325  user_create (display_t display, uint32_t Line 505  user_create (display_t display, uint32_t
505                            MACH_MSG_TYPE_MAKE_SEND);                            MACH_MSG_TYPE_MAKE_SEND);
506    
507    err = vm_map (mach_task_self (),    err = vm_map (mach_task_self (),
508                  (vm_address_t *) &user, (vm_size_t) display->memobj_size,                  (vm_address_t *) &user,
509                    (vm_size_t) display->upi->memobj_npages * vm_page_size,
510                  (vm_address_t) 0,                  (vm_address_t) 0,
511                  1 /* ! (flags & MAP_FIXED) */,                  1 /* ! (flags & MAP_FIXED) */,
512                  display->memobj, 0 /* (vm_offset_t) offset */,                  display->memobj, 0 /* (vm_offset_t) offset */,
# Line 384  screen_fill (display_t display, size_t c Line 565  screen_fill (display_t display, size_t c
565    if (end < size)    if (end < size)
566      {      {
567        wmemset (user->_matrix + start, chr, end - start + 1);        wmemset (user->_matrix + start, chr, end - start + 1);
568        display_notice_filechange (display, FILE_CHANGED_WRITE,        display_record_filechange (display, start, end);
                                  sizeof (struct cons_display)  
                                  + start * sizeof (wchar_t),  
                                  sizeof (struct cons_display)  
                                  + (end + 1) * sizeof (wchar_t) - 1);  
569      }      }
570    else    else
571      {      {
572        wmemset (user->_matrix + start, chr, size - start);        wmemset (user->_matrix + start, chr, size - start);
573        wmemset (user->_matrix, chr, end - size + 1);        wmemset (user->_matrix, chr, end - size + 1);
574        display_notice_filechange (display, FILE_CHANGED_WRITE,        display_record_filechange (display, start, end - size);
                                  sizeof (struct cons_display)  
                                  + start * sizeof (wchar_t),  
                                  sizeof (struct cons_display)  
                                  + (end - size + 1) * sizeof (wchar_t) - 1);  
575      }      }
576  }  }
577    
# Line 429  screen_shift_left (display_t display, si Line 602  screen_shift_left (display_t display, si
602        while (dst <= end)        while (dst <= end)
603          user->_matrix[dst++ % size] = chr;          user->_matrix[dst++ % size] = chr;
604    
605          display_flush_filechange (display, DISPLAY_CHANGE_MATRIX);
606        display_notice_filechange (display, FILE_CHANGED_TRUNCATE,        display_notice_filechange (display, FILE_CHANGED_TRUNCATE,
607                                   sizeof (struct cons_display)                                   sizeof (struct cons_display)
608                                   + start * sizeof (wchar_t),                                   + start * sizeof (wchar_t),
# Line 471  screen_shift_right (display_t display, s Line 645  screen_shift_right (display_t display, s
645        while (dst >= start)        while (dst >= start)
646          user->_matrix[dst-- % size] = chr;          user->_matrix[dst-- % size] = chr;
647    
648          display_flush_filechange (display, DISPLAY_CHANGE_MATRIX);
649        display_notice_filechange (display, FILE_CHANGED_EXTEND,        display_notice_filechange (display, FILE_CHANGED_EXTEND,
650                                   sizeof (struct cons_display)                                   sizeof (struct cons_display)
651                                   + start * sizeof (wchar_t),                                   + start * sizeof (wchar_t),
# Line 842  display_output_one (display_t display, w Line 1017  display_output_one (display_t display, w
1017    struct cons_display *user = display->user;    struct cons_display *user = display->user;
1018    parse_t parse = &display->output.parse;    parse_t parse = &display->output.parse;
1019    
   uint32_t old_cursor_col = user->cursor.col;  
   uint32_t old_cursor_row = user->cursor.row;  
   uint32_t old_cursor_status = user->cursor.status;  
   uint32_t old_cur_line = user->screen.cur_line;  
   uint32_t old_scr_lines = user->screen.scr_lines;  
   
1020    void newline (void)    void newline (void)
1021      {      {
1022        if (user->cursor.row < user->screen.height - 1)        if (user->cursor.row < user->screen.height - 1)
# Line 929  display_output_one (display_t display, w Line 1098  display_output_one (display_t display, w
1098              /* XXX Set attribute flags.  */              /* XXX Set attribute flags.  */
1099              user->_matrix[idx] = chr;              user->_matrix[idx] = chr;
1100    
1101              display_notice_filechange (display, FILE_CHANGED_WRITE,              display_record_filechange (display, idx, idx);
                                        sizeof (struct cons_display)  
                                        + idx * sizeof (wchar_t),  
                                        sizeof (struct cons_display)  
                                        + (idx + 1) * sizeof (wchar_t) - 1);  
   
1102              user->cursor.col++;              user->cursor.col++;
1103              if (user->cursor.col == user->screen.width)              if (user->cursor.col == user->screen.width)
1104                {                {
# Line 1002  display_output_one (display_t display, w Line 1166  display_output_one (display_t display, w
1166      default:      default:
1167        abort ();        abort ();
1168      }      }
   
   if (old_cursor_col != user->cursor.col || old_cursor_row != user->cursor.row)  
     display_notice_filechange (display, FILE_CHANGED_WRITE,  
                                offsetof (struct cons_display, cursor.col),  
                                (old_cursor_status == user->cursor.status  
                                ? offsetof (struct cons_display, cursor.row)  
                                : offsetof (struct cons_display, cursor.row))  
                                + sizeof (wchar_t) - 1);  
   else if (old_cursor_status != user->cursor.status)  
     display_notice_filechange (display, FILE_CHANGED_WRITE,  
                                offsetof (struct cons_display, cursor.status),  
                                offsetof (struct cons_display, cursor.status)  
                                + sizeof (wchar_t) - 1);  
   if (old_cur_line != user->screen.cur_line)  
     display_notice_filechange (display, FILE_CHANGED_WRITE,  
                                offsetof (struct cons_display, screen.cur_line),  
                                (old_scr_lines == user->screen.scr_lines  
                                 ? offsetof (struct cons_display,  
                                             screen.cur_line)  
                                 : offsetof (struct cons_display,  
                                             screen.scr_lines))  
                                + sizeof (wchar_t) - 1);  
   else if (old_scr_lines != user->screen.scr_lines)  
     display_notice_filechange (display, FILE_CHANGED_WRITE,  
                                offsetof (struct cons_display,  
                                          screen.scr_lines),  
                                offsetof (struct cons_display,  
                                          screen.scr_lines)  
                                + sizeof (wchar_t) - 1);  
1169  }  }
1170    
1171  /* Output LENGTH bytes starting from BUFFER in the system encoding.  /* Output LENGTH bytes starting from BUFFER in the system encoding.
# Line 1042  display_output_some (display_t display, Line 1177  display_output_some (display_t display,
1177  #define CONV_OUTBUF_SIZE 256  #define CONV_OUTBUF_SIZE 256
1178    error_t err = 0;    error_t err = 0;
1179    
1180      display->changes.cursor.col = display->user->cursor.col;
1181      display->changes.cursor.row = display->user->cursor.row;
1182      display->changes.cursor.status = display->user->cursor.status;
1183      display->changes.screen.cur_line = display->user->screen.cur_line;
1184      display->changes.screen.scr_lines = display->user->screen.scr_lines;
1185      display->changes.which = ~DISPLAY_CHANGE_MATRIX;
1186    
1187    while (!err && *length > 0)    while (!err && *length > 0)
1188      {      {
1189        size_t nconv;        size_t nconv;
# Line 1069  display_output_some (display_t display, Line 1211  display_output_some (display_t display,
1211              err = saved_err;              err = saved_err;
1212          }          }
1213      }      }
1214    
1215      display_flush_filechange (display, ~0);
1216    return err;    return err;
1217  }  }
1218    

Legend:
Removed from v.1.5  
changed lines
  Added in v.1.6

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26