This source file includes following definitions.
- vcs_size
- vcs_lseek
- vcs_read
- vcs_write
- vcs_open
- vcs_init
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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)
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)
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)
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 clear_selection();
84 size = vcs_size(inode);
85 if (count < 0 || p > size)
86 return -EINVAL;
87 if (count > size - p)
88 count = size - p;
89
90 buf0 = buf;
91 if (!attr) {
92 org = screen_pos(cons, p, viewed);
93 while (count-- > 0)
94 put_fs_byte(scr_readw(org++) & 0xff, buf++);
95 } else {
96 if (p < HEADER_SIZE) {
97 char header[HEADER_SIZE];
98 header[0] = (char) video_num_lines;
99 header[1] = (char) video_num_columns;
100 getconsxy(cons, header+2);
101 while (p < HEADER_SIZE && count-- > 0)
102 put_fs_byte(header[p++], buf++);
103 }
104 p -= HEADER_SIZE;
105 org = screen_pos(cons, p/2, viewed);
106 if ((p & 1) && count-- > 0)
107 put_fs_byte(scr_readw(org++) >> 8, buf++);
108 while (count > 1) {
109 put_fs_word(scr_readw(org++), buf);
110 buf += 2;
111 count -= 2;
112 }
113 if (count > 0)
114 put_fs_byte(scr_readw(org) & 0xff, buf++);
115 }
116 read = buf - buf0;
117 file->f_pos += read;
118 return read;
119 }
120
121 static int
122 vcs_write(struct inode *inode, struct file *file, char *buf, int count)
123 {
124 unsigned long p = file->f_pos;
125 unsigned int cons = MINOR(inode->i_rdev);
126 int viewed, attr, size, written;
127 char *buf0;
128 unsigned short *org;
129
130 attr = (cons & 128);
131 cons = (cons & 127);
132 if (cons == 0) {
133 cons = fg_console;
134 viewed = 1;
135 } else {
136 cons--;
137 viewed = 0;
138 }
139 if (!vc_cons_allocated(cons))
140 return -ENXIO;
141
142 clear_selection();
143 size = vcs_size(inode);
144 if (count < 0 || p > size)
145 return -EINVAL;
146 if (count > size - p)
147 count = size - p;
148
149 buf0 = buf;
150 if (!attr) {
151 org = screen_pos(cons, p, viewed);
152 while (count-- > 0) {
153 scr_writew((scr_readw(org) & 0xff00) |
154 get_fs_byte(buf++), org);
155 org++;
156 }
157 } else {
158 if (p < HEADER_SIZE) {
159 char header[HEADER_SIZE];
160 getconsxy(cons, header+2);
161 while (p < HEADER_SIZE && count-- > 0)
162 header[p++] = get_fs_byte(buf++);
163 if (!viewed)
164 putconsxy(cons, header+2);
165 }
166 p -= HEADER_SIZE;
167 org = screen_pos(cons, p/2, viewed);
168 if ((p & 1) && count-- > 0) {
169 scr_writew((get_fs_byte(buf++) << 8) |
170 (scr_readw(org) & 0xff), org);
171 org++;
172 }
173 while (count > 1) {
174 scr_writew(get_fs_word(buf), org++);
175 buf += 2;
176 count -= 2;
177 }
178 if (count > 0)
179 scr_writew((scr_readw(org) & 0xff00) |
180 get_fs_byte(buf++), org);
181 }
182 written = buf - buf0;
183 file->f_pos += written;
184 return written;
185 }
186
187 static int
188 vcs_open(struct inode *inode, struct file *filp)
189 {
190 unsigned int cons = (MINOR(inode->i_rdev) & 127);
191 if(cons && !vc_cons_allocated(cons-1))
192 return -ENXIO;
193 return 0;
194 }
195
196 static struct file_operations vcs_fops = {
197 vcs_lseek,
198 vcs_read,
199 vcs_write,
200 NULL,
201 NULL,
202 NULL,
203 NULL,
204 vcs_open,
205 NULL,
206 NULL
207 };
208
209 long vcs_init(long kmem_start)
210 {
211 if (register_chrdev(VCS_MAJOR, "vcs", &vcs_fops))
212 printk("unable to get major %d for vcs device", VCS_MAJOR);
213 return kmem_start;
214 }