root/drivers/char/vc_screen.c

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

DEFINITIONS

This source file includes following definitions.
  1. vcs_size
  2. vcs_lseek
  3. vcs_read
  4. vcs_write
  5. vcs_open
  6. vcs_init

   1 /*
   2  * linux/drivers/char/vc_screen.c
   3  *
   4  * Provide access to virtual console memory.
   5  * /dev/vcs0: the screen as it is being viewed right now (possibly scrolled)
   6  * /dev/vcsN: the screen of /dev/ttyN (1 <= N <= 63)
   7  *            [minor: N]
   8  *
   9  * /dev/vcsaN: idem, but including attributes, and prefixed with
  10  *      the 4 bytes lines,columns,x,y (as screendump used to give)
  11  *            [minor: N+128]
  12  *
  13  * This replaces screendump and part of selection, so that the system
  14  * administrator can control access using file system permissions.
  15  *
  16  * aeb@cwi.nl - efter Friedas begravelse - 950211
  17  */
  18 
  19 #include <linux/kernel.h>
  20 #include <linux/major.h>
  21 #include <linux/errno.h>
  22 #include <linux/tty.h>
  23 #include <linux/fs.h>
  24 #include <asm/segment.h>
  25 #include "vt_kern.h"
  26 #include "selection.h"
  27 
  28 #define HEADER_SIZE     4
  29 
  30 static inline int
  31 vcs_size(struct inode *inode)
     /* [previous][next][first][last][top][bottom][index][help] */
  32 {
  33         int size = video_num_lines * video_num_columns;
  34         if (MINOR(inode->i_rdev) & 128)
  35                 size = 2*size + HEADER_SIZE;
  36         return size;
  37 }
  38 
  39 static int
  40 vcs_lseek(struct inode *inode, struct file *file, off_t offset, int orig)
     /* [previous][next][first][last][top][bottom][index][help] */
  41 {
  42         int size = vcs_size(inode);
  43 
  44         switch (orig) {
  45                 case 0:
  46                         file->f_pos = offset;
  47                         break;
  48                 case 1:
  49                         file->f_pos += offset;
  50                         break;
  51                 case 2:
  52                         file->f_pos = size + offset;
  53                         break;
  54                 default:
  55                         return -EINVAL;
  56         }
  57         if (file->f_pos < 0 || file->f_pos > size)
  58                 return -EINVAL;
  59         return file->f_pos;
  60 }
  61 
  62 static int
  63 vcs_read(struct inode *inode, struct file *file, char *buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
  64 {
  65         unsigned long p = file->f_pos;
  66         unsigned int cons = MINOR(inode->i_rdev);
  67         int viewed, attr, size, read;
  68         char *buf0;
  69         unsigned short *org;
  70 
  71         attr = (cons & 128);
  72         cons = (cons & 127);
  73         if (cons == 0) {
  74                 cons = fg_console;
  75                 viewed = 1;
  76         } else {
  77                 cons--;
  78                 viewed = 0;
  79         }
  80         if (!vc_cons_allocated(cons))
  81                 return -ENXIO;
  82 
  83         size = vcs_size(inode);
  84         if (count < 0 || p > size)
  85                 return -EINVAL;
  86         if (count > size - p)
  87                 count = size - p;
  88 
  89         buf0 = buf;
  90         if (!attr) {
  91                 org = screen_pos(cons, p, viewed);
  92                 while (count-- > 0)
  93                         put_user(scr_readw(org++) & 0xff, buf++);
  94         } else {
  95                 if (p < HEADER_SIZE) {
  96                         char header[HEADER_SIZE];
  97                         header[0] = (char) video_num_lines;
  98                         header[1] = (char) video_num_columns;
  99                         getconsxy(cons, header+2);
 100                         while (p < HEADER_SIZE && count-- > 0)
 101                             put_user(header[p++], buf++);
 102                 }
 103                 p -= HEADER_SIZE;
 104                 org = screen_pos(cons, p/2, viewed);
 105                 if ((p & 1) && count-- > 0)
 106                         put_user(scr_readw(org++) >> 8, buf++);
 107                 while (count > 1) {
 108                         put_user(scr_readw(org++), (unsigned short *) buf);
 109                         buf += 2;
 110                         count -= 2;
 111                 }
 112                 if (count > 0)
 113                         put_user(scr_readw(org) & 0xff, buf++);
 114         }
 115         read = buf - buf0;
 116         file->f_pos += read;
 117         return read;
 118 }
 119 
 120 static int
 121 vcs_write(struct inode *inode, struct file *file, const char *buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 122 {
 123         unsigned long p = file->f_pos;
 124         unsigned int cons = MINOR(inode->i_rdev);
 125         int viewed, attr, size, written;
 126         const char *buf0;
 127         unsigned short *org;
 128 
 129         attr = (cons & 128);
 130         cons = (cons & 127);
 131         if (cons == 0) {
 132                 cons = fg_console;
 133                 viewed = 1;
 134         } else {
 135                 cons--;
 136                 viewed = 0;
 137         }
 138         if (!vc_cons_allocated(cons))
 139                 return -ENXIO;
 140 
 141         size = vcs_size(inode);
 142         if (count < 0 || p > size)
 143                 return -EINVAL;
 144         if (count > size - p)
 145                 count = size - p;
 146 
 147         buf0 = buf;
 148         if (!attr) {
 149                 org = screen_pos(cons, p, viewed);
 150                 while (count-- > 0) {
 151                         scr_writew((scr_readw(org) & 0xff00) |
 152                                    get_user(buf++), org);
 153                         org++;
 154                 }
 155         } else {
 156                 if (p < HEADER_SIZE) {
 157                         char header[HEADER_SIZE];
 158                         getconsxy(cons, header+2);
 159                         while (p < HEADER_SIZE && count-- > 0)
 160                                 header[p++] = get_user(buf++);
 161                         if (!viewed)
 162                                 putconsxy(cons, header+2);
 163                 }
 164                 p -= HEADER_SIZE;
 165                 org = screen_pos(cons, p/2, viewed);
 166                 if ((p & 1) && count-- > 0) {
 167                         scr_writew((get_user(buf++) << 8) |
 168                                    (scr_readw(org) & 0xff), org);
 169                         org++;
 170                 }
 171                 while (count > 1) {
 172                         scr_writew(get_user((const unsigned short *) buf), org++);
 173                         buf += 2;
 174                         count -= 2;
 175                 }
 176                 if (count > 0)
 177                         scr_writew((scr_readw(org) & 0xff00) |
 178                                    get_user(buf++), org);
 179         }
 180         written = buf - buf0;
 181         file->f_pos += written;
 182         return written;
 183 }
 184 
 185 static int
 186 vcs_open(struct inode *inode, struct file *filp)
     /* [previous][next][first][last][top][bottom][index][help] */
 187 {
 188         unsigned int cons = (MINOR(inode->i_rdev) & 127);
 189         if(cons && !vc_cons_allocated(cons-1))
 190                 return -ENXIO;
 191         return 0;
 192 }
 193 
 194 static struct file_operations vcs_fops = {
 195         vcs_lseek,      /* lseek */
 196         vcs_read,       /* read */
 197         vcs_write,      /* write */
 198         NULL,           /* readdir */
 199         NULL,           /* select */
 200         NULL,           /* ioctl */
 201         NULL,           /* mmap */
 202         vcs_open,       /* open */
 203         NULL,           /* release */
 204         NULL            /* fsync */
 205 };
 206 
 207 long vcs_init(long kmem_start)
     /* [previous][next][first][last][top][bottom][index][help] */
 208 {
 209         if (register_chrdev(VCS_MAJOR, "vcs", &vcs_fops))
 210                 printk("unable to get major %d for vcs device", VCS_MAJOR);
 211         return kmem_start;
 212 }

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