foo
[visor] / visor / src / main_unix.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <fcntl.h>
5 #include <sys/mman.h>
6 #include <sys/stat.h>
7 #include "term.h"
8 #include "visor.h"
9
10 struct file {
11         int fd;
12         void *maddr;
13         size_t msize;
14 };
15
16 static int parse_args(int argc, char **argv);
17 static int init(void);
18 static void cleanup(void);
19 static void resized(int x, int y);
20 /* file operations */
21 static vi_file *file_open(const char *path, unsigned int flags);
22 static void file_close(vi_file *file);
23 static long file_size(vi_file *file);
24 static void *file_map(vi_file *file);
25 static void file_unmap(vi_file *file);
26 static long file_read(vi_file *file, void *buf, long count);
27 static long file_write(vi_file *file, void *buf, long count);
28 static long file_seek(vi_file *file, long offs, int whence);
29 /* tty operations */
30 static void tty_clear(void *cls);
31 static void tty_clear_line(void *cls);
32 static void tty_clear_line_at(int y, void *cls);
33 static void tty_setcursor(int x, int y, void *cls);
34 static void tty_putchar(char c, void *cls);
35 static void tty_putchar_at(int x, int y, char c, void *cls);
36 static void tty_scroll(int nlines, void *cls);
37 static void tty_del_back(void *cls);
38 static void tty_del_fwd(void *cls);
39 static void tty_status(char *s, void *cls);
40 static void tty_flush(void *cls);
41
42
43 static struct visor *vi;
44
45 static int num_fpaths;
46 static char **fpaths;
47
48 static struct vi_alloc alloc = {
49         malloc, free, realloc
50 };
51
52 static struct vi_fileops fops = {
53         file_open, file_close, file_size,
54         file_map, file_unmap,
55         file_read, file_write, file_seek
56 };
57
58 static struct vi_ttyops ttyops = {
59         tty_clear, tty_clear_line, tty_clear_line_at,
60         tty_setcursor, tty_putchar, tty_putchar_at,
61         tty_scroll, tty_del_back, tty_del_fwd, tty_status, tty_flush
62 };
63
64 int main(int argc, char **argv)
65 {
66         if(parse_args(argc, argv) == -1) {
67                 return 1;
68         }
69         if(init() == -1) {
70                 return 1;
71         }
72
73         vi_redraw(vi);
74
75         for(;;) {
76                 int c = term_getchar();
77
78                 switch(c) {
79                 case 27:
80                 case 'q':
81                 case -1:
82                         goto end;
83                 }
84         }
85 end:
86
87         cleanup();
88         return 0;
89 }
90
91 static int parse_args(int argc, char **argv)
92 {
93         int i;
94
95         fpaths = argv + 1;
96         num_fpaths = 0;
97         for(i=1; i<argc; i++) {
98                 if(argv[i][0] == '-') {
99                         fprintf(stderr, "invalid option: %s\n", argv[i]);
100                         return -1;
101                 } else {
102                         argv[++num_fpaths] = argv[i];
103                 }
104         }
105         return 0;
106 }
107
108 static int init(void)
109 {
110         int i;
111
112         if(term_init(0) == -1) {
113                 return -1;
114         }
115         term_clear();
116
117         if(!(vi = vi_create(&alloc))) {
118                 return -1;
119         }
120         vi_set_fileops(vi, &fops);
121         vi_set_ttyops(vi, &ttyops);
122
123         for(i=0; i<num_fpaths; i++) {
124                 if(!vi_new_buf(vi, fpaths[i])) {
125                         return -1;
126                 }
127         }
128
129         term_resize_func(resized);
130         return 0;
131 }
132
133 static void cleanup(void)
134 {
135         if(vi) {
136                 vi_destroy(vi);
137         }
138         term_cleanup();
139 }
140
141 static void resized(int x, int y)
142 {
143         vi_term_size(vi, x, y);
144 }
145
146 static vi_file *file_open(const char *path, unsigned int flags)
147 {
148         struct file *file;
149
150         if(!(file = calloc(1, sizeof *file))) {
151                 return 0;
152         }
153         if((file->fd = open(path, flags)) == -1) {
154                 free(file);
155                 return 0;
156         }
157         return (vi_file*)file;
158 }
159
160 static void file_close(vi_file *vif)
161 {
162         struct file *file = vif;
163         if(!file) return;
164
165         if(file->fd >= 0) {
166                 if(file->maddr) {
167                         file_unmap(file);
168                 }
169                 close(file->fd);
170         }
171         free(file);
172 }
173
174 static long file_size(vi_file *vif)
175 {
176         struct file *file = vif;
177         struct stat st;
178
179         if(fstat(file->fd, &st) == -1) {
180                 return -1;
181         }
182         return st.st_size;
183 }
184
185 static void *file_map(vi_file *vif)
186 {
187         struct file *file = vif;
188         long sz;
189
190         if((sz = file_size(file)) == -1) {
191                 return 0;
192         }
193         if((file->maddr = mmap(0, sz, PROT_READ, MAP_PRIVATE, file->fd, 0)) == (void*)-1) {
194                 return 0;
195         }
196         file->msize = sz;
197         return file->maddr;
198 }
199
200 static void file_unmap(vi_file *vif)
201 {
202         struct file *file = vif;
203         if(file->maddr) {
204                 munmap(file->maddr, file->msize);
205         }
206         file->maddr = 0;
207 }
208
209 static long file_read(vi_file *vif, void *buf, long count)
210 {
211         struct file *file = vif;
212         return read(file->fd, buf, count);
213 }
214
215 static long file_write(vi_file *vif, void *buf, long count)
216 {
217         struct file *file = vif;
218         return write(file->fd, buf, count);
219 }
220
221 static long file_seek(vi_file *vif, long offs, int whence)
222 {
223         struct file *file = vif;
224         return lseek(file->fd, offs, whence);
225 }
226
227 /* tty operations */
228
229 static void tty_clear(void *cls)
230 {
231         term_clear();
232 }
233
234 static void tty_clear_line(void *cls)
235 {
236         /* TODO */
237 }
238
239 static void tty_clear_line_at(int y, void *cls)
240 {
241         term_setcursor(y, 0);
242         /* TODO */
243 }
244
245 static void tty_setcursor(int x, int y, void *cls)
246 {
247         term_setcursor(y, x);
248 }
249
250 static void tty_putchar(char c, void *cls)
251 {
252         term_putchar(c);
253 }
254
255 static void tty_putchar_at(int x, int y, char c, void *cls)
256 {
257         term_setcursor(y, x);
258         term_putchar(c);
259 }
260
261 static void tty_scroll(int nlines, void *cls)
262 {
263         /* TODO */
264 }
265
266 static void tty_del_back(void *cls)
267 {
268         /* TODO */
269 }
270
271 static void tty_del_fwd(void *cls)
272 {
273         /* TODO */
274 }
275
276 static void tty_status(char *s, void *cls)
277 {
278         /* TODO */
279 }
280
281 static void tty_flush(void *cls)
282 {
283         term_flush();
284 }