/[nova]/nova/kern/dv-cons.c
ViewVC logotype

Diff of /nova/kern/dv-cons.c

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

revision 1.1.1.1 by jrydberg, Tue Feb 12 19:28:44 2002 UTC revision 1.2 by jrydberg, Wed Mar 27 23:21:54 2002 UTC
# Line 16  along with this program; if not, write t Line 16  along with this program; if not, write t
16  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
17    
18  #include <errno.h>  #include <errno.h>
19    #include <pthread.h>
20    #include <unistd.h>
21    
22  #include "nova-intern.h"  #include "nova-intern.h"
23  #include "module.h"  #include "module.h"
24  #include "dv-cons.h"  #include "dv-cons.h"
25  #include "io.h"  #include "io-bus.h"
26    #include "io-uio.h"
27    
28    #include "term.h"
29    
30  #define NVTS    16  #define NVTS    16
31    
32    struct consterm
33    {
34      /* TTY for this virtual terminal.  */
35      struct term *term;
36      
37      /* Video buffer for this virtual terminal, if it's off-screen.
38         If this VT is the current VT, we do not use this.  */
39      void *video_buffer;
40      
41      /* X and Y position on the screen.  Width and height of screen.  */
42      int xpos, ypos, xmax, ymax;
43      bool active_p: 1;
44    };
45    
46    /* ??? this must be fixed */
47    static char key_map [NUMKEYS][NUMSTATES][NUMOUTPUT] =
48    {
49      /* Special keys  */
50      [K_homeSC] = { { K_HOME }, { K_HOME }, { K_HOME }, { K_HOME }, { K_HOME } },
51      [K_delSC]  = { { 0x7f   }, { 0x7f   }, { 0x7f   }, { 0x7f   }, { 0x7f   } },
52      [K_bsSC]   = { { '\b'   }, { '\b'   }, { '\b'   }, { '\b'   }, { '\b'   } },
53      [K_retSC]  = { { '\r'   }, { '\r'   }, { '\r'   }, { '\r'   }, { '\r'   } },
54      [K_tabSC]  = { { '\t'   }, { '\t'   }, { '\t'   }, { '\t'   }, { '\t'   } },
55      [K_spSC]   = { { ' '    }, { ' '    }, { ' '    }, { ' '    }, { ' '    } },
56    
57    
58      /* Number keys */
59      [K_0SC] = { { '0' }, { '=' }, { 0 }, { 0 }, { 0 } },
60      [K_1SC] = { { '1' }, { '!' }, { 0 }, { 0 }, { 0 } },
61      [K_2SC] = { { '2' }, { '\"' }, { 0 }, { 0 }, { 0 } },
62      [K_3SC] = { { '3' }, { '#' }, { 0 }, { 0 }, { 0 } },
63      [K_4SC] = { { '4' }, { '$' }, { 0 }, { 0 }, { 0 } },
64      [K_5SC] = { { '5' }, { '%' }, { 0 }, { 0 }, { 0 } },
65      [K_6SC] = { { '6' }, { '&' }, { 0 }, { 0 }, { 0 } },
66      [K_7SC] = { { '7' }, { '/' }, { 0 }, { 0 }, { 0 } },
67      [K_8SC] = { { '8' }, { '(' }, { 0 }, { 0 }, { 0 } },
68      [K_9SC] = { { '9' }, { ')' }, { 0 }, { 0 }, { 0 } },
69    
70      /* Punctuation keys */
71      [K_minusSC]  = { { '-' }, { '-' }, { 0 }, { 0 }, { 0 } },
72      [K_eqlSC]    = { { '=' }, { '=' }, { 0 }, { 0 }, { 0 } },
73      [K_lbrktSC]  = { { '[' }, { '[' }, { 0 }, { 0 }, { 0 } },
74      [K_rbrktSC]  = { { ']' }, { ']' }, { 0 }, { 0 }, { 0 } },
75      [K_semiSC]   = { { ';' }, { ';' }, { 0 }, { 0 }, { 0 } },
76      [K_squoteSC] = { { '\''}, { '\''}, { 0 }, { 0 }, { 0 } },
77      [K_gravSC]   = { { '`' }, { '`' }, { 0 }, { 0 }, { 0 } },
78      [K_bslashSC] = { { '\\'}, { '\\'}, { 0 }, { 0 }, { 0 } },
79      [K_commaSC]  = { { ',' }, { ',' }, { 0 }, { 0 }, { 0 } },
80      [K_periodSC] = { { '.' }, { '.' }, { 0 }, { 0 }, { 0 } },
81      [K_dollarSC] = { { '$' }, { '$' }, { 0 }, { 0 }, { 0 } },
82    
83      /* Alphabetic keys */
84      [K_aSC] = { { 'a' }, { 'A' }, { 0 }, { 0 }, { 0 } },
85      [K_bSC] = { { 'b' }, { 'B' }, { 0 }, { 0 }, { 0 } },
86      [K_cSC] = { { 'c' }, { 'C' }, { 0 }, { 0 }, { 0 } },
87      [K_dSC] = { { 'd' }, { 'D' }, { 0 }, { 0 }, { 0 } },
88      [K_eSC] = { { 'e' }, { 'E' }, { 0 }, { 0 }, { 0 } },
89      [K_fSC] = { { 'f' }, { 'F' }, { 0 }, { 0 }, { 0 } },
90      [K_gSC] = { { 'g' }, { 'G' }, { 0 }, { 0 }, { 0 } },
91      [K_hSC] = { { 'h' }, { 'H' }, { 0 }, { 0 }, { 0 } },
92      [K_iSC] = { { 'i' }, { 'I' }, { 0 }, { 0 }, { 0 } },
93      [K_jSC] = { { 'j' }, { 'J' }, { 0 }, { 0 }, { 0 } },
94      [K_kSC] = { { 'k' }, { 'K' }, { 0 }, { 0 }, { 0 } },
95      [K_lSC] = { { 'l' }, { 'L' }, { 0 }, { 0 }, { 0 } },
96      [K_mSC] = { { 'm' }, { 'M' }, { 0 }, { 0 }, { 0 } },
97      [K_nSC] = { { 'n' }, { 'N' }, { 0 }, { 0 }, { 0 } },
98      [K_oSC] = { { 'o' }, { 'O' }, { 0 }, { 0 }, { 0 } },
99      [K_pSC] = { { 'p' }, { 'P' }, { 0 }, { 0 }, { 0 } },
100      [K_qSC] = { { 'q' }, { 'Q' }, { 0 }, { 0 }, { 0 } },
101      [K_rSC] = { { 'r' }, { 'R' }, { 0 }, { 0 }, { 0 } },
102      [K_sSC] = { { 's' }, { 'S' }, { 0 }, { 0 }, { 0 } },
103      [K_tSC] = { { 't' }, { 'T' }, { 0 }, { 0 }, { 0 } },
104      [K_uSC] = { { 'u' }, { 'U' }, { 0 }, { 0 }, { 0 } },
105      [K_vSC] = { { 'v' }, { 'V' }, { 0 }, { 0 }, { 0 } },
106      [K_wSC] = { { 'w' }, { 'W' }, { 0 }, { 0 }, { 0 } },
107      [K_xSC] = { { 'x' }, { 'X' }, { 0 }, { 0 }, { 0 } },
108      [K_ySC] = { { 'y' }, { 'Y' }, { 0 }, { 0 }, { 0 } },
109      [K_zSC] = { { 'z' }, { 'Z' }, { 0 }, { 0 }, { 0 } }
110    };
111    
112    static int kb_state = NORM_STATE;
113    
114  static const char printable[256] =  static const char printable[256] =
115  {  {
116    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
# Line 46  static const char printable[256] = Line 133  static const char printable[256] =
133    
134  static io_bus_tag cons_io_tag;  static io_bus_tag cons_io_tag;
135  static io_handle  cons_io_hdl;  static io_handle  cons_io_hdl;
136    static io_handle  cons_io_kbd;
137    
138  /* Write BYTES character to VT, from buffer BUF.  */  /* Write BYTES character to VT, from buffer BUF.  */
139  static void write_chars (struct cons_vt *vt, const char *buf, size_t bytes);  static void write_chars (struct consterm *vt, const char *buf, size_t bytes);
140    
141  /* Show cursor on screen, at (VT->xpos, VT->ypos).  Only if active.  */  /* Show cursor on screen, at (VT->xpos, VT->ypos).  Only if active.  */
142  static void show_cursor (struct cons_vt *vt);  static void show_cursor (struct consterm *vt);
143    
144  /* Array of pointers to our virtual terminal structures.  */  /* Array of pointers to our virtual terminal structures.  */
145  static struct cons_vt *vts [NVTS];  static struct consterm *terminals [NVTS];
146    
147  /* Pointer to current virtual terminal.  Also used by (dev :0).  */  /* Pointer to current virtual terminal.  Also used by (dev :0).  */
148  static struct cons_vt *cvt;  static struct consterm *current_terminal;
149    
 /* ??? */  
150  static vm_offset_t video_memory;  static vm_offset_t video_memory;
151    
152  static ssize_t  static ssize_t
153  kern_cons_write (void *cookie, const char *buffer, size_t n)  kern_cons_write (void *cookie, const char *buffer, size_t n)
154  {  {
155    write_chars (cvt, buffer, n);    write_chars (current_terminal, buffer, n);
156    return 0;    return 0;
157  }  }
158    
# Line 75  kern_cons_dealloc (void *cookie) Line 162  kern_cons_dealloc (void *cookie)
162    return 0;    return 0;
163  }  }
164    
165    /* Return virtual terminal associated with DEV.  */
166    static struct consterm *
167    vt_lookup (dev_t dev)
168    {
169      if (minor (dev) == 0)
170        return current_terminal;
171      else
172        return terminals [minor (dev)];
173    }
174    
175    /* Return the value for the 2nd index into key_map that
176       corresponds to the given state.  */
177    static inline int
178    index_by_state (int state, int ext_p)
179    {
180      int state_idx = NORM_STATE;
181    
182      if (!ext_p && state != KBS_NORMAL)
183        {
184          if ((state & (KBS_SHIFTED | KBS_ALTED)) == (KBS_SHIFTED | KBS_ALTED))
185            state_idx = SHIFT_ALT;
186          else if (state & KBS_SHIFTED)
187            state_idx = SHIFT_STATE;
188          else if (state & KBS_ALTED)
189            state_idx = ALT_STATE;
190          else if (state & KBS_CTRLED)
191            state_idx = CTRL_STATE;
192        }
193      return state_idx;
194    }
195    
196    
197    /* Lower half for tty node */
198    
199    static void
200    cons_start_output (struct term *term)
201    {
202      struct consterm *consterm = term->term_aux;
203    
204      while (qsize (term->outputq))
205        {
206          char c = dequeue (term, term->outputq);
207          write_chars (consterm, &c, 1);      
208        }
209    }
210    
211    static void
212    cons_abandon_physical_output (struct term *term)
213    {
214    }
215    
216    static void
217    cons_suspend_physical_output (struct term *term)
218    {
219    }
220    
221    static int
222    cons_pending_output_size (struct term *term)
223    {
224      /* We don't maintain any pending output buffer separate from the outputq. */
225      return 0;
226    }
227    
228    static void
229    cons_notice_input_flushed (struct term *term)
230    {
231    }
232    
233    static error_t
234    cons_assert_dtr (struct term *term)
235    {
236      return 0;
237    }
238    
239    static void
240    cons_desert_dtr (struct term *term)
241    {
242    }
243    
244    static void
245    cons_set_bits (struct term *term)
246    {
247    }
248    
249    /* These do nothing.  In BSD the associated ioctls get errors, but
250       I'd rather just ignore them. */
251    static void
252    cons_set_break (struct term *term)
253    {
254    }
255    
256    static void
257    cons_clear_break (struct term *term)
258    {
259    }
260    
261    static void
262    cons_mdmctl (struct term *term, int a, int b)
263    {
264    }
265    
266    static int
267    cons_mdmstate (struct term *term)
268    {
269      return 0;
270    }
271    
272    static struct bottomhalf cons_bottom =
273    {
274      cons_start_output,
275      cons_set_break,
276      cons_clear_break,
277      cons_abandon_physical_output,
278      cons_suspend_physical_output,
279      cons_pending_output_size,
280      cons_notice_input_flushed,
281      cons_assert_dtr,
282      cons_desert_dtr,
283      cons_set_bits,
284      cons_mdmctl,
285      cons_mdmstate,
286    };
287    
288    /* Allocate a new console terminal structure.  
289       Also allocates a terminal structure for it.  */
290    static struct consterm *
291    consterm_alloc (void)
292    {
293      struct consterm *consterm;
294    
295      consterm = malloc (sizeof (struct consterm));
296      assert (consterm);
297      
298      memset (consterm, 0, sizeof (struct consterm));
299      consterm->term = term_allocate (&cons_bottom, consterm);
300      consterm->video_buffer = malloc (80 * 25 * 2);
301      return consterm;
302    }
303    
304    
305  /* Initialize the console -- we do not do this through the module  /* Initialize the console -- we do not do this through the module
306     switch, since we need the console before that.  */     switch, since we need the console before that.  */
   
307  kern_return_t  kern_return_t
308  cons_init (void)  cons_init (void)
309  {  {
   rtmk_port_t pobject;  
310    kern_return_t err;    kern_return_t err;
311    int cursor_pos;    int cursor_pos;
312    
   /* Create physical (host) object for video memory area.  We do not  
      allocate more than needed.  */  
   err = host_memory_object_create (host_port, 0xb8000,  
                                    vm_round_page (80 * 25 * 2), &pobject);  
   if (err)  
     return err;  
   
313    /* Map the video memory into our address space.  */    /* Map the video memory into our address space.  */
314    err = vm_map (task_self (), pobject, &video_memory,    err = vm_map (task_self (), & video_memory, vm_round_page (80 * 25 * 2),
315                  vm_round_page (80 * 25 * 2), 1, VM_PROT_READ|VM_PROT_WRITE,                  1, host_port, 0xb8000, 0, VM_PROT_READ|VM_PROT_WRITE,
316                  VM_INHERIT_NONE);                  VM_PROT_READ|VM_PROT_WRITE, VM_INHERIT_NONE);
317    if (err)    if (err)
318      return err;      return err;
319    
320    /* Allocate the first virtual terminal, and install it as current.  */    /* Attach this driver to the ISA bus.  */
   
   vts [0] = (struct cons_vt *) malloc (sizeof (struct cons_vt));  
   if (! vts [0])  
     return ENOMEM;  
   memset (vts [0], 0, sizeof (struct cons_vt));  
   
   vts[0]->active_p = true;  
   vts[0]->ymax     = 25;  
   vts[0]->xmax     = 80;  
     
321    io_bus_attach (&cons_io_tag, IO_BUS_TYPE_ISA);    io_bus_attach (&cons_io_tag, IO_BUS_TYPE_ISA);
322    io_map (&cons_io_tag, &cons_io_hdl, 0x3d4, 4);    io_map (&cons_io_tag, &cons_io_hdl, 0x3d4, 4);
323      io_map (&cons_io_tag, &cons_io_kbd, 0x60,  4);
324    
325      /* Allocate the first virtual terminal, and install it as current.  */
326      terminals [0] = consterm_alloc ();
327    
328      terminals[0]->active_p = true;
329      terminals[0]->ymax     = 25;
330      terminals[0]->xmax     = 80;
331      
332      /* Get current cursor position.  */
333    io_write_1 (&cons_io_tag, &cons_io_hdl, 0, 14);    io_write_1 (&cons_io_tag, &cons_io_hdl, 0, 14);
334    cursor_pos =  io_read_1 (&cons_io_tag, &cons_io_hdl, 1) << 8;    cursor_pos =  io_read_1 (&cons_io_tag, &cons_io_hdl, 1) << 8;
335    io_write_1 (&cons_io_tag, &cons_io_hdl, 0, 15);    io_write_1 (&cons_io_tag, &cons_io_hdl, 0, 15);
336    cursor_pos |= io_read_1 (&cons_io_tag, &cons_io_hdl, 1);    cursor_pos |= io_read_1 (&cons_io_tag, &cons_io_hdl, 1);
337    
338    vts[0]->xpos = cursor_pos % vts[0]->xmax;    terminals[0]->xpos = cursor_pos % terminals[0]->xmax;
339    vts[0]->ypos = cursor_pos / vts[0]->xmax;    terminals[0]->ypos = cursor_pos / terminals[0]->xmax;
340    
341      /* Create stream for stdout, that will be used by the kernel.  */
342    stdout = fopencookie (0, "w",    stdout = fopencookie (0, "w",
343                          (_IO_cookie_io_functions_t) { write: kern_cons_write,                          (_IO_cookie_io_functions_t) { write: kern_cons_write,
344                                                        close: kern_cons_dealloc });                                                        close: kern_cons_dealloc });
345    stderr = stdout;    stderr = stdout;
346    
347    cvt = vts [0];    current_terminal = terminals [0];
348      return 0;
349    }
350    
351    /* Open device DEV.  We just pass it to the TTY.  */
352    int
353    cons_open (dev_t dev, int flags, struct proc *p)
354    {
355      struct consterm *consterm = vt_lookup (dev);
356    
357      if (consterm == 0)
358        {
359          consterm = consterm_alloc ();
360          terminals [minor (dev)] = consterm;
361        }
362    return 0;    return 0;
363  }  }
364    
365    /* Read character from DEV.  We just pass it to the TTY.  */
366  int  int
367  cons_open (dev_t dev)  cons_read (dev_t dev, struct io_uio *uio, struct proc *p)
368  {  {
369    return EPERM;    struct consterm *consterm = vt_lookup (dev);
370      int i, max, avail, amount;
371      struct term *term;
372    
373      if (! consterm)
374        return EIO;
375      term = consterm->term;
376    
377      pthread_mutex_lock (& term->global_lock);
378      while (! qsize (term->inputq))
379        {
380          if ((term->termflags & NO_CARRIER) && !(term->termstate.c_cflag & CLOCAL))
381            {
382              /* Return EOF, Posix.1 7.1.1.10. */
383              pthread_mutex_unlock (& term->global_lock);
384              return 0;
385            }
386    
387          /* ??? somehow handle O_NOBLOCK here. */
388          trace_printf ("process waiting on input %x", pthread_self ());
389          pthread_cond_wait (&term->inputq->wait, &term->global_lock);
390        }
391    
392      amount = uio->uio_resid;
393      avail = qsize (term->inputq);
394    
395      max = (amount < avail) ? amount : avail;
396      for (i = 0; i < max; i++)
397        {
398          char c = dequeue (term, term->inputq);
399    
400          /* Unless this is EOF, add it to the response. */
401          if (!(term->termstate.c_lflag & ICANON)
402              || !CCEQ (term->termstate.c_cc[VEOF], c))
403            io_uio_putc (uio, c);
404    
405          /* If this is a break character, then finish now. */
406          if ((term->termstate.c_lflag & ICANON)
407              && (c == '\n'
408                  || CCEQ (term->termstate.c_cc[VEOF], c)
409                  || CCEQ (term->termstate.c_cc[VEOL], c)
410                  || CCEQ (term->termstate.c_cc[VEOL2], c)))
411            break;
412        }
413    
414      pthread_mutex_unlock (&term->global_lock);
415      return 0;
416  }  }
417    
418    /* Write characters on DEV.  We just pass it to the TTY.  */
419  int  int
420  cons_write (dev_t dev, struct io_uio *uio, struct proc *p)  cons_write (dev_t dev, struct io_uio *uio, struct proc *p)
421  {  {
422    struct io_iovec *iov;    struct consterm *consterm = vt_lookup (dev);
423    struct cons_vt *vt;    struct term *term;
424      int i;
425    
426      if (! consterm)
427        return EIO;
428    
429    /* if (minor (dev) == 0) */    term = consterm->term;
430    vt = cvt;    pthread_mutex_lock (&term->global_lock);
431    
432      if ((term->termflags & NO_CARRIER) && !(term->termstate.c_cflag & CLOCAL))
433        {
434          pthread_mutex_unlock (&term->global_lock);
435          return EIO;
436        }
437    
438    while (uio->uio_resid)    while (uio->uio_resid)
439      {      {
440        iov = uio->uio_iov++;        struct io_iovec *iov = uio->uio_iov++;
441        uio->uio_iovcnt--;        
442          --uio->uio_iovcnt;
443          assert (uio->uio_iovcnt >= 0);
444          
445          while (!qavail (term->outputq))
446            {
447              (*term->bottom->start_output) (term);
448              if (!qavail (term->outputq))
449                pthread_cond_wait (&term->outputq->wait, &term->global_lock);
450            }
451    
452        write_chars (vt, iov->iov_base, iov->iov_len);        for (i = 0; i < iov->iov_len; i++)
453            write_character (term, ((char *) iov->iov_base) [i]);
454        uio->uio_resid -= iov->iov_len;        uio->uio_resid -= iov->iov_len;
455      }      }
456    
457      (*term->bottom->start_output) (term);
458      pthread_mutex_unlock (&term->global_lock);
459    return 0;    return 0;
460  }  }
461    
462  static void  static void
463  scroll_down (struct cons_vt *vt, int lines)  scroll_down (struct consterm *vt, int lines)
464  {  {
465    unsigned short *p;    unsigned short *p;
466    char *dst_buf;    char *dst_buf;
# Line 180  scroll_down (struct cons_vt *vt, int lin Line 483  scroll_down (struct cons_vt *vt, int lin
483    vt->ypos -= lines;    vt->ypos -= lines;
484  }  }
485    
   
486  /* Write BYTES character to VT, from buffer BUF.  */  /* Write BYTES character to VT, from buffer BUF.  */
487  static void  static void
488  write_chars (struct cons_vt *vt, const char *buf, size_t bytes)  write_chars (struct consterm *consterm, const char *buf, size_t bytes)
489  {  {
490    char *dst_buf, *dst_off;    char *dst_buf, *dst_off;
491    unsigned int video_off;    unsigned int video_off;
492    int c;    int c;
493    
494    dst_buf = vt->active_p ? (char *) video_memory    dst_buf = consterm->active_p ? (char *) video_memory
495                           : (char *) vt->video_buffer;                                 : (char *) consterm->video_buffer;
496    
497    while (bytes--)    while (bytes--)
498      {      {
# Line 199  write_chars (struct cons_vt *vt, const c Line 501  write_chars (struct cons_vt *vt, const c
501        switch (c)        switch (c)
502          {          {
503          case '\n':          case '\n':
504            if (++vt->ypos >= vt->ymax)            if (++consterm->ypos >= consterm->ymax)
505              scroll_down (vt, 1);              scroll_down (consterm, 1);
506            vt->xpos = 0;            consterm->xpos = 0;
507              break;
508    
509            case '\b':
510              if (consterm->xpos)
511                --consterm->xpos;
512            break;            break;
513    
514          case '\r':          case '\r':
515            vt->xpos = 0;            consterm->xpos = 0;
516            break;            break;
517    
518          default:          default:
519            if (! printable [c])            if (! printable [c])
520              continue;              continue;
521    
522            video_off  = (vt->xpos + (vt->xmax * vt->ypos)) * 2;            video_off  = (consterm->xpos + (consterm->xmax * consterm->ypos)) * 2;
523            dst_off    = dst_buf + video_off;            dst_off    = dst_buf + video_off;
524                        
525            *dst_off++ = (unsigned char) c;            *dst_off++ = (unsigned char) c;
526            *dst_off++ = 0x07;            *dst_off++ = 0x07;
527    
528            vt->xpos++;            consterm->xpos++;
529            break;            break;
530          }          }
531      }      }
532    
533    show_cursor (vt);    show_cursor (consterm);
534  }  }
535    
536  /* Show cursor on screen, at (VT->xpos, VT->ypos).  Only if active.  */  /* Show cursor on screen, at (CONSTERM->xpos, CONSTERM->ypos).  Only if active.  */
537  static void  static void
538  show_cursor (struct cons_vt *vt)  show_cursor (struct consterm *consterm)
539  {  {
540    if (vt->active_p)    if (consterm->active_p)
541      {      {
542        int pos = (vt->xpos + (vt->ypos * vt->xmax));        int pos = (consterm->xpos + (consterm->ypos * consterm->xmax));
543                    
544        io_write_1 (&cons_io_tag, &cons_io_hdl, 0, 14);        io_write_1 (&cons_io_tag, &cons_io_hdl, 0, 14);
545        io_write_1 (&cons_io_tag, &cons_io_hdl, 1, (pos >> 8));        io_write_1 (&cons_io_tag, &cons_io_hdl, 1, (pos >> 8));
# Line 244  show_cursor (struct cons_vt *vt) Line 551  show_cursor (struct cons_vt *vt)
551  static struct cdev_ops cons_ops =  static struct cdev_ops cons_ops =
552  {  {
553    cons_open,    cons_open,
554    0,    cons_read,
555    cons_write    cons_write
556  };  };
557    
558    static void
559    kdb_intr (struct consterm *consterm)
560    {
561      unsigned char scancode;
562      int up_p = 0, i;
563    
564      scancode = io_read_1 (&cons_io_tag, &cons_io_kbd, 0);
565    
566      up_p = (scancode & K_UP) == K_UP;
567      scancode = scancode & ~K_UP;
568    
569      /* We first check for special scancodes.  */
570      switch (scancode)
571        {
572        case K_CTLSC:
573          kb_state = up_p ? kb_state & ~KBS_CTRLED
574                          : kb_state |  KBS_CTRLED;
575          break;
576    
577        case K_LSHSC:
578        case K_RSHSC:
579          kb_state = up_p ? kb_state & ~KBS_SHIFTED
580                          : kb_state |  KBS_SHIFTED;
581          break;
582    
583        case K_ALTSC:
584          kb_state = up_p ? kb_state & ~KBS_ALTED
585                          : kb_state |  KBS_ALTED;
586          break;
587    
588        case K_CLCKSC:
589          kb_state = up_p ? kb_state & ~KBS_CPLK
590                          : kb_state |  KBS_CPLK;
591          goto update_leds;
592    
593        case K_NLCKSC:
594          kb_state = up_p ? kb_state & ~KBS_NUMLK
595                          : kb_state |  KBS_NUMLK;
596          goto update_leds;
597    
598        update_leds:
599          break;
600    
601        default:
602          if (! up_p)
603            {
604              char *seq;
605              seq = key_map [scancode] [index_by_state (kb_state & 0xf, 0)];
606    
607              for (i = 0; i < NUMOUTPUT && seq[i]; i++)
608                input_character (consterm->term, seq [i]);
609            }
610        }
611    }
612    
613    static void *
614    cons_intr (void *arg)
615    {
616      rtmk_port_t evc_port = (rtmk_port_t) arg;
617      kern_return_t kr;
618    
619      kr = host_attach_interrupt (host_port, 1, evc_port);
620      if (kr)
621        pthread_exit ((void *) kr);
622    
623      trace_printf ("interrupt thread is kicking\n");
624      
625      while (1)
626        {
627          kr = eventcnt_wait (task_self (), evc_port);
628          kdb_intr (current_terminal);
629        }
630    }
631    
632    static pthread_t intr_thread;
633    
634  static int  static int
635  cons_probe (struct md_descriptor *mdd)  cons_probe (struct md_descriptor *mdd)
636  {  {
637      kern_return_t kr;
638      rtmk_port_t evc;
639    
640      kr = eventcnt_allocate (task_self (), &evc);
641      if (kr)
642        return kr;
643    
644      pthread_create (&intr_thread, 0, cons_intr, (void *) evc);
645    
646    md_attach (mdd, (void *) &cons_ops);    md_attach (mdd, (void *) &cons_ops);
647    return 0;    return 0;
648  }  }

Legend:
Removed from v.1.1.1.1  
changed lines
  Added in v.1.2

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