647b7da5d818a6d3ae5992ce4edca6ba63d8e85b
[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                         goto end;
82                 }
83         }
84 end:
85
86         cleanup();
87         return 0;
88 }
89
90 static int parse_args(int argc, char **argv)
91 {
92         int i;
93
94         fpaths = argv + 1;
95         num_fpaths = 0;
96         for(i=1; i<argc; i++) {
97                 if(argv[i][0] == '-') {
98                         fprintf(stderr, "invalid option: %s\n", argv[i]);
99                         return -1;
100                 } else {
101                         argv[++num_fpaths] = argv[i];
102                 }
103         }
104         return 0;
105 }
106
107 static int init(void)
108 {
109         int i;
110
111         if(term_init(0) == -1) {
112                 return -1;
113         }
114         term_clear();
115
116         if(!(vi = vi_create(&alloc))) {
117                 return -1;
118         }
119         vi_set_fileops(vi, &fops);
120         vi_set_ttyops(vi, &ttyops);
121
122         for(i=0; i<num_fpaths; i++) {
123                 if(!vi_new_buf(vi, fpaths[i])) {
124                         return -1;
125                 }
126         }
127
128         term_resize_func(resized);
129         return 0;
130 }
131
132 static void cleanup(void)
133 {
134         if(vi) {
135                 vi_destroy(vi);
136         }
137         term_cleanup();
138 }
139
140 static void resized(int x, int y)
141 {
142         vi_term_size(vi, x, y);
143 }
144
145 static vi_file *file_open(const char *path, unsigned int flags)
146 {
147         struct file *file;
148
149         if(!(file = calloc(1, sizeof *file))) {
150                 return 0;
151         }
152         if((file->fd = open(path, flags)) == -1) {
153                 free(file);
154                 return 0;
155         }
156         return (vi_file*)file;
157 }
158
159 static void file_close(vi_file *vif)
160 {
161         struct file *file = vif;
162         if(!file) return;
163
164         if(file->fd >= 0) {
165                 if(file->maddr) {
166                         file_unmap(file);
167                 }
168                 close(file->fd);
169         }
170         free(file);
171 }
172
173 static long file_size(vi_file *vif)
174 {
175         struct file *file = vif;
176         struct stat st;
177
178         if(fstat(file->fd, &st) == -1) {
179                 return -1;
180         }
181         return st.st_size;
182 }
183
184 static void *file_map(vi_file *vif)
185 {
186         struct file *file = vif;
187         long sz;
188
189         if((sz = file_size(file)) == -1) {
190                 return 0;
191         }
192         if((file->maddr = mmap(0, sz, PROT_READ, MAP_PRIVATE, file->fd, 0)) == (void*)-1) {
193                 return 0;
194         }
195         file->msize = sz;
196         return file->maddr;
197 }
198
199 static void file_unmap(vi_file *vif)
200 {
201         struct file *file = vif;
202         if(file->maddr) {
203                 munmap(file->maddr, file->msize);
204         }
205         file->maddr = 0;
206 }
207
208 static long file_read(vi_file *vif, void *buf, long count)
209 {
210         struct file *file = vif;
211         return read(file->fd, buf, count);
212 }
213
214 static long file_write(vi_file *vif, void *buf, long count)
215 {
216         struct file *file = vif;
217         return write(file->fd, buf, count);
218 }
219
220 static long file_seek(vi_file *vif, long offs, int whence)
221 {
222         struct file *file = vif;
223         return lseek(file->fd, offs, whence);
224 }
225
226 /* tty operations */
227
228 static void tty_clear(void *cls)
229 {
230         term_clear();
231 }
232
233 static void tty_clear_line(void *cls)
234 {
235         /* TODO */
236 }
237
238 static void tty_clear_line_at(int y, void *cls)
239 {
240         term_setcursor(y, 0);
241         /* TODO */
242 }
243
244 static void tty_setcursor(int x, int y, void *cls)
245 {
246         term_setcursor(y, x);
247 }
248
249 static void tty_putchar(char c, void *cls)
250 {
251         term_putchar(c);
252 }
253
254 static void tty_putchar_at(int x, int y, char c, void *cls)
255 {
256         term_setcursor(y, x);
257         term_putchar(c);
258 }
259
260 static void tty_scroll(int nlines, void *cls)
261 {
262         /* TODO */
263 }
264
265 static void tty_del_back(void *cls)
266 {
267         /* TODO */
268 }
269
270 static void tty_del_fwd(void *cls)
271 {
272         /* TODO */
273 }
274
275 static void tty_status(char *s, void *cls)
276 {
277         /* TODO */
278 }
279
280 static void tty_flush(void *cls)
281 {
282         term_flush();
283 }