/[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.27 by marcus, Sun Sep 22 00:17:43 2002 UTC revision 1.28 by marcus, Sun Sep 22 01:28:01 2002 UTC
# Line 21  Line 21 
21    
22  #include <stddef.h>  #include <stddef.h>
23  #include <errno.h>  #include <errno.h>
 #include <fcntl.h>  
24  #include <unistd.h>  #include <unistd.h>
25  #include <wchar.h>  #include <wchar.h>
26  #include <iconv.h>  #include <iconv.h>
# Line 30  Line 29 
29  #include <assert.h>  #include <assert.h>
30  #include <error.h>  #include <error.h>
31    
 #include <sys/io.h>  
 #include <sys/fcntl.h>  
 #include <sys/mman.h>  
32  #include <cthreads.h>  #include <cthreads.h>
33    
34  #include <hurd.h>  #include <hurd.h>
35  #include <hurd/pager.h>  #include <hurd/ports.h>
36  #include <hurd/console.h>  #include <hurd/console.h>
37    
38  #ifndef __STDC_ISO_10646__  #ifndef __STDC_ISO_10646__
# Line 44  Line 40 
40  #endif  #endif
41    
42  #include "display.h"  #include "display.h"
43    #include "pager.h"
44    
45    
46  struct changes  struct changes
# Line 141  struct attr Line 138  struct attr
138  };  };
139  typedef struct attr *attr_t;  typedef struct attr *attr_t;
140    
 struct user_pager_info  
 {  
   size_t memobj_npages;  
   vm_address_t memobj_pages[0];  
 };  
   
141  /* Pending directory and file modification requests.  */  /* Pending directory and file modification requests.  */
142  struct modreq  struct modreq
143  {  {
# Line 193  struct display Line 184  struct display
184    
185    struct cons_display *user;    struct cons_display *user;
186    
187    struct pager *pager;      /* The pager for the USER member.  */
188    memory_object_t memobj;    struct user_pager user_pager;
189    
190    /* A list of ports to send file change notifications to.  */    /* A list of ports to send file change notifications to.  */
191    struct modreq *filemod_reqs;    struct modreq *filemod_reqs;
# Line 205  struct display Line 196  struct display
196  };  };
197    
198    
 /* We need a separate bucket for the pager ports.  */  
 struct port_bucket *pager_bucket;  
   
 mach_port_t  
 display_get_filemap (display_t display, vm_prot_t prot)  
 {  
   error_t err;  
   
   /* Add a reference for each call, the caller will deallocate it.  */  
   err = mach_port_mod_refs (mach_task_self (), display->memobj,  
                             MACH_PORT_RIGHT_SEND, +1);  
   assert_perror (err);  
   
   return display->memobj;  
 }  
   
 /* Implement the pager_clear_user_data callback from the pager library. */  
 void  
 pager_clear_user_data (struct user_pager_info *upi)  
 {  
   int idx;  
   
   for (idx = 0; idx < upi->memobj_npages; idx++)  
     if (upi->memobj_pages[idx])  
       vm_deallocate (mach_task_self (), upi->memobj_pages[idx], vm_page_size);  
   free (upi);  
 }  
   
 error_t  
 pager_read_page (struct user_pager_info *upi, vm_offset_t page,  
                  vm_address_t *buf, int *writelock)  
 {  
   /* XXX clients should get a read only object.  */  
   *writelock = 0;  
   
   if (upi->memobj_pages[page / vm_page_size] != (vm_address_t) NULL)  
     {  
       *buf = upi->memobj_pages[page / vm_page_size];  
       upi->memobj_pages[page / vm_page_size] = (vm_address_t) NULL;  
     }  
   else  
     *buf = (vm_address_t) mmap (0, vm_page_size, PROT_READ|PROT_WRITE,  
                                 MAP_ANON, 0, 0);  
   return 0;  
 }  
   
 error_t  
 pager_write_page (struct user_pager_info *upi, vm_offset_t page,  
                   vm_address_t buf)  
 {  
   assert (upi->memobj_pages[page / vm_page_size] == (vm_address_t) NULL);  
   upi->memobj_pages[page / vm_page_size] = buf;  
   return 0;  
 }  
   
 error_t  
 pager_unlock_page (struct user_pager_info *pager,  
                    vm_offset_t address)  
 {  
   assert (!"unlocking requested on unlocked page");  
   return 0;  
 }  
   
 /* Tell how big the file is. */  
 error_t  
 pager_report_extent (struct user_pager_info *upi,  
                      vm_address_t *offset,  
                      vm_size_t *size)  
 {  
   *offset = 0;  
   *size =  upi->memobj_npages * vm_page_size;  
   return 0;  
 }  
   
 void  
 pager_dropweak (struct user_pager_info *upi)  
 {  
 }  
   
 /* A top-level function for the paging thread that just services paging  
    requests.  */  
 static void  
 service_paging_requests (any_t arg)  
 {  
   struct port_bucket *pager_bucket = arg;  
   for (;;)  
     ports_manage_port_operations_multithread (pager_bucket,  
                                               pager_demuxer,  
                                               1000 * 60 * 2,  
                                               1000 * 60 * 10, 0);  
 }      
   
   
199  /* The bucket and class for notification messages.  */  /* The bucket and class for notification messages.  */
200  static struct port_bucket *notify_bucket;  static struct port_bucket *notify_bucket;
201  static struct port_class *notify_class;  static struct port_class *notify_class;
# Line 874  conchar_memset (conchar_t *conchar, wcha Line 772  conchar_memset (conchar_t *conchar, wcha
772      }      }
773  }  }
774    
775    
776  static error_t  static error_t
777  user_create (display_t display, uint32_t width, uint32_t height,  user_create (display_t display, uint32_t width, uint32_t height,
778               uint32_t lines, wchar_t chr, conchar_attr_t attr)               uint32_t lines, wchar_t chr, conchar_attr_t attr)
779  {  {
780    error_t err;    error_t err;
781    struct cons_display *user;    struct cons_display *user;
782    struct user_pager_info *upi;    int npages = (round_page (sizeof (struct cons_display) + sizeof (conchar_t)
783                                * width * lines)) / vm_page_size;
   int npages = (round_page (sizeof (struct cons_display) +  
                            sizeof (conchar_t) * width * lines)) / vm_page_size;  
   
   upi = calloc (1, sizeof (struct user_pager_info)  
                 + sizeof (vm_address_t) * npages);  
   if (!upi)  
     return MACH_PORT_NULL;  
   upi->memobj_npages = npages;  
   /* 1 & MOCD correct? */  
   display->pager = pager_create (upi, pager_bucket,  
                                  1, MEMORY_OBJECT_COPY_DELAY);  
   if (display->pager == 0)  
     {  
       free (upi);  
       return errno;  
     }  
   display->memobj = pager_get_port (display->pager);  
   ports_port_deref (display->pager);  
   
   mach_port_insert_right (mach_task_self (), display->memobj, display->memobj,  
                           MACH_MSG_TYPE_MAKE_SEND);  
   
   err = vm_map (mach_task_self (),  
                 (vm_address_t *) &user,  
                 (vm_size_t) npages * vm_page_size,  
                 (vm_address_t) 0,  
                 1 /* ! (flags & MAP_FIXED) */,  
                 display->memobj, 0 /* (vm_offset_t) offset */,  
                 0 /* ! (flags & MAP_SHARED) */,  
                 VM_PROT_READ | VM_PROT_WRITE,  
                 VM_PROT_READ | VM_PROT_WRITE,  
                 VM_INHERIT_NONE);  
784    
785      err = user_pager_create (&display->user_pager, npages, &display->user);
786    if (err)    if (err)
787      {      return err;
788        /* UPI will be cleaned up by libpager.  */  
789        mach_port_deallocate (mach_task_self (), display->memobj);    user = display->user;
       return err;  
     }  
       
790    user->magic = CONS_MAGIC;    user->magic = CONS_MAGIC;
791    user->version = CONS_VERSION_MAJ << 16 | CONS_VERSION_AGE;    user->version = CONS_VERSION_MAJ << 16 | CONS_VERSION_AGE;
792    user->changes.buffer = offsetof (struct cons_display, changes._buffer)    user->changes.buffer = offsetof (struct cons_display, changes._buffer)
# Line 938  user_create (display_t display, uint32_t Line 803  user_create (display_t display, uint32_t
803    user->cursor.status = CONS_CURSOR_NORMAL;    user->cursor.status = CONS_CURSOR_NORMAL;
804    conchar_memset (user->_matrix, chr, attr,    conchar_memset (user->_matrix, chr, attr,
805                    user->screen.width * user->screen.lines);                    user->screen.width * user->screen.lines);
   
   display->user = user;  
806    return 0;    return 0;
807  }  }
808    
809  static void  static void
810  user_destroy (display_t display)  user_destroy (display_t display)
811  {  {
812    /* The pager will be deallocated by libpager.  */    user_pager_destroy (&display->user_pager, display->user);
   vm_deallocate (mach_task_self (), (vm_offset_t) display->user,  
                  pager_get_upi (display->pager)->memobj_npages * vm_page_size);  
   mach_port_deallocate (mach_task_self (), display->memobj);  
813  }  }
814    
815    
# Line 1922  void display_destroy_complete (void *pi) Line 1782  void display_destroy_complete (void *pi)
1782  void  void
1783  display_init (void)  display_init (void)
1784  {  {
1785    /* Create the pager bucket, and start to serve paging requests.  */    user_pager_init ();
   pager_bucket = ports_create_bucket ();  
   if (! pager_bucket)  
     error (5, errno, "Cannot create pager bucket");  
   
   /* Make a thread to service paging requests.  */  
   cthread_detach (cthread_fork ((cthread_fn_t) service_paging_requests,  
                                 (any_t) pager_bucket));  
1786    
1787    /* Create the notify bucket, and start to serve notifications.  */    /* Create the notify bucket, and start to serve notifications.  */
1788    notify_bucket = ports_create_bucket ();    notify_bucket = ports_create_bucket ();
# Line 2250  display_discard_output (display_t displa Line 2103  display_discard_output (display_t displa
2103    display->output.size = 0;    display->output.size = 0;
2104    mutex_unlock (&display->lock);    mutex_unlock (&display->lock);
2105  }  }
2106    
2107    
2108    mach_port_t
2109    display_get_filemap (display_t display, vm_prot_t prot)
2110    {
2111      mach_port_t memobj;
2112      mutex_lock (&display->lock);
2113      memobj = user_pager_get_filemap (&display->user_pager, prot);
2114      mutex_unlock (&display->lock);
2115      return memobj;
2116    }

Legend:
Removed from v.1.27  
changed lines
  Added in v.1.28

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