The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/pc/kbd.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * keyboard input
    3  */
    4 #include        "u.h"
    5 #include        "../port/lib.h"
    6 #include        "mem.h"
    7 #include        "dat.h"
    8 #include        "fns.h"
    9 #include        "io.h"
   10 #include        "../port/error.h"
   11 
   12 enum {
   13         Data=           0x60,           /* data port */
   14 
   15         Status=         0x64,           /* status port */
   16          Inready=       0x01,           /*  input character ready */
   17          Outbusy=       0x02,           /*  output busy */
   18          Sysflag=       0x04,           /*  system flag */
   19          Cmddata=       0x08,           /*  cmd==0, data==1 */
   20          Inhibit=       0x10,           /*  keyboard/mouse inhibited */
   21          Minready=      0x20,           /*  mouse character ready */
   22          Rtimeout=      0x40,           /*  general timeout */
   23          Parity=        0x80,
   24 
   25         Cmd=            0x64,           /* command port (write only) */
   26 
   27         Spec=           0xF800,         /* Unicode private space */
   28         PF=             Spec|0x20,      /* num pad function key */
   29         View=           Spec|0x00,      /* view (shift window up) */
   30         KF=             0xF000,         /* function key (begin Unicode private space) */
   31         Shift=          Spec|0x60,
   32         Break=          Spec|0x61,
   33         Ctrl=           Spec|0x62,
   34         Latin=          Spec|0x63,
   35         Caps=           Spec|0x64,
   36         Num=            Spec|0x65,
   37         Middle=         Spec|0x66,
   38         Altgr=          Spec|0x67,
   39         Kmouse=         Spec|0x100,
   40         No=             0x00,           /* peter */
   41 
   42         Home=           KF|13,
   43         Up=             KF|14,
   44         Pgup=           KF|15,
   45         Print=          KF|16,
   46         Left=           KF|17,
   47         Right=          KF|18,
   48         End=            KF|24,
   49         Down=           View,
   50         Pgdown=         KF|19,
   51         Ins=            KF|20,
   52         Del=            0x7F,
   53         Scroll=         KF|21,
   54 
   55         Nscan=  128,
   56 };
   57 
   58 /*
   59  * The codes at 0x79 and 0x7b are produced by the PFU Happy Hacking keyboard.
   60  * A 'standard' keyboard doesn't produce anything above 0x58.
   61  */
   62 Rune kbtab[Nscan] = 
   63 {
   64 [0x00]  No,     0x1b,   '1',    '2',    '3',    '4',    '5',    '6',
   65 [0x08]  '7',    '8',    '9',    '',    '-',    '=',    '\b',   '\t',
   66 [0x10]  'q',    'w',    'e',    'r',    't',    'y',    'u',    'i',
   67 [0x18]  'o',    'p',    '[',    ']',    '\n',   Ctrl,   'a',    's',
   68 [0x20]  'd',    'f',    'g',    'h',    'j',    'k',    'l',    ';',
   69 [0x28]  '\'',   '`',    Shift,  '\\',   'z',    'x',    'c',    'v',
   70 [0x30]  'b',    'n',    'm',    ',',    '.',    '/',    Shift,  '*',
   71 [0x38]  Latin,  ' ',    Ctrl,   KF|1,   KF|2,   KF|3,   KF|4,   KF|5,
   72 [0x40]  KF|6,   KF|7,   KF|8,   KF|9,   KF|10,  Num,    Scroll, '7',
   73 [0x48]  '8',    '9',    '-',    '4',    '5',    '6',    '+',    '1',
   74 [0x50]  '2',    '3',    '',    '.',    No,     No,     No,     KF|11,
   75 [0x58]  KF|12,  No,     No,     No,     No,     No,     No,     No,
   76 [0x60]  No,     No,     No,     No,     No,     No,     No,     No,
   77 [0x68]  No,     No,     No,     No,     No,     No,     No,     No,
   78 [0x70]  No,     No,     No,     No,     No,     No,     No,     No,
   79 [0x78]  No,     View,   No,     Up,     No,     No,     No,     No,
   80 };
   81 
   82 Rune kbtabshift[Nscan] =
   83 {
   84 [0x00]  No,     0x1b,   '!',    '@',    '#',    '$',    '%',    '^',
   85 [0x08]  '&',    '*',    '(',    ')',    '_',    '+',    '\b',   '\t',
   86 [0x10]  'Q',    'W',    'E',    'R',    'T',    'Y',    'U',    'I',
   87 [0x18]  'O',    'P',    '{',    '}',    '\n',   Ctrl,   'A',    'S',
   88 [0x20]  'D',    'F',    'G',    'H',    'J',    'K',    'L',    ':',
   89 [0x28]  '"',    '~',    Shift,  '|',    'Z',    'X',    'C',    'V',
   90 [0x30]  'B',    'N',    'M',    '<',    '>',    '?',    Shift,  '*',
   91 [0x38]  Latin,  ' ',    Ctrl,   KF|1,   KF|2,   KF|3,   KF|4,   KF|5,
   92 [0x40]  KF|6,   KF|7,   KF|8,   KF|9,   KF|10,  Num,    Scroll, '7',
   93 [0x48]  '8',    '9',    '-',    '4',    '5',    '6',    '+',    '1',
   94 [0x50]  '2',    '3',    '',    '.',    No,     No,     No,     KF|11,
   95 [0x58]  KF|12,  No,     No,     No,     No,     No,     No,     No,
   96 [0x60]  No,     No,     No,     No,     No,     No,     No,     No,
   97 [0x68]  No,     No,     No,     No,     No,     No,     No,     No,
   98 [0x70]  No,     No,     No,     No,     No,     No,     No,     No,
   99 [0x78]  No,     Up,     No,     Up,     No,     No,     No,     No,
  100 };
  101 
  102 Rune kbtabesc1[Nscan] =
  103 {
  104 [0x00]  No,     No,     No,     No,     No,     No,     No,     No,
  105 [0x08]  No,     No,     No,     No,     No,     No,     No,     No,
  106 [0x10]  No,     No,     No,     No,     No,     No,     No,     No,
  107 [0x18]  No,     No,     No,     No,     '\n',   Ctrl,   No,     No,
  108 [0x20]  No,     No,     No,     No,     No,     No,     No,     No,
  109 [0x28]  No,     No,     Shift,  No,     No,     No,     No,     No,
  110 [0x30]  No,     No,     No,     No,     No,     '/',    No,     Print,
  111 [0x38]  Altgr,  No,     No,     No,     No,     No,     No,     No,
  112 [0x40]  No,     No,     No,     No,     No,     No,     Break,  Home,
  113 [0x48]  Up,     Pgup,   No,     Left,   No,     Right,  No,     End,
  114 [0x50]  Down,   Pgdown, Ins,    Del,    No,     No,     No,     No,
  115 [0x58]  No,     No,     No,     No,     No,     No,     No,     No,
  116 [0x60]  No,     No,     No,     No,     No,     No,     No,     No,
  117 [0x68]  No,     No,     No,     No,     No,     No,     No,     No,
  118 [0x70]  No,     No,     No,     No,     No,     No,     No,     No,
  119 [0x78]  No,     Up,     No,     No,     No,     No,     No,     No,
  120 };
  121 
  122 Rune kbtabaltgr[Nscan] =
  123 {
  124 [0x00]  No,     No,     No,     No,     No,     No,     No,     No,
  125 [0x08]  No,     No,     No,     No,     No,     No,     No,     No,
  126 [0x10]  No,     No,     No,     No,     No,     No,     No,     No,
  127 [0x18]  No,     No,     No,     No,     '\n',   Ctrl,   No,     No,
  128 [0x20]  No,     No,     No,     No,     No,     No,     No,     No,
  129 [0x28]  No,     No,     Shift,  No,     No,     No,     No,     No,
  130 [0x30]  No,     No,     No,     No,     No,     '/',    No,     Print,
  131 [0x38]  Altgr,  No,     No,     No,     No,     No,     No,     No,
  132 [0x40]  No,     No,     No,     No,     No,     No,     Break,  Home,
  133 [0x48]  Up,     Pgup,   No,     Left,   No,     Right,  No,     End,
  134 [0x50]  Down,   Pgdown, Ins,    Del,    No,     No,     No,     No,
  135 [0x58]  No,     No,     No,     No,     No,     No,     No,     No,
  136 [0x60]  No,     No,     No,     No,     No,     No,     No,     No,
  137 [0x68]  No,     No,     No,     No,     No,     No,     No,     No,
  138 [0x70]  No,     No,     No,     No,     No,     No,     No,     No,
  139 [0x78]  No,     Up,     No,     No,     No,     No,     No,     No,
  140 };
  141 
  142 Rune kbtabctrl[Nscan] =
  143 {
  144 [0x00]  No,     '',    '',    '',    '',    '',    '',    '', 
  145 [0x08]  '',    '',    '',    '',    '
',    '',    '\b',   '\t',
  146 [0x10]  '',    '',    '',    '',    '',    '',    '',    '\t',
  147 [0x18]  '',    '',    '',    '',    '\n',   Ctrl,   '',    '', 
  148 [0x20]  '',    '',    '',    '\b',   '\n',   '',    '',    '', 
  149 [0x28]  '',    No,     Shift,  '',    '',    '',    '',    '', 
  150 [0x30]  '',    '',    '
',    '',    '',    '',    Shift,  '\n',
  151 [0x38]  Latin,  No,     Ctrl,   '',    '',    '',    '',    '', 
  152 [0x40]  '',    '',    '',    '
',    '',    '',    '',    '', 
  153 [0x48]  '',    '',    '
',    '',    '',    '',    '',    '', 
  154 [0x50]  '',    '',    '',    '',    No,     No,     No,     '', 
  155 [0x58]  '',    No,     No,     No,     No,     No,     No,     No,
  156 [0x60]  No,     No,     No,     No,     No,     No,     No,     No,
  157 [0x68]  No,     No,     No,     No,     No,     No,     No,     No,
  158 [0x70]  No,     No,     No,     No,     No,     No,     No,     No,
  159 [0x78]  No,     '',    No,     '\b',   No,     No,     No,     No,
  160 };
  161 
  162 enum
  163 {
  164         /* controller command byte */
  165         Cscs1=          (1<<6),         /* scan code set 1 */
  166         Cauxdis=        (1<<5),         /* mouse disable */
  167         Ckbddis=        (1<<4),         /* kbd disable */
  168         Csf=            (1<<2),         /* system flag */
  169         Cauxint=        (1<<1),         /* mouse interrupt enable */
  170         Ckbdint=        (1<<0),         /* kbd interrupt enable */
  171 };
  172 
  173 int mouseshifted;
  174 void (*kbdmouse)(int);
  175 
  176 static Lock i8042lock;
  177 static uchar ccc;
  178 static void (*auxputc)(int, int);
  179 static int nokbd = 1;
  180 
  181 /*
  182  *  wait for output no longer busy
  183  */
  184 static int
  185 outready(void)
  186 {
  187         int tries;
  188 
  189         for(tries = 0; (inb(Status) & Outbusy); tries++){
  190                 if(tries > 500)
  191                         return -1;
  192                 delay(2);
  193         }
  194         return 0;
  195 }
  196 
  197 /*
  198  *  wait for input
  199  */
  200 static int
  201 inready(void)
  202 {
  203         int tries;
  204 
  205         for(tries = 0; !(inb(Status) & Inready); tries++){
  206                 if(tries > 500)
  207                         return -1;
  208                 delay(2);
  209         }
  210         return 0;
  211 }
  212 
  213 /*
  214  *  ask 8042 to reset the machine
  215  */
  216 void
  217 i8042reset(void)
  218 {
  219         int i, x;
  220 
  221         if(nokbd)
  222                 return;
  223 
  224         *((ushort*)KADDR(0x472)) = 0x1234;      /* BIOS warm-boot flag */
  225 
  226         /*
  227          *  newer reset the machine command
  228          */
  229         outready();
  230         outb(Cmd, 0xFE);
  231         outready();
  232 
  233         /*
  234          *  Pulse it by hand (old somewhat reliable)
  235          */
  236         x = 0xDF;
  237         for(i = 0; i < 5; i++){
  238                 x ^= 1;
  239                 outready();
  240                 outb(Cmd, 0xD1);
  241                 outready();
  242                 outb(Data, x);  /* toggle reset */
  243                 delay(100);
  244         }
  245 }
  246 
  247 int
  248 i8042auxcmd(int cmd)
  249 {
  250         unsigned int c;
  251         int tries;
  252 
  253         c = 0;
  254         tries = 0;
  255 
  256         ilock(&i8042lock);
  257         do{
  258                 if(tries++ > 2)
  259                         break;
  260                 if(outready() < 0)
  261                         break;
  262                 outb(Cmd, 0xD4);
  263                 if(outready() < 0)
  264                         break;
  265                 outb(Data, cmd);
  266                 if(outready() < 0)
  267                         break;
  268                 if(inready() < 0)
  269                         break;
  270                 c = inb(Data);
  271         } while(c == 0xFE || c == 0);
  272         iunlock(&i8042lock);
  273 
  274         if(c != 0xFA){
  275                 print("i8042: %2.2ux returned to the %2.2ux command\n", c, cmd);
  276                 return -1;
  277         }
  278         return 0;
  279 }
  280 
  281 int
  282 i8042auxcmds(uchar *cmd, int ncmd)
  283 {
  284         int i;
  285 
  286         ilock(&i8042lock);
  287         for(i=0; i<ncmd; i++){
  288                 if(outready() < 0)
  289                         break;
  290                 outb(Cmd, 0xD4);
  291                 if(outready() < 0)
  292                         break;
  293                 outb(Data, cmd[i]);
  294         }
  295         iunlock(&i8042lock);
  296         return i;
  297 }
  298 
  299 typedef struct Kbscan Kbscan;
  300 struct Kbscan {
  301         int     esc1;
  302         int     esc2;
  303         int     alt;
  304         int     altgr;
  305         int     caps;
  306         int     ctl;
  307         int     num;
  308         int     shift;
  309         int     collecting;
  310         int     nk;
  311         Rune    kc[5];
  312         int     buttons;
  313 };
  314 
  315 Kbscan kbscans[2];      /* kernel and external scan code state */
  316 static int kdebug;
  317 /*
  318  * Scan code processing
  319  */
  320 void
  321 kbdputsc(int c, int external)
  322 {
  323         int i, keyup;
  324         Kbscan *kbscan;
  325 
  326         if(external)
  327                 kbscan = &kbscans[1];
  328         else
  329                 kbscan = &kbscans[0];
  330 
  331         if(kdebug)
  332                 print("sc %x ms %d\n", c, mouseshifted);
  333         /*
  334          *  e0's is the first of a 2 character sequence, e1 the first
  335          *  of a 3 character sequence (on the safari)
  336          */
  337         if(c == 0xe0){
  338                 kbscan->esc1 = 1;
  339                 return;
  340         } else if(c == 0xe1){
  341                 kbscan->esc2 = 2;
  342                 return;
  343         }
  344 
  345         keyup = c & 0x80;
  346         c &= 0x7f;
  347         if(c > sizeof kbtab){
  348                 c |= keyup;
  349                 if(c != 0xFF)   /* these come fairly often: CAPSLOCK U Y */
  350                         print("unknown key %ux\n", c);
  351                 return;
  352         }
  353 
  354         if(kbscan->esc1){
  355                 c = kbtabesc1[c];
  356                 kbscan->esc1 = 0;
  357         } else if(kbscan->esc2){
  358                 kbscan->esc2--;
  359                 return;
  360         } else if(kbscan->shift)
  361                 c = kbtabshift[c];
  362         else if(kbscan->altgr)
  363                 c = kbtabaltgr[c];
  364         else if(kbscan->ctl)
  365                 c = kbtabctrl[c];
  366         else
  367                 c = kbtab[c];
  368 
  369         if(kbscan->caps && c<='z' && c>='a')
  370                 c += 'A' - 'a';
  371 
  372         /*
  373          *  keyup only important for shifts
  374          */
  375         if(keyup){
  376                 switch(c){
  377                 case Latin:
  378                         kbscan->alt = 0;
  379                         break;
  380                 case Shift:
  381                         kbscan->shift = 0;
  382                         mouseshifted = 0;
  383 if(kdebug)
  384         print("shiftclr\n");
  385                         break;
  386                 case Ctrl:
  387                         kbscan->ctl = 0;
  388                         break;
  389                 case Altgr:
  390                         kbscan->altgr = 0;
  391                         break;
  392                 case Kmouse|1:
  393                 case Kmouse|2:
  394                 case Kmouse|3:
  395                 case Kmouse|4:
  396                 case Kmouse|5:
  397                         kbscan->buttons &= ~(1<<(c-Kmouse-1));
  398                         if(kbdmouse)
  399                                 kbdmouse(kbscan->buttons);
  400                         break;
  401                 }
  402                 return;
  403         }
  404 
  405         /*
  406          *  normal character
  407          */
  408         if(!(c & (Spec|KF))){
  409                 if(kbscan->ctl)
  410                         if(kbscan->alt && c == Del)
  411                                 exit(0);
  412                 if(!kbscan->collecting){
  413                         kbdputc(kbdq, c);
  414                         return;
  415                 }
  416                 kbscan->kc[kbscan->nk++] = c;
  417                 c = latin1(kbscan->kc, kbscan->nk);
  418                 if(c < -1)      /* need more keystrokes */
  419                         return;
  420                 if(c != -1)     /* valid sequence */
  421                         kbdputc(kbdq, c);
  422                 else    /* dump characters */
  423                         for(i=0; i<kbscan->nk; i++)
  424                                 kbdputc(kbdq, kbscan->kc[i]);
  425                 kbscan->nk = 0;
  426                 kbscan->collecting = 0;
  427                 return;
  428         } else {
  429                 switch(c){
  430                 case Caps:
  431                         kbscan->caps ^= 1;
  432                         return;
  433                 case Num:
  434                         kbscan->num ^= 1;
  435                         return;
  436                 case Shift:
  437                         kbscan->shift = 1;
  438 if(kdebug)
  439         print("shift\n");
  440                         mouseshifted = 1;
  441                         return;
  442                 case Latin:
  443                         kbscan->alt = 1;
  444                         /*
  445                          * VMware and Qemu use Ctl-Alt as the key combination
  446                          * to make the VM give up keyboard and mouse focus.
  447                          * This has the unfortunate side effect that when you
  448                          * come back into focus, Plan 9 thinks you want to type
  449                          * a compose sequence (you just typed alt). 
  450                          *
  451                          * As a clumsy hack around this, we look for ctl-alt
  452                          * and don't treat it as the start of a compose sequence.
  453                          */
  454                         if(!kbscan->ctl){
  455                                 kbscan->collecting = 1;
  456                                 kbscan->nk = 0;
  457                         }
  458                         return;
  459                 case Ctrl:
  460                         kbscan->ctl = 1;
  461                         return;
  462                 case Altgr:
  463                         kbscan->altgr = 1;
  464                         return;
  465                 case Kmouse|1:
  466                 case Kmouse|2:
  467                 case Kmouse|3:
  468                 case Kmouse|4:
  469                 case Kmouse|5:
  470                         kbscan->buttons |= 1<<(c-Kmouse-1);
  471                         if(kbdmouse)
  472                                 kbdmouse(kbscan->buttons);
  473                         return;
  474                 case KF|11:
  475                         kdebug = 1;
  476                         break;
  477                 case KF|12:
  478                         kdebug = 0;
  479                         break;
  480                 }
  481         }
  482         kbdputc(kbdq, c);
  483 }
  484 
  485 /*
  486  *  keyboard interrupt
  487  */
  488 static void
  489 i8042intr(Ureg*, void*)
  490 {
  491         int s, c;
  492 
  493         /*
  494          *  get status
  495          */
  496         ilock(&i8042lock);
  497         s = inb(Status);
  498         if(!(s&Inready)){
  499                 iunlock(&i8042lock);
  500                 return;
  501         }
  502 
  503         /*
  504          *  get the character
  505          */
  506         c = inb(Data);
  507         iunlock(&i8042lock);
  508 
  509         /*
  510          *  if it's the aux port...
  511          */
  512         if(s & Minready){
  513                 if(auxputc != nil)
  514                         auxputc(c, kbscans[0].shift);   /* internal source */
  515                 return;
  516         }
  517 
  518         kbdputsc(c, 0);                 /* internal source */
  519 }
  520 
  521 void
  522 i8042auxenable(void (*putc)(int, int))
  523 {
  524         char *err = "i8042: aux init failed\n";
  525 
  526         /* enable kbd/aux xfers and interrupts */
  527         ccc &= ~Cauxdis;
  528         ccc |= Cauxint;
  529 
  530         ilock(&i8042lock);
  531         if(outready() < 0)
  532                 print(err);
  533         outb(Cmd, 0x60);                        /* write control register */
  534         if(outready() < 0)
  535                 print(err);
  536         outb(Data, ccc);
  537         if(outready() < 0)
  538                 print(err);
  539         outb(Cmd, 0xA8);                        /* auxiliary device enable */
  540         if(outready() < 0){
  541                 iunlock(&i8042lock);
  542                 return;
  543         }
  544         auxputc = putc;
  545         intrenable(IrqAUX, i8042intr, 0, BUSUNKNOWN, "kbdaux");
  546         iunlock(&i8042lock);
  547 }
  548 
  549 static char *initfailed = "i8042: kbdinit failed\n";
  550 
  551 static int
  552 outbyte(int port, int c)
  553 {
  554         outb(port, c);
  555         if(outready() < 0) {
  556                 print(initfailed);
  557                 return -1;
  558         }
  559         return 0;
  560 }
  561 
  562 void
  563 kbdinit(void)
  564 {
  565         int c, try;
  566 
  567         /* wait for a quiescent controller */
  568         try = 1000;
  569         while(try-- > 0 && (c = inb(Status)) & (Outbusy | Inready)) {
  570                 if(c & Inready)
  571                         inb(Data);
  572                 delay(1);
  573         }
  574         if (try <= 0) {
  575                 print(initfailed);
  576                 return;
  577         }
  578 
  579         /* get current controller command byte */
  580         outb(Cmd, 0x20);
  581         if(inready() < 0){
  582                 print("i8042: kbdinit can't read ccc\n");
  583                 ccc = 0;
  584         } else
  585                 ccc = inb(Data);
  586 
  587         /* enable kbd xfers and interrupts */
  588         ccc &= ~Ckbddis;
  589         ccc |= Csf | Ckbdint | Cscs1;
  590         if(outready() < 0) {
  591                 print(initfailed);
  592                 return;
  593         }
  594 
  595         nokbd = 0;
  596 
  597         /* disable mouse */
  598         if (outbyte(Cmd, 0x60) < 0 || outbyte(Data, ccc) < 0)
  599                 print("i8042: kbdinit mouse disable failed\n");
  600 }
  601 
  602 void
  603 kbdenable(void)
  604 {
  605         kbdq = qopen(4*1024, 0, 0, 0);
  606         if(kbdq == nil)
  607                 panic("kbdinit");
  608         qnoblock(kbdq, 1);
  609 
  610         ioalloc(Data, 1, 0, "kbd");
  611         ioalloc(Cmd, 1, 0, "kbd");
  612 
  613         intrenable(IrqKBD, i8042intr, 0, BUSUNKNOWN, "kbd");
  614 }
  615 
  616 void
  617 kbdputmap(ushort m, ushort scanc, Rune r)
  618 {
  619         if(scanc >= Nscan)
  620                 error(Ebadarg);
  621         switch(m) {
  622         default:
  623                 error(Ebadarg);
  624         case 0:
  625                 kbtab[scanc] = r;
  626                 break;
  627         case 1:
  628                 kbtabshift[scanc] = r;
  629                 break;
  630         case 2:
  631                 kbtabesc1[scanc] = r;
  632                 break;
  633         case 3:
  634                 kbtabaltgr[scanc] = r;
  635                 break;
  636         case 4: 
  637                 kbtabctrl[scanc] = r;
  638                 break;
  639         }
  640 }
  641 
  642 int
  643 kbdgetmap(uint offset, int *t, int *sc, Rune *r)
  644 {
  645         if ((int)offset < 0)
  646                 error(Ebadarg);
  647         *t = offset/Nscan;
  648         *sc = offset%Nscan;
  649         switch(*t) {
  650         default:
  651                 return 0;
  652         case 0:
  653                 *r = kbtab[*sc];
  654                 return 1;
  655         case 1:
  656                 *r = kbtabshift[*sc];
  657                 return 1;
  658         case 2:
  659                 *r = kbtabesc1[*sc];
  660                 return 1;
  661         case 3:
  662                 *r = kbtabaltgr[*sc];
  663                 return 1;
  664         case 4:
  665                 *r = kbtabctrl[*sc];
  666                 return 1;
  667         }
  668 }

Cache object: feae64083b7660231cb085f4b1a6cc9d


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.