Fork me on GitHub

root/drivers/char/vt.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. vt_ioctl

   1 /*
   2  * fiwix/drivers/char/vt.c
   3  *
   4  * Copyright 2018-2021, Jordi Sanfeliu. All rights reserved.
   5  * Distributed under the terms of the Fiwix License.
   6  */
   7 
   8 #include <fiwix/kernel.h>
   9 #include <fiwix/console.h>
  10 #include <fiwix/keyboard.h>
  11 #include <fiwix/tty.h>
  12 #include <fiwix/vt.h>
  13 #include <fiwix/kd.h>
  14 #include <fiwix/errno.h>
  15 #include <fiwix/stdio.h>
  16 #include <fiwix/string.h>
  17 
  18 int kbdmode = 0;
  19 
  20 int vt_ioctl(struct tty *tty, int cmd, unsigned long int arg)
  21 {
  22         struct vconsole *vc;
  23         int n, errno;
  24 
  25         /* only virtual consoles support the following ioctl commands */
  26         if(MAJOR(tty->dev) != VCONSOLES_MAJOR) {
  27                 return -ENXIO;
  28         }
  29 
  30         vc = (struct vconsole *)tty->driver_data;
  31 
  32         switch(cmd) {
  33                 case KDGETLED:
  34                         if((errno = check_user_area(VERIFY_WRITE, (void *)arg, sizeof(unsigned char)))) {
  35                                 return errno;
  36                         }
  37                         memset_b((void *)arg, vc->led_status, sizeof(char));
  38                         break;
  39 
  40                 case KDSETLED:
  41                         if(arg > 7) {
  42                                 return -EINVAL;
  43                         }
  44                         vc->led_status = arg;
  45                         set_leds(vc->led_status);
  46                         break;
  47 
  48                 /* FIXME: implement KDGKBLED and KDSKBLED
  49                  * it will need to convert 'scrlock, numlock, capslock' into led_flags.
  50                  */
  51 
  52                 case KDGKBTYPE:
  53                         if((errno = check_user_area(VERIFY_WRITE, (void *)arg, sizeof(unsigned char)))) {
  54                                 return errno;
  55                         }
  56                         memset_b((void *)arg, KB_101, sizeof(char));
  57                         break;
  58 
  59                 case KDSETMODE:
  60                         if(arg != KD_TEXT && arg != KD_GRAPHICS) {
  61                                 return -EINVAL;
  62                         }
  63                         if(vc->vc_mode != arg) {
  64                                 vc->vc_mode = arg;
  65                                 if(arg == KD_GRAPHICS) {
  66                                         video.blank_screen(vc);
  67                                 } else {
  68                                         unblank_screen(vc);
  69                                 }
  70                         }
  71                         break;
  72 
  73                 case KDGETMODE:
  74                         if((errno = check_user_area(VERIFY_WRITE, (void *)arg, sizeof(unsigned char)))) {
  75                                 return errno;
  76                         }
  77                         memset_b((void *)arg, vc->vc_mode, sizeof(char));
  78                         break;
  79 
  80                 case KDGKBMODE:
  81                         if((errno = check_user_area(VERIFY_WRITE, (void *)arg, sizeof(unsigned char)))) {
  82                                 return errno;
  83                         }
  84                         memset_b((void *)arg, tty->kbd.mode, sizeof(unsigned char));
  85                         break;
  86 
  87                 case KDSKBMODE:
  88                         if(arg != K_RAW && arg != K_XLATE && arg != K_MEDIUMRAW) {
  89                                 arg = K_XLATE;
  90                         }
  91                         tty->kbd.mode = arg;
  92                         tty_queue_flush(&tty->read_q);
  93                         break;
  94 
  95                 case KDSKBENT:
  96                 {
  97                         struct kbentry *k = (struct kbentry *)arg;
  98                         if((errno = check_user_area(VERIFY_WRITE, (void *)k, sizeof(struct kbentry)))) {
  99                                 return errno;
 100                         }
 101                         if(k->kb_table < NR_MODIFIERS) {
 102                                 if(k->kb_index < NR_SCODES) {
 103                                         keymap[(k->kb_index * NR_MODIFIERS) + k->kb_table] = k->kb_value;
 104                                 } else {
 105                                         return -EINVAL;
 106                                 }
 107                         } else {
 108                                 printk("%s(): kb_table value '%d' not supported.\n", __FUNCTION__, k->kb_table);
 109                                 return -EINVAL;
 110                         }
 111                 }
 112                         break;
 113 
 114                 case VT_OPENQRY:
 115                 {
 116                         int *val = (int *)arg;
 117                         if((errno = check_user_area(VERIFY_WRITE, (void *)arg, sizeof(unsigned int)))) {
 118                                 return errno;
 119                         }
 120                         for(n = 1; n < NR_VCONSOLES + 1; n++) {
 121                                 tty = get_tty(MKDEV(VCONSOLES_MAJOR, n));
 122                                 if(!tty->count) {
 123                                         break;
 124                                 }
 125                         }
 126                         *val = (n < NR_VCONSOLES + 1 ? n : -1);
 127                 }
 128                         break;
 129 
 130                 case VT_GETMODE:
 131                 {
 132                         struct vt_mode *vt_mode = (struct vt_mode *)arg;
 133                         if((errno = check_user_area(VERIFY_WRITE, (void *)vt_mode, sizeof(struct vt_mode)))) {
 134                                 return errno;
 135                         }
 136                         memcpy_b(vt_mode, &vc->vt_mode, sizeof(struct vt_mode));
 137                 }
 138                         break;
 139 
 140                 case VT_SETMODE:
 141                 {
 142                         struct vt_mode *vt_mode = (struct vt_mode *)arg;
 143                         if((errno = check_user_area(VERIFY_READ, (void *)vt_mode, sizeof(struct vt_mode)))) {
 144                                 return errno;
 145                         }
 146                         if(vt_mode->mode != VT_AUTO && vt_mode->mode != VT_PROCESS) {
 147                                 return -EINVAL;
 148                         }
 149                         memcpy_b(&vc->vt_mode, vt_mode, sizeof(struct vt_mode));
 150                         vc->vt_mode.frsig = 0;  /* ignored */
 151                         tty->pid = current->pid;
 152                         vc->switchto_tty = 0;
 153                 }
 154                         break;
 155 
 156                 case VT_GETSTATE:
 157                 {
 158                         struct vt_stat *vt_stat = (struct vt_stat *)arg;
 159                         if((errno = check_user_area(VERIFY_WRITE, (void *)vt_stat, sizeof(struct vt_stat)))) {
 160                                 return errno;
 161                         }
 162                         vt_stat->v_active = current_cons;
 163                         vt_stat->v_state = 1;   /* /dev/tty0 is always opened */
 164                         for(n = 1; n < NR_VCONSOLES + 1; n++) {
 165                                 tty = get_tty(MKDEV(VCONSOLES_MAJOR, n));
 166                                 if(tty->count) {
 167                                         vt_stat->v_state |= (1 << n);
 168                                 }
 169                         }
 170                 }
 171                         break;
 172 
 173                 case VT_RELDISP:
 174                         if(vc->vt_mode.mode != VT_PROCESS) {
 175                                 return -EINVAL;
 176                         }
 177                         if(vc->switchto_tty < 0) {
 178                                 if(arg != VT_ACKACQ) {
 179                                         return -EINVAL;
 180                                 }
 181                         } else {
 182                                 if(arg) {
 183                                         int switchto_tty;
 184                                         switchto_tty = vc->switchto_tty;
 185                                         vc->switchto_tty = -1;
 186                                         vconsole_select_final(switchto_tty);
 187                                 } else {
 188                                         vc->switchto_tty = -1;
 189                                 }
 190                         }
 191                         break;
 192 
 193                 case VT_ACTIVATE:
 194                         if(current_cons == MINOR(tty->dev) || IS_SUPERUSER) {
 195                                 if(!arg || arg > NR_VCONSOLES) {
 196                                         return -ENXIO;
 197                                 }
 198                                 vconsole_select(--arg);
 199                         } else {
 200                                 return -EPERM;
 201                         }
 202                         break;
 203 
 204                 case VT_WAITACTIVE:
 205                         if(current_cons == MINOR(tty->dev)) {
 206                                 break;
 207                         }
 208                         if(!arg || arg > NR_VCONSOLES) {
 209                                 return -ENXIO;
 210                         }
 211                         printk("ACTIVATING another tty!! (cmd = 0x%x)\n", cmd);
 212                         break;
 213 
 214                 default:
 215                         return -EINVAL;
 216         }
 217         return 0;
 218 }

/* [previous][next][first][last][top][bottom][index][help] */