remove util.[hc]
[cnoor.git] / txtwin.c
blobd0356febb3cc0a2a5ce3eb365052f19a2d0bb8b8
1 #include <ctype.h>
2 #include <errno.h>
3 #include <fcntl.h>
4 #include <locale.h>
5 #include <poll.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <sys/wait.h>
10 #include <pty.h>
12 #include <glib.h>
13 #include <pango/pango.h>
14 #include <pango/pangoft2.h>
16 #include "draw.h"
17 #include "config.h"
19 #define MAXTEXT (1 << 20)
20 #define DPI 196
21 #define PAGESTEPS 8
22 #define CTRLKEY(x) ((x) - 96)
24 static char name[128];
25 static PangoContext *context;
26 static int width = 1;
27 static int height = 1;
28 static int head;
29 static PangoFontMap *fontmap;
30 static FT_Bitmap *bitmap;
31 static char text[MAXTEXT];
32 static char *pos = text;
33 static int count;
34 static int mark[128];
36 static FT_Bitmap *create_bitmap(int width, int height)
38 FT_Bitmap *bitmap = g_slice_new(FT_Bitmap);
39 bitmap->width = width;
40 bitmap->pitch = (bitmap->width + 3) & ~3;
41 bitmap->rows = height;
42 bitmap->buffer = g_malloc(bitmap->pitch * bitmap->rows);
43 bitmap->num_grays = 256;
44 bitmap->pixel_mode = ft_pixel_mode_grays;
45 memset(bitmap->buffer, 0, bitmap->pitch * bitmap->rows);
46 return bitmap;
49 static void destroy_bitmap(FT_Bitmap *bitmap)
51 g_free(bitmap->buffer);
52 g_slice_free(FT_Bitmap, bitmap);
55 #define CR(a) (((a) >> 16) & 0x0000ff)
56 #define CG(a) (((a) >> 8) & 0x0000ff)
57 #define CB(a) ((a) & 0x0000ff)
58 #define COLORMERGE(f, b, c) ((b) + (((f) - (b)) * (c) >> 8u))
60 static void view_write(int sr)
62 int r, c;
63 fbval_t buf[1 << 14];
64 int nr = MIN(height - sr, fb_rows());
65 int nc = MIN(width, fb_cols());
66 for (r = 0; r < nr; r++) {
67 for (c = 0; c < nc; c++) {
68 int v = bitmap->buffer[(sr + r) * bitmap->pitch + c];
69 int r = COLORMERGE(CR(COLOR_FG), CR(COLOR_BG), v);
70 int g = COLORMERGE(CG(COLOR_FG), CG(COLOR_BG), v);
71 int b = COLORMERGE(CB(COLOR_FG), CB(COLOR_BG), v);
72 buf[c] = FB_VAL(r, g, b);
74 fb_set(r, 0, buf, width);
78 static PangoLayout *make_layout(PangoContext *context, char *text, double size)
80 static PangoFontDescription *font_description;
81 PangoLayout *layout = pango_layout_new(context);
82 pango_layout_set_markup(layout, text, -1);
83 pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
84 pango_layout_set_width(layout, fb_cols() << 10);
85 pango_layout_set_height(layout, -1);
86 pango_layout_set_alignment(layout, PANGO_ALIGN_RIGHT);
87 pango_layout_set_font_description(layout, font_description);
88 pango_font_description_free(font_description);
89 return layout;
92 static void do_output(PangoContext *context, char *text)
94 PangoLayout *layout;
95 PangoRectangle logical_rect;
96 pango_context_set_language(context, pango_language_get_default());
97 pango_context_set_base_dir(context, PANGO_DIRECTION_RTL);
98 layout = make_layout(context, text, -1);
99 pango_layout_get_pixel_extents(layout, NULL, &logical_rect);
100 pango_ft2_render_layout(bitmap, layout, 0, 0);
101 width = MAX(width, MAX(logical_rect.x + logical_rect.width,
102 PANGO_PIXELS(pango_layout_get_width(layout))));
103 height = MAX(logical_rect.y + logical_rect.height,
104 PANGO_PIXELS(pango_layout_get_height(layout)));
105 g_object_unref(layout);
108 static int readkey(void)
110 char b;
111 if (read(STDIN_FILENO, &b, 1) <= 0)
112 return -1;
113 return b;
116 void txtwin_append(char *s, char *font)
118 snprintf(pos, MAXTEXT - (pos - text),
119 "<span font=\"%s\">%s</span>", font, s);
120 pos = strchr(pos, '\0');
123 static int getcount(int def)
125 int result = count ? count : def;
126 count = 0;
127 return result;
130 static void printinfo(void)
132 printf("\x1b[H");
133 printf("CNOOR \t\t\t %d%% \t\t\t %s \x1b[K",
134 head * 100 / height, name);
135 fflush(stdout);
138 void txtwin_loop(void)
140 int step = fb_rows() / PAGESTEPS;
141 int c;
142 struct termios oldtermios, termios;
143 tcgetattr(STDIN_FILENO, &termios);
144 oldtermios = termios;
145 cfmakeraw(&termios);
146 tcsetattr(STDIN_FILENO, TCSAFLUSH, &termios);
147 bitmap = create_bitmap(width, height);
148 do_output(context, text);
149 destroy_bitmap(bitmap);
150 bitmap = create_bitmap(width, height);
151 do_output(context, text);
152 view_write(head);
153 while ((c = readkey()) != -1) {
154 switch (c) {
155 case 27:
156 count = 0;
157 break;
158 case 'q':
159 tcsetattr(STDIN_FILENO, 0, &oldtermios);
160 return;
161 default:
162 if (isdigit(c))
163 count = count * 10 + c - '0';
165 switch (c) {
166 case 'j':
167 head += step * getcount(1);
168 break;
169 case 'k':
170 head -= step * getcount(1);
171 break;
172 case CTRLKEY('f'):
173 case ' ':
174 head += fb_rows() * getcount(1) - step;
175 break;
176 case CTRLKEY('b'):
177 case 127:
178 head -= fb_rows() * getcount(1) - step;
179 break;
180 case CTRLKEY('l'):
181 break;
182 case 'G':
183 if (getcount(0))
184 head = 0;
185 else
186 head = height - fb_rows();
187 break;
188 case '%':
189 if (count)
190 head = height * getcount(0) / 100;
191 break;
192 case 'i':
193 printinfo();
194 continue;
195 case 'm':
196 c = readkey();
197 if (isalnum(c))
198 mark[c] = head;
199 continue;
200 case '\'':
201 c = readkey();
202 head = mark[c];
203 break;
204 default:
205 /* no need to redraw */
206 continue;
208 head = MAX(0, MIN(head, height - fb_rows()));
209 view_write(head);
213 void txtwin_gtk_init(int argc, char **argv)
215 g_type_init();
216 g_set_prgname("cpan");
217 setlocale(LC_ALL, "");
220 void txtwin_init(char *sura)
222 char *clear = "\x1b[2J\x1b[H";
223 char *hide = "\x1b[?25l";
224 fontmap = pango_ft2_font_map_new();
225 pango_ft2_font_map_set_resolution(PANGO_FT2_FONT_MAP(fontmap), DPI, DPI);
226 context = pango_font_map_create_context(PANGO_FONT_MAP(fontmap));
227 strcpy(name, sura);
228 if (fb_init())
229 exit(1);
230 if (FBM_BPP(fb_mode()) != sizeof(fbval_t)) {
231 fprintf(stderr, "cnoor: fbval_t doesn't match fb depth\n");
232 exit(1);
234 write(STDIN_FILENO, clear, strlen(clear));
235 write(STDIN_FILENO, hide, strlen(hide));
236 printinfo();
239 void txtwin_free(void)
241 char *show = "\x1b[?25h\n";
242 fb_free();
243 destroy_bitmap(bitmap);
244 g_object_unref(context);
245 g_object_unref(fontmap);
246 write(STDIN_FILENO, show, strlen(show));