File: | frontends/framebuffer/gui.c |
Warning: | line 1699, column 3 Value stored to 'widget' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* |
2 | * Copyright 2008, 2014 Vincent Sanders <vince@netsurf-browser.org> |
3 | * |
4 | * This file is part of NetSurf, http://www.netsurf-browser.org/ |
5 | * |
6 | * NetSurf is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by |
8 | * the Free Software Foundation; version 2 of the License. |
9 | * |
10 | * NetSurf is distributed in the hope that it will be useful, |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | * GNU General Public License for more details. |
14 | * |
15 | * You should have received a copy of the GNU General Public License |
16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | */ |
18 | |
19 | #include <stdint.h> |
20 | #include <limits.h> |
21 | #include <getopt.h> |
22 | #include <assert.h> |
23 | #include <string.h> |
24 | #include <stdbool.h> |
25 | #include <stdlib.h> |
26 | #include <nsutils/time.h> |
27 | |
28 | #include <libnsfb.h> |
29 | #include <libnsfb_plot.h> |
30 | #include <libnsfb_event.h> |
31 | |
32 | #include "utils/utils.h" |
33 | #include "utils/nsoption.h" |
34 | #include "utils/filepath.h" |
35 | #include "utils/log.h" |
36 | #include "utils/messages.h" |
37 | #include "netsurf/browser_window.h" |
38 | #include "netsurf/keypress.h" |
39 | #include "desktop/browser_history.h" |
40 | #include "netsurf/plotters.h" |
41 | #include "netsurf/window.h" |
42 | #include "netsurf/misc.h" |
43 | #include "netsurf/netsurf.h" |
44 | #include "netsurf/cookie_db.h" |
45 | #include "content/fetch.h" |
46 | |
47 | #include "framebuffer/gui.h" |
48 | #include "framebuffer/fbtk.h" |
49 | #include "framebuffer/framebuffer.h" |
50 | #include "framebuffer/schedule.h" |
51 | #include "framebuffer/findfile.h" |
52 | #include "framebuffer/image_data.h" |
53 | #include "framebuffer/font.h" |
54 | #include "framebuffer/clipboard.h" |
55 | #include "framebuffer/fetch.h" |
56 | #include "framebuffer/bitmap.h" |
57 | #include "framebuffer/local_history.h" |
58 | #include "framebuffer/corewindow.h" |
59 | |
60 | |
61 | #define NSFB_TOOLBAR_DEFAULT_LAYOUT"blfsrutc" "blfsrutc" |
62 | |
63 | fbtk_widget_t *fbtk; |
64 | |
65 | static bool_Bool fb_complete = false0; |
66 | |
67 | struct gui_window *input_window = NULL((void*)0); |
68 | struct gui_window *search_current_window; |
69 | struct gui_window *window_list = NULL((void*)0); |
70 | |
71 | /* private data for browser user widget */ |
72 | struct browser_widget_s { |
73 | struct browser_window *bw; /**< The browser window connected to this gui window */ |
74 | int scrollx, scrolly; /**< scroll offsets. */ |
75 | |
76 | /* Pending window redraw state. */ |
77 | bool_Bool redraw_required; /**< flag indicating the foreground loop |
78 | * needs to redraw the browser widget. |
79 | */ |
80 | bbox_t redraw_box; /**< Area requiring redraw. */ |
81 | bool_Bool pan_required; /**< flag indicating the foreground loop |
82 | * needs to pan the window. |
83 | */ |
84 | int panx, pany; /**< Panning required. */ |
85 | }; |
86 | |
87 | static struct gui_drag { |
88 | enum state { |
89 | GUI_DRAG_NONE, |
90 | GUI_DRAG_PRESSED, |
91 | GUI_DRAG_DRAG |
92 | } state; |
93 | int button; |
94 | int x; |
95 | int y; |
96 | bool_Bool grabbed_pointer; |
97 | } gui_drag; |
98 | |
99 | |
100 | /** |
101 | * Cause an abnormal program termination. |
102 | * |
103 | * \note This never returns and is intended to terminate without any cleanup. |
104 | * |
105 | * \param error The message to display to the user. |
106 | */ |
107 | static void die(const char *error) |
108 | { |
109 | fprintf(stderrstderr, "%s\n", error); |
110 | exit(1); |
111 | } |
112 | |
113 | |
114 | /** |
115 | * Warn the user of an event. |
116 | * |
117 | * \param[in] warning A warning looked up in the message translation table |
118 | * \param[in] detail Additional text to be displayed or NULL. |
119 | * \return NSERROR_OK on success or error code if there was a |
120 | * faliure displaying the message to the user. |
121 | */ |
122 | static nserror fb_warn_user(const char *warning, const char *detail) |
123 | { |
124 | NSLOG(netsurf, INFO, "%s %s", warning, detail)do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "frontends/framebuffer/gui.c", sizeof("frontends/framebuffer/gui.c" ) - 1, __PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__) - 1, 124 , }; nslog__log(&_nslog_ctx, "%s %s", warning, detail); } } while(0); |
125 | return NSERROR_OK; |
126 | } |
127 | |
128 | /* queue a redraw operation, co-ordinates are relative to the window */ |
129 | static void |
130 | fb_queue_redraw(struct fbtk_widget_s *widget, int x0, int y0, int x1, int y1) |
131 | { |
132 | struct browser_widget_s *bwidget = fbtk_get_userpw(widget); |
133 | |
134 | bwidget->redraw_box.x0 = min(bwidget->redraw_box.x0, x0)(((bwidget->redraw_box.x0)<(x0))?(bwidget->redraw_box .x0):(x0)); |
135 | bwidget->redraw_box.y0 = min(bwidget->redraw_box.y0, y0)(((bwidget->redraw_box.y0)<(y0))?(bwidget->redraw_box .y0):(y0)); |
136 | bwidget->redraw_box.x1 = max(bwidget->redraw_box.x1, x1)(((bwidget->redraw_box.x1)>(x1))?(bwidget->redraw_box .x1):(x1)); |
137 | bwidget->redraw_box.y1 = max(bwidget->redraw_box.y1, y1)(((bwidget->redraw_box.y1)>(y1))?(bwidget->redraw_box .y1):(y1)); |
138 | |
139 | if (fbtk_clip_to_widget(widget, &bwidget->redraw_box)) { |
140 | bwidget->redraw_required = true1; |
141 | fbtk_request_redraw(widget); |
142 | } else { |
143 | bwidget->redraw_box.y0 = bwidget->redraw_box.x0 = INT_MAX2147483647; |
144 | bwidget->redraw_box.y1 = bwidget->redraw_box.x1 = -(INT_MAX2147483647); |
145 | bwidget->redraw_required = false0; |
146 | } |
147 | } |
148 | |
149 | /* queue a window scroll */ |
150 | static void |
151 | widget_scroll_y(struct gui_window *gw, int y, bool_Bool abs) |
152 | { |
153 | struct browser_widget_s *bwidget = fbtk_get_userpw(gw->browser); |
154 | int content_width, content_height; |
155 | int height; |
156 | |
157 | NSLOG(netsurf, DEEPDEBUG, "window scroll")do { if (NSLOG_LEVEL_DEEPDEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_DEEPDEBUG, "frontends/framebuffer/gui.c", sizeof ("frontends/framebuffer/gui.c") - 1, __PRETTY_FUNCTION__, sizeof (__PRETTY_FUNCTION__) - 1, 157, }; nslog__log(&_nslog_ctx , "window scroll"); } } while(0); |
158 | if (abs) { |
159 | bwidget->pany = y - bwidget->scrolly; |
160 | } else { |
161 | bwidget->pany += y; |
162 | } |
163 | |
164 | browser_window_get_extents(gw->bw, true1, |
165 | &content_width, &content_height); |
166 | |
167 | height = fbtk_get_height(gw->browser); |
168 | |
169 | /* dont pan off the top */ |
170 | if ((bwidget->scrolly + bwidget->pany) < 0) |
171 | bwidget->pany = -bwidget->scrolly; |
172 | |
173 | /* do not pan off the bottom of the content */ |
174 | if ((bwidget->scrolly + bwidget->pany) > (content_height - height)) |
175 | bwidget->pany = (content_height - height) - bwidget->scrolly; |
176 | |
177 | if (bwidget->pany == 0) |
178 | return; |
179 | |
180 | bwidget->pan_required = true1; |
181 | |
182 | fbtk_request_redraw(gw->browser); |
183 | |
184 | fbtk_set_scroll_position(gw->vscroll, bwidget->scrolly + bwidget->pany); |
185 | } |
186 | |
187 | /* queue a window scroll */ |
188 | static void |
189 | widget_scroll_x(struct gui_window *gw, int x, bool_Bool abs) |
190 | { |
191 | struct browser_widget_s *bwidget = fbtk_get_userpw(gw->browser); |
192 | int content_width, content_height; |
193 | int width; |
194 | |
195 | if (abs) { |
196 | bwidget->panx = x - bwidget->scrollx; |
197 | } else { |
198 | bwidget->panx += x; |
199 | } |
200 | |
201 | browser_window_get_extents(gw->bw, true1, |
202 | &content_width, &content_height); |
203 | |
204 | width = fbtk_get_width(gw->browser); |
205 | |
206 | /* dont pan off the left */ |
207 | if ((bwidget->scrollx + bwidget->panx) < 0) |
208 | bwidget->panx = - bwidget->scrollx; |
209 | |
210 | /* do not pan off the right of the content */ |
211 | if ((bwidget->scrollx + bwidget->panx) > (content_width - width)) |
212 | bwidget->panx = (content_width - width) - bwidget->scrollx; |
213 | |
214 | if (bwidget->panx == 0) |
215 | return; |
216 | |
217 | bwidget->pan_required = true1; |
218 | |
219 | fbtk_request_redraw(gw->browser); |
220 | |
221 | fbtk_set_scroll_position(gw->hscroll, bwidget->scrollx + bwidget->panx); |
222 | } |
223 | |
224 | static void |
225 | fb_pan(fbtk_widget_t *widget, |
226 | struct browser_widget_s *bwidget, |
227 | struct browser_window *bw) |
228 | { |
229 | int x; |
230 | int y; |
231 | int width; |
232 | int height; |
233 | nsfb_bbox_t srcbox; |
234 | nsfb_bbox_t dstbox; |
235 | |
236 | nsfb_t *nsfb = fbtk_get_nsfb(widget); |
237 | |
238 | height = fbtk_get_height(widget); |
239 | width = fbtk_get_width(widget); |
240 | |
241 | NSLOG(netsurf, DEEPDEBUG, "panning %d, %d",do { if (NSLOG_LEVEL_DEEPDEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_DEEPDEBUG, "frontends/framebuffer/gui.c", sizeof ("frontends/framebuffer/gui.c") - 1, __PRETTY_FUNCTION__, sizeof (__PRETTY_FUNCTION__) - 1, 242, }; nslog__log(&_nslog_ctx , "panning %d, %d", bwidget->panx, bwidget->pany); } } while (0) |
242 | bwidget->panx, bwidget->pany)do { if (NSLOG_LEVEL_DEEPDEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_DEEPDEBUG, "frontends/framebuffer/gui.c", sizeof ("frontends/framebuffer/gui.c") - 1, __PRETTY_FUNCTION__, sizeof (__PRETTY_FUNCTION__) - 1, 242, }; nslog__log(&_nslog_ctx , "panning %d, %d", bwidget->panx, bwidget->pany); } } while (0); |
243 | |
244 | x = fbtk_get_absx(widget); |
245 | y = fbtk_get_absy(widget); |
246 | |
247 | /* if the pan exceeds the viewport size just redraw the whole area */ |
248 | if (bwidget->pany >= height || bwidget->pany <= -height || |
249 | bwidget->panx >= width || bwidget->panx <= -width) { |
250 | |
251 | bwidget->scrolly += bwidget->pany; |
252 | bwidget->scrollx += bwidget->panx; |
253 | fb_queue_redraw(widget, 0, 0, width, height); |
254 | |
255 | /* ensure we don't try to scroll again */ |
256 | bwidget->panx = 0; |
257 | bwidget->pany = 0; |
258 | bwidget->pan_required = false0; |
259 | return; |
260 | } |
261 | |
262 | if (bwidget->pany < 0) { |
263 | /* pan up by less then viewport height */ |
264 | srcbox.x0 = x; |
265 | srcbox.y0 = y; |
266 | srcbox.x1 = srcbox.x0 + width; |
267 | srcbox.y1 = srcbox.y0 + height + bwidget->pany; |
268 | |
269 | dstbox.x0 = x; |
270 | dstbox.y0 = y - bwidget->pany; |
271 | dstbox.x1 = dstbox.x0 + width; |
272 | dstbox.y1 = dstbox.y0 + height + bwidget->pany; |
273 | |
274 | /* move part that remains visible up */ |
275 | nsfb_plot_copy(nsfb, &srcbox, nsfb, &dstbox); |
276 | |
277 | /* redraw newly exposed area */ |
278 | bwidget->scrolly += bwidget->pany; |
279 | fb_queue_redraw(widget, 0, 0, width, - bwidget->pany); |
280 | |
281 | } else if (bwidget->pany > 0) { |
282 | /* pan down by less then viewport height */ |
283 | srcbox.x0 = x; |
284 | srcbox.y0 = y + bwidget->pany; |
285 | srcbox.x1 = srcbox.x0 + width; |
286 | srcbox.y1 = srcbox.y0 + height - bwidget->pany; |
287 | |
288 | dstbox.x0 = x; |
289 | dstbox.y0 = y; |
290 | dstbox.x1 = dstbox.x0 + width; |
291 | dstbox.y1 = dstbox.y0 + height - bwidget->pany; |
292 | |
293 | /* move part that remains visible down */ |
294 | nsfb_plot_copy(nsfb, &srcbox, nsfb, &dstbox); |
295 | |
296 | /* redraw newly exposed area */ |
297 | bwidget->scrolly += bwidget->pany; |
298 | fb_queue_redraw(widget, 0, height - bwidget->pany, |
299 | width, height); |
300 | } |
301 | |
302 | if (bwidget->panx < 0) { |
303 | /* pan left by less then viewport width */ |
304 | srcbox.x0 = x; |
305 | srcbox.y0 = y; |
306 | srcbox.x1 = srcbox.x0 + width + bwidget->panx; |
307 | srcbox.y1 = srcbox.y0 + height; |
308 | |
309 | dstbox.x0 = x - bwidget->panx; |
310 | dstbox.y0 = y; |
311 | dstbox.x1 = dstbox.x0 + width + bwidget->panx; |
312 | dstbox.y1 = dstbox.y0 + height; |
313 | |
314 | /* move part that remains visible left */ |
315 | nsfb_plot_copy(nsfb, &srcbox, nsfb, &dstbox); |
316 | |
317 | /* redraw newly exposed area */ |
318 | bwidget->scrollx += bwidget->panx; |
319 | fb_queue_redraw(widget, 0, 0, -bwidget->panx, height); |
320 | |
321 | } else if (bwidget->panx > 0) { |
322 | /* pan right by less then viewport width */ |
323 | srcbox.x0 = x + bwidget->panx; |
324 | srcbox.y0 = y; |
325 | srcbox.x1 = srcbox.x0 + width - bwidget->panx; |
326 | srcbox.y1 = srcbox.y0 + height; |
327 | |
328 | dstbox.x0 = x; |
329 | dstbox.y0 = y; |
330 | dstbox.x1 = dstbox.x0 + width - bwidget->panx; |
331 | dstbox.y1 = dstbox.y0 + height; |
332 | |
333 | /* move part that remains visible right */ |
334 | nsfb_plot_copy(nsfb, &srcbox, nsfb, &dstbox); |
335 | |
336 | /* redraw newly exposed area */ |
337 | bwidget->scrollx += bwidget->panx; |
338 | fb_queue_redraw(widget, width - bwidget->panx, 0, |
339 | width, height); |
340 | } |
341 | |
342 | bwidget->pan_required = false0; |
343 | bwidget->panx = 0; |
344 | bwidget->pany = 0; |
345 | } |
346 | |
347 | static void |
348 | fb_redraw(fbtk_widget_t *widget, |
349 | struct browser_widget_s *bwidget, |
350 | struct browser_window *bw) |
351 | { |
352 | int x; |
353 | int y; |
354 | int caret_x, caret_y, caret_h; |
355 | struct rect clip; |
356 | struct redraw_context ctx = { |
357 | .interactive = true1, |
358 | .background_images = true1, |
359 | .plot = &fb_plotters |
360 | }; |
361 | nsfb_t *nsfb = fbtk_get_nsfb(widget); |
362 | |
363 | x = fbtk_get_absx(widget); |
364 | y = fbtk_get_absy(widget); |
365 | |
366 | /* adjust clipping co-ordinates according to window location */ |
367 | bwidget->redraw_box.y0 += y; |
368 | bwidget->redraw_box.y1 += y; |
369 | bwidget->redraw_box.x0 += x; |
370 | bwidget->redraw_box.x1 += x; |
371 | |
372 | nsfb_claim(nsfb, &bwidget->redraw_box); |
373 | |
374 | /* redraw bounding box is relative to window */ |
375 | clip.x0 = bwidget->redraw_box.x0; |
376 | clip.y0 = bwidget->redraw_box.y0; |
377 | clip.x1 = bwidget->redraw_box.x1; |
378 | clip.y1 = bwidget->redraw_box.y1; |
379 | |
380 | browser_window_redraw(bw, |
381 | x - bwidget->scrollx, |
382 | y - bwidget->scrolly, |
383 | &clip, &ctx); |
384 | |
385 | if (fbtk_get_caret(widget, &caret_x, &caret_y, &caret_h)) { |
386 | /* This widget has caret, so render it */ |
387 | nsfb_bbox_t line; |
388 | nsfb_plot_pen_t pen; |
389 | |
390 | line.x0 = x - bwidget->scrollx + caret_x; |
391 | line.y0 = y - bwidget->scrolly + caret_y; |
392 | line.x1 = x - bwidget->scrollx + caret_x; |
393 | line.y1 = y - bwidget->scrolly + caret_y + caret_h; |
394 | |
395 | pen.stroke_type = NFSB_PLOT_OPTYPE_SOLID; |
396 | pen.stroke_width = 1; |
397 | pen.stroke_colour = 0xFF0000FF; |
398 | |
399 | nsfb_plot_line(nsfb, &line, &pen); |
400 | } |
401 | |
402 | nsfb_update(fbtk_get_nsfb(widget), &bwidget->redraw_box); |
403 | |
404 | bwidget->redraw_box.y0 = bwidget->redraw_box.x0 = INT_MAX2147483647; |
405 | bwidget->redraw_box.y1 = bwidget->redraw_box.x1 = INT_MIN(-2147483647 -1); |
406 | bwidget->redraw_required = false0; |
407 | } |
408 | |
409 | static int |
410 | fb_browser_window_redraw(fbtk_widget_t *widget, fbtk_callback_info *cbi) |
411 | { |
412 | struct gui_window *gw = cbi->context; |
413 | struct browser_widget_s *bwidget; |
414 | |
415 | bwidget = fbtk_get_userpw(widget); |
416 | if (bwidget == NULL((void*)0)) { |
417 | NSLOG(netsurf, INFO,do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "frontends/framebuffer/gui.c", sizeof("frontends/framebuffer/gui.c" ) - 1, __PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__) - 1, 418 , }; nslog__log(&_nslog_ctx, "browser widget from widget %p was null" , widget); } } while(0) |
418 | "browser widget from widget %p was null", widget)do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "frontends/framebuffer/gui.c", sizeof("frontends/framebuffer/gui.c" ) - 1, __PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__) - 1, 418 , }; nslog__log(&_nslog_ctx, "browser widget from widget %p was null" , widget); } } while(0); |
419 | return -1; |
420 | } |
421 | |
422 | if (bwidget->pan_required) { |
423 | fb_pan(widget, bwidget, gw->bw); |
424 | } |
425 | |
426 | if (bwidget->redraw_required) { |
427 | fb_redraw(widget, bwidget, gw->bw); |
428 | } else { |
429 | bwidget->redraw_box.x0 = 0; |
430 | bwidget->redraw_box.y0 = 0; |
431 | bwidget->redraw_box.x1 = fbtk_get_width(widget); |
432 | bwidget->redraw_box.y1 = fbtk_get_height(widget); |
433 | fb_redraw(widget, bwidget, gw->bw); |
434 | } |
435 | return 0; |
436 | } |
437 | |
438 | static int fb_browser_window_destroy(fbtk_widget_t *widget, |
439 | fbtk_callback_info *cbi) |
440 | { |
441 | struct browser_widget_s *browser_widget; |
442 | |
443 | if (widget == NULL((void*)0)) { |
444 | return 0; |
445 | } |
446 | |
447 | /* Free private data */ |
448 | browser_widget = fbtk_get_userpw(widget); |
449 | free(browser_widget); |
450 | |
451 | return 0; |
452 | } |
453 | |
454 | static void |
455 | framebuffer_surface_iterator(void *ctx, const char *name, enum nsfb_type_e type) |
456 | { |
457 | const char *arg0 = ctx; |
458 | |
459 | fprintf(stderrstderr, "%s: %s\n", arg0, name); |
460 | } |
461 | |
462 | static enum nsfb_type_e fetype = NSFB_SURFACE_COUNT; |
463 | static const char *fename; |
464 | static int febpp; |
465 | static int fewidth; |
466 | static int feheight; |
467 | static const char *feurl; |
468 | |
469 | static void |
470 | framebuffer_pick_default_fename(void *ctx, const char *name, enum nsfb_type_e type) |
471 | { |
472 | if (type < fetype) { |
473 | fename = name; |
474 | } |
475 | } |
476 | |
477 | static bool_Bool |
478 | process_cmdline(int argc, char** argv) |
479 | { |
480 | int opt; |
481 | int option_index; |
482 | static struct option long_options[] = { |
483 | {0, 0, 0, 0 } |
484 | }; /* no long options */ |
485 | |
486 | NSLOG(netsurf, INFO, "argc %d, argv %p", argc, argv)do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "frontends/framebuffer/gui.c", sizeof("frontends/framebuffer/gui.c" ) - 1, __PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__) - 1, 486 , }; nslog__log(&_nslog_ctx, "argc %d, argv %p", argc, argv ); } } while(0); |
487 | |
488 | nsfb_enumerate_surface_types(framebuffer_pick_default_fename, NULL((void*)0)); |
489 | |
490 | febpp = 32; |
491 | |
492 | fewidth = nsoption_int(window_width)(nsoptions[NSOPTION_window_width].value.i); |
493 | if (fewidth <= 0) { |
494 | fewidth = 800; |
495 | } |
496 | feheight = nsoption_int(window_height)(nsoptions[NSOPTION_window_height].value.i); |
497 | if (feheight <= 0) { |
498 | feheight = 600; |
499 | } |
500 | |
501 | if ((nsoption_charp(homepage_url)(nsoptions[NSOPTION_homepage_url].value.s) != NULL((void*)0)) && |
502 | (nsoption_charp(homepage_url)(nsoptions[NSOPTION_homepage_url].value.s)[0] != '\0')) { |
503 | feurl = nsoption_charp(homepage_url)(nsoptions[NSOPTION_homepage_url].value.s); |
504 | } else { |
505 | feurl = NETSURF_HOMEPAGE"about:welcome"; |
506 | } |
507 | |
508 | while((opt = getopt_long(argc, argv, "f:b:w:h:", |
509 | long_options, &option_index)) != -1) { |
510 | switch (opt) { |
511 | case 'f': |
512 | fename = optarg; |
513 | break; |
514 | |
515 | case 'b': |
516 | febpp = atoi(optarg); |
517 | break; |
518 | |
519 | case 'w': |
520 | fewidth = atoi(optarg); |
521 | break; |
522 | |
523 | case 'h': |
524 | feheight = atoi(optarg); |
525 | break; |
526 | |
527 | default: |
528 | fprintf(stderrstderr, |
529 | "Usage: %s [-f frontend] [-b bpp] [-w width] [-h height] <url>\n", |
530 | argv[0]); |
531 | return false0; |
532 | } |
533 | } |
534 | |
535 | if (optind < argc) { |
536 | feurl = argv[optind]; |
537 | } |
538 | |
539 | if (nsfb_type_from_name(fename) == NSFB_SURFACE_NONE) { |
540 | if (strcmp(fename, "?") != 0) { |
541 | fprintf(stderrstderr, |
542 | "%s: Unknown surface `%s`\n", argv[0], fename); |
543 | } |
544 | fprintf(stderrstderr, "%s: Valid surface names are:\n", argv[0]); |
545 | nsfb_enumerate_surface_types(framebuffer_surface_iterator, argv[0]); |
546 | return false0; |
547 | } |
548 | |
549 | return true1; |
550 | } |
551 | |
552 | /** |
553 | * Set option defaults for framebuffer frontend |
554 | * |
555 | * @param defaults The option table to update. |
556 | * @return error status. |
557 | */ |
558 | static nserror set_defaults(struct nsoption_s *defaults) |
559 | { |
560 | /* Set defaults for absent option strings */ |
561 | nsoption_setnull_charp(cookie_file, strdup("~/.netsurf/Cookies"))do { if (nsoptions[NSOPTION_cookie_file].value.s == ((void*)0 )) { nsoption_set_tbl_charp(nsoptions, NSOPTION_cookie_file, strdup ("~/.netsurf/Cookies")); } else { free(strdup("~/.netsurf/Cookies" )); } } while (0); |
562 | nsoption_setnull_charp(cookie_jar, strdup("~/.netsurf/Cookies"))do { if (nsoptions[NSOPTION_cookie_jar].value.s == ((void*)0) ) { nsoption_set_tbl_charp(nsoptions, NSOPTION_cookie_jar, strdup ("~/.netsurf/Cookies")); } else { free(strdup("~/.netsurf/Cookies" )); } } while (0); |
563 | |
564 | if (nsoption_charp(cookie_file)(nsoptions[NSOPTION_cookie_file].value.s) == NULL((void*)0) || |
565 | nsoption_charp(cookie_jar)(nsoptions[NSOPTION_cookie_jar].value.s) == NULL((void*)0)) { |
566 | NSLOG(netsurf, INFO, "Failed initialising cookie options")do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "frontends/framebuffer/gui.c", sizeof("frontends/framebuffer/gui.c" ) - 1, __PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__) - 1, 566 , }; nslog__log(&_nslog_ctx, "Failed initialising cookie options" ); } } while(0); |
567 | return NSERROR_BAD_PARAMETER; |
568 | } |
569 | |
570 | /* set system colours for framebuffer ui */ |
571 | nsoption_set_colour(sys_colour_ActiveBorder, 0x00000000)nsoptions[NSOPTION_sys_colour_ActiveBorder].value.c = 0x00000000; |
572 | nsoption_set_colour(sys_colour_ActiveCaption, 0x00ddddcc)nsoptions[NSOPTION_sys_colour_ActiveCaption].value.c = 0x00ddddcc; |
573 | nsoption_set_colour(sys_colour_AppWorkspace, 0x00eeeeee)nsoptions[NSOPTION_sys_colour_AppWorkspace].value.c = 0x00eeeeee; |
574 | nsoption_set_colour(sys_colour_Background, 0x00aa0000)nsoptions[NSOPTION_sys_colour_Background].value.c = 0x00aa0000; |
575 | nsoption_set_colour(sys_colour_ButtonFace, 0x00dddddd)nsoptions[NSOPTION_sys_colour_ButtonFace].value.c = 0x00dddddd; |
576 | nsoption_set_colour(sys_colour_ButtonHighlight, 0x00cccccc)nsoptions[NSOPTION_sys_colour_ButtonHighlight].value.c = 0x00cccccc; |
577 | nsoption_set_colour(sys_colour_ButtonShadow, 0x00bbbbbb)nsoptions[NSOPTION_sys_colour_ButtonShadow].value.c = 0x00bbbbbb; |
578 | nsoption_set_colour(sys_colour_ButtonText, 0x00000000)nsoptions[NSOPTION_sys_colour_ButtonText].value.c = 0x00000000; |
579 | nsoption_set_colour(sys_colour_CaptionText, 0x00000000)nsoptions[NSOPTION_sys_colour_CaptionText].value.c = 0x00000000; |
580 | nsoption_set_colour(sys_colour_GrayText, 0x00777777)nsoptions[NSOPTION_sys_colour_GrayText].value.c = 0x00777777; |
581 | nsoption_set_colour(sys_colour_Highlight, 0x00ee0000)nsoptions[NSOPTION_sys_colour_Highlight].value.c = 0x00ee0000; |
582 | nsoption_set_colour(sys_colour_HighlightText, 0x00000000)nsoptions[NSOPTION_sys_colour_HighlightText].value.c = 0x00000000; |
583 | nsoption_set_colour(sys_colour_InactiveBorder, 0x00000000)nsoptions[NSOPTION_sys_colour_InactiveBorder].value.c = 0x00000000; |
584 | nsoption_set_colour(sys_colour_InactiveCaption, 0x00ffffff)nsoptions[NSOPTION_sys_colour_InactiveCaption].value.c = 0x00ffffff; |
585 | nsoption_set_colour(sys_colour_InactiveCaptionText, 0x00cccccc)nsoptions[NSOPTION_sys_colour_InactiveCaptionText].value.c = 0x00cccccc; |
586 | nsoption_set_colour(sys_colour_InfoBackground, 0x00aaaaaa)nsoptions[NSOPTION_sys_colour_InfoBackground].value.c = 0x00aaaaaa; |
587 | nsoption_set_colour(sys_colour_InfoText, 0x00000000)nsoptions[NSOPTION_sys_colour_InfoText].value.c = 0x00000000; |
588 | nsoption_set_colour(sys_colour_Menu, 0x00aaaaaa)nsoptions[NSOPTION_sys_colour_Menu].value.c = 0x00aaaaaa; |
589 | nsoption_set_colour(sys_colour_MenuText, 0x00000000)nsoptions[NSOPTION_sys_colour_MenuText].value.c = 0x00000000; |
590 | nsoption_set_colour(sys_colour_Scrollbar, 0x00aaaaaa)nsoptions[NSOPTION_sys_colour_Scrollbar].value.c = 0x00aaaaaa; |
591 | nsoption_set_colour(sys_colour_ThreeDDarkShadow, 0x00555555)nsoptions[NSOPTION_sys_colour_ThreeDDarkShadow].value.c = 0x00555555; |
592 | nsoption_set_colour(sys_colour_ThreeDFace, 0x00dddddd)nsoptions[NSOPTION_sys_colour_ThreeDFace].value.c = 0x00dddddd; |
593 | nsoption_set_colour(sys_colour_ThreeDHighlight, 0x00aaaaaa)nsoptions[NSOPTION_sys_colour_ThreeDHighlight].value.c = 0x00aaaaaa; |
594 | nsoption_set_colour(sys_colour_ThreeDLightShadow, 0x00999999)nsoptions[NSOPTION_sys_colour_ThreeDLightShadow].value.c = 0x00999999; |
595 | nsoption_set_colour(sys_colour_ThreeDShadow, 0x00777777)nsoptions[NSOPTION_sys_colour_ThreeDShadow].value.c = 0x00777777; |
596 | nsoption_set_colour(sys_colour_Window, 0x00aaaaaa)nsoptions[NSOPTION_sys_colour_Window].value.c = 0x00aaaaaa; |
597 | nsoption_set_colour(sys_colour_WindowFrame, 0x00000000)nsoptions[NSOPTION_sys_colour_WindowFrame].value.c = 0x00000000; |
598 | nsoption_set_colour(sys_colour_WindowText, 0x00000000)nsoptions[NSOPTION_sys_colour_WindowText].value.c = 0x00000000; |
599 | |
600 | return NSERROR_OK; |
601 | } |
602 | |
603 | |
604 | /** |
605 | * Ensures output logging stream is correctly configured |
606 | */ |
607 | static bool_Bool nslog_stream_configure(FILE *fptr) |
608 | { |
609 | /* set log stream to be non-buffering */ |
610 | setbuf(fptr, NULL((void*)0)); |
611 | |
612 | return true1; |
613 | } |
614 | |
615 | static void framebuffer_run(void) |
616 | { |
617 | nsfb_event_t event; |
618 | int timeout; /* timeout in miliseconds */ |
619 | |
620 | while (fb_complete != true1) { |
621 | /* run the scheduler and discover how long to wait for |
622 | * the next event. |
623 | */ |
624 | timeout = schedule_run(); |
625 | |
626 | /* if redraws are pending do not wait for event, |
627 | * return immediately |
628 | */ |
629 | if (fbtk_get_redraw_pending(fbtk)) |
630 | timeout = 0; |
631 | |
632 | if (fbtk_event(fbtk, &event, timeout)) { |
633 | if ((event.type == NSFB_EVENT_CONTROL) && |
634 | (event.value.controlcode == NSFB_CONTROL_QUIT)) |
635 | fb_complete = true1; |
636 | } |
637 | |
638 | fbtk_redraw(fbtk); |
639 | } |
640 | } |
641 | |
642 | static void gui_quit(void) |
643 | { |
644 | NSLOG(netsurf, INFO, "gui_quit")do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "frontends/framebuffer/gui.c", sizeof("frontends/framebuffer/gui.c" ) - 1, __PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__) - 1, 644 , }; nslog__log(&_nslog_ctx, "gui_quit"); } } while(0); |
645 | |
646 | urldb_save_cookies(nsoption_charp(cookie_jar)(nsoptions[NSOPTION_cookie_jar].value.s)); |
647 | |
648 | framebuffer_finalise(); |
649 | } |
650 | |
651 | /* called back when click in browser window */ |
652 | static int |
653 | fb_browser_window_click(fbtk_widget_t *widget, fbtk_callback_info *cbi) |
654 | { |
655 | struct gui_window *gw = cbi->context; |
656 | struct browser_widget_s *bwidget = fbtk_get_userpw(widget); |
657 | browser_mouse_state mouse; |
658 | int x = cbi->x + bwidget->scrollx; |
659 | int y = cbi->y + bwidget->scrolly; |
660 | uint64_t time_now; |
661 | static struct { |
662 | enum { CLICK_SINGLE, CLICK_DOUBLE, CLICK_TRIPLE } type; |
663 | uint64_t time; |
664 | } last_click; |
665 | |
666 | if (cbi->event->type != NSFB_EVENT_KEY_DOWN && |
667 | cbi->event->type != NSFB_EVENT_KEY_UP) |
668 | return 0; |
669 | |
670 | NSLOG(netsurf, DEEPDEBUG, "browser window clicked at %d,%d",do { if (NSLOG_LEVEL_DEEPDEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_DEEPDEBUG, "frontends/framebuffer/gui.c", sizeof ("frontends/framebuffer/gui.c") - 1, __PRETTY_FUNCTION__, sizeof (__PRETTY_FUNCTION__) - 1, 671, }; nslog__log(&_nslog_ctx , "browser window clicked at %d,%d", cbi->x, cbi->y); } } while(0) |
671 | cbi->x, cbi->y)do { if (NSLOG_LEVEL_DEEPDEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_DEEPDEBUG, "frontends/framebuffer/gui.c", sizeof ("frontends/framebuffer/gui.c") - 1, __PRETTY_FUNCTION__, sizeof (__PRETTY_FUNCTION__) - 1, 671, }; nslog__log(&_nslog_ctx , "browser window clicked at %d,%d", cbi->x, cbi->y); } } while(0); |
672 | |
673 | switch (cbi->event->type) { |
674 | case NSFB_EVENT_KEY_DOWN: |
675 | switch (cbi->event->value.keycode) { |
676 | case NSFB_KEY_MOUSE_1: |
677 | browser_window_mouse_click(gw->bw, |
678 | BROWSER_MOUSE_PRESS_1, x, y); |
679 | gui_drag.state = GUI_DRAG_PRESSED; |
680 | gui_drag.button = 1; |
681 | gui_drag.x = x; |
682 | gui_drag.y = y; |
683 | break; |
684 | |
685 | case NSFB_KEY_MOUSE_3: |
686 | browser_window_mouse_click(gw->bw, |
687 | BROWSER_MOUSE_PRESS_2, x, y); |
688 | gui_drag.state = GUI_DRAG_PRESSED; |
689 | gui_drag.button = 2; |
690 | gui_drag.x = x; |
691 | gui_drag.y = y; |
692 | break; |
693 | |
694 | case NSFB_KEY_MOUSE_4: |
695 | /* scroll up */ |
696 | if (browser_window_scroll_at_point(gw->bw, |
697 | x, y, |
698 | 0, -100) == false0) |
699 | widget_scroll_y(gw, -100, false0); |
700 | break; |
701 | |
702 | case NSFB_KEY_MOUSE_5: |
703 | /* scroll down */ |
704 | if (browser_window_scroll_at_point(gw->bw, |
705 | x, y, |
706 | 0, 100) == false0) |
707 | widget_scroll_y(gw, 100, false0); |
708 | break; |
709 | |
710 | default: |
711 | break; |
712 | |
713 | } |
714 | |
715 | break; |
716 | case NSFB_EVENT_KEY_UP: |
717 | |
718 | mouse = 0; |
719 | nsu_getmonotonic_ms(&time_now); |
720 | |
721 | switch (cbi->event->value.keycode) { |
722 | case NSFB_KEY_MOUSE_1: |
723 | if (gui_drag.state == GUI_DRAG_DRAG) { |
724 | /* End of a drag, rather than click */ |
725 | |
726 | if (gui_drag.grabbed_pointer) { |
727 | /* need to ungrab pointer */ |
728 | fbtk_tgrab_pointer(widget); |
729 | gui_drag.grabbed_pointer = false0; |
730 | } |
731 | |
732 | gui_drag.state = GUI_DRAG_NONE; |
733 | |
734 | /* Tell core */ |
735 | browser_window_mouse_track(gw->bw, 0, x, y); |
736 | break; |
737 | } |
738 | /* This is a click; |
739 | * clear PRESSED state and pass to core */ |
740 | gui_drag.state = GUI_DRAG_NONE; |
741 | mouse = BROWSER_MOUSE_CLICK_1; |
742 | break; |
743 | |
744 | case NSFB_KEY_MOUSE_3: |
745 | if (gui_drag.state == GUI_DRAG_DRAG) { |
746 | /* End of a drag, rather than click */ |
747 | gui_drag.state = GUI_DRAG_NONE; |
748 | |
749 | if (gui_drag.grabbed_pointer) { |
750 | /* need to ungrab pointer */ |
751 | fbtk_tgrab_pointer(widget); |
752 | gui_drag.grabbed_pointer = false0; |
753 | } |
754 | |
755 | /* Tell core */ |
756 | browser_window_mouse_track(gw->bw, 0, x, y); |
757 | break; |
758 | } |
759 | /* This is a click; |
760 | * clear PRESSED state and pass to core */ |
761 | gui_drag.state = GUI_DRAG_NONE; |
762 | mouse = BROWSER_MOUSE_CLICK_2; |
763 | break; |
764 | |
765 | default: |
766 | break; |
767 | |
768 | } |
769 | |
770 | /* Determine if it's a double or triple click, allowing |
771 | * 0.5 seconds (500ms) between clicks |
772 | */ |
773 | if ((time_now < (last_click.time + 500)) && |
774 | (cbi->event->value.keycode != NSFB_KEY_MOUSE_4) && |
775 | (cbi->event->value.keycode != NSFB_KEY_MOUSE_5)) { |
776 | if (last_click.type == CLICK_SINGLE) { |
777 | /* Set double click */ |
778 | mouse |= BROWSER_MOUSE_DOUBLE_CLICK; |
779 | last_click.type = CLICK_DOUBLE; |
780 | |
781 | } else if (last_click.type == CLICK_DOUBLE) { |
782 | /* Set triple click */ |
783 | mouse |= BROWSER_MOUSE_TRIPLE_CLICK; |
784 | last_click.type = CLICK_TRIPLE; |
785 | } else { |
786 | /* Set normal click */ |
787 | last_click.type = CLICK_SINGLE; |
788 | } |
789 | } else { |
790 | last_click.type = CLICK_SINGLE; |
791 | } |
792 | |
793 | if (mouse) { |
794 | browser_window_mouse_click(gw->bw, mouse, x, y); |
795 | } |
796 | |
797 | last_click.time = time_now; |
798 | |
799 | break; |
800 | default: |
801 | break; |
802 | |
803 | } |
804 | return 1; |
805 | } |
806 | |
807 | /* called back when movement in browser window */ |
808 | static int |
809 | fb_browser_window_move(fbtk_widget_t *widget, fbtk_callback_info *cbi) |
810 | { |
811 | browser_mouse_state mouse = 0; |
812 | struct gui_window *gw = cbi->context; |
813 | struct browser_widget_s *bwidget = fbtk_get_userpw(widget); |
814 | int x = cbi->x + bwidget->scrollx; |
815 | int y = cbi->y + bwidget->scrolly; |
816 | |
817 | if (gui_drag.state == GUI_DRAG_PRESSED && |
818 | (abs(x - gui_drag.x) > 5 || |
819 | abs(y - gui_drag.y) > 5)) { |
820 | /* Drag started */ |
821 | if (gui_drag.button == 1) { |
822 | browser_window_mouse_click(gw->bw, |
823 | BROWSER_MOUSE_DRAG_1, |
824 | gui_drag.x, gui_drag.y); |
825 | } else { |
826 | browser_window_mouse_click(gw->bw, |
827 | BROWSER_MOUSE_DRAG_2, |
828 | gui_drag.x, gui_drag.y); |
829 | } |
830 | gui_drag.grabbed_pointer = fbtk_tgrab_pointer(widget); |
831 | gui_drag.state = GUI_DRAG_DRAG; |
832 | } |
833 | |
834 | if (gui_drag.state == GUI_DRAG_DRAG) { |
835 | /* set up mouse state */ |
836 | mouse |= BROWSER_MOUSE_DRAG_ON; |
837 | |
838 | if (gui_drag.button == 1) |
839 | mouse |= BROWSER_MOUSE_HOLDING_1; |
840 | else |
841 | mouse |= BROWSER_MOUSE_HOLDING_2; |
842 | } |
843 | |
844 | browser_window_mouse_track(gw->bw, mouse, x, y); |
845 | |
846 | return 0; |
847 | } |
848 | |
849 | |
850 | static int |
851 | fb_browser_window_input(fbtk_widget_t *widget, fbtk_callback_info *cbi) |
852 | { |
853 | struct gui_window *gw = cbi->context; |
854 | static fbtk_modifier_type modifier = FBTK_MOD_CLEAR; |
855 | int ucs4 = -1; |
856 | |
857 | NSLOG(netsurf, INFO, "got value %d", cbi->event->value.keycode)do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "frontends/framebuffer/gui.c", sizeof("frontends/framebuffer/gui.c" ) - 1, __PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__) - 1, 857 , }; nslog__log(&_nslog_ctx, "got value %d", cbi->event ->value.keycode); } } while(0); |
858 | |
859 | switch (cbi->event->type) { |
860 | case NSFB_EVENT_KEY_DOWN: |
861 | switch (cbi->event->value.keycode) { |
862 | |
863 | case NSFB_KEY_DELETE: |
864 | browser_window_key_press(gw->bw, NS_KEY_DELETE_RIGHT); |
865 | break; |
866 | |
867 | case NSFB_KEY_PAGEUP: |
868 | if (browser_window_key_press(gw->bw, |
869 | NS_KEY_PAGE_UP) == false0) |
870 | widget_scroll_y(gw, -fbtk_get_height( |
871 | gw->browser), false0); |
872 | break; |
873 | |
874 | case NSFB_KEY_PAGEDOWN: |
875 | if (browser_window_key_press(gw->bw, |
876 | NS_KEY_PAGE_DOWN) == false0) |
877 | widget_scroll_y(gw, fbtk_get_height( |
878 | gw->browser), false0); |
879 | break; |
880 | |
881 | case NSFB_KEY_RIGHT: |
882 | if (modifier & FBTK_MOD_RCTRL || |
883 | modifier & FBTK_MOD_LCTRL) { |
884 | /* CTRL held */ |
885 | if (browser_window_key_press(gw->bw, |
886 | NS_KEY_LINE_END) == false0) |
887 | widget_scroll_x(gw, INT_MAX2147483647, true1); |
888 | |
889 | } else if (modifier & FBTK_MOD_RSHIFT || |
890 | modifier & FBTK_MOD_LSHIFT) { |
891 | /* SHIFT held */ |
892 | if (browser_window_key_press(gw->bw, |
893 | NS_KEY_WORD_RIGHT) == false0) |
894 | widget_scroll_x(gw, fbtk_get_width( |
895 | gw->browser), false0); |
896 | |
897 | } else { |
898 | /* no modifier */ |
899 | if (browser_window_key_press(gw->bw, |
900 | NS_KEY_RIGHT) == false0) |
901 | widget_scroll_x(gw, 100, false0); |
902 | } |
903 | break; |
904 | |
905 | case NSFB_KEY_LEFT: |
906 | if (modifier & FBTK_MOD_RCTRL || |
907 | modifier & FBTK_MOD_LCTRL) { |
908 | /* CTRL held */ |
909 | if (browser_window_key_press(gw->bw, |
910 | NS_KEY_LINE_START) == false0) |
911 | widget_scroll_x(gw, 0, true1); |
912 | |
913 | } else if (modifier & FBTK_MOD_RSHIFT || |
914 | modifier & FBTK_MOD_LSHIFT) { |
915 | /* SHIFT held */ |
916 | if (browser_window_key_press(gw->bw, |
917 | NS_KEY_WORD_LEFT) == false0) |
918 | widget_scroll_x(gw, -fbtk_get_width( |
919 | gw->browser), false0); |
920 | |
921 | } else { |
922 | /* no modifier */ |
923 | if (browser_window_key_press(gw->bw, |
924 | NS_KEY_LEFT) == false0) |
925 | widget_scroll_x(gw, -100, false0); |
926 | } |
927 | break; |
928 | |
929 | case NSFB_KEY_UP: |
930 | if (browser_window_key_press(gw->bw, |
931 | NS_KEY_UP) == false0) |
932 | widget_scroll_y(gw, -100, false0); |
933 | break; |
934 | |
935 | case NSFB_KEY_DOWN: |
936 | if (browser_window_key_press(gw->bw, |
937 | NS_KEY_DOWN) == false0) |
938 | widget_scroll_y(gw, 100, false0); |
939 | break; |
940 | |
941 | case NSFB_KEY_MINUS: |
942 | if (modifier & FBTK_MOD_RCTRL || |
943 | modifier & FBTK_MOD_LCTRL) { |
944 | browser_window_set_scale(gw->bw, -0.1, false0); |
945 | } |
946 | break; |
947 | |
948 | case NSFB_KEY_EQUALS: /* PLUS */ |
949 | if (modifier & FBTK_MOD_RCTRL || |
950 | modifier & FBTK_MOD_LCTRL) { |
951 | browser_window_set_scale(gw->bw, 0.1, false0); |
952 | } |
953 | break; |
954 | |
955 | case NSFB_KEY_0: |
956 | if (modifier & FBTK_MOD_RCTRL || |
957 | modifier & FBTK_MOD_LCTRL) { |
958 | browser_window_set_scale(gw->bw, 1.0, true1); |
959 | } |
960 | break; |
961 | |
962 | case NSFB_KEY_RSHIFT: |
963 | modifier |= FBTK_MOD_RSHIFT; |
964 | break; |
965 | |
966 | case NSFB_KEY_LSHIFT: |
967 | modifier |= FBTK_MOD_LSHIFT; |
968 | break; |
969 | |
970 | case NSFB_KEY_RCTRL: |
971 | modifier |= FBTK_MOD_RCTRL; |
972 | break; |
973 | |
974 | case NSFB_KEY_LCTRL: |
975 | modifier |= FBTK_MOD_LCTRL; |
976 | break; |
977 | |
978 | case NSFB_KEY_y: |
979 | case NSFB_KEY_z: |
980 | if (cbi->event->value.keycode == NSFB_KEY_z && |
981 | (modifier & FBTK_MOD_RCTRL || |
982 | modifier & FBTK_MOD_LCTRL) && |
983 | (modifier & FBTK_MOD_RSHIFT || |
984 | modifier & FBTK_MOD_LSHIFT)) { |
985 | /* Z pressed with CTRL and SHIFT held */ |
986 | browser_window_key_press(gw->bw, NS_KEY_REDO); |
987 | break; |
988 | |
989 | } else if (cbi->event->value.keycode == NSFB_KEY_z && |
990 | (modifier & FBTK_MOD_RCTRL || |
991 | modifier & FBTK_MOD_LCTRL)) { |
992 | /* Z pressed with CTRL held */ |
993 | browser_window_key_press(gw->bw, NS_KEY_UNDO); |
994 | break; |
995 | |
996 | } else if (cbi->event->value.keycode == NSFB_KEY_y && |
997 | (modifier & FBTK_MOD_RCTRL || |
998 | modifier & FBTK_MOD_LCTRL)) { |
999 | /* Y pressed with CTRL held */ |
1000 | browser_window_key_press(gw->bw, NS_KEY_REDO); |
1001 | break; |
1002 | } |
1003 | /* Z or Y pressed but not undo or redo; */ |
1004 | fallthrough__attribute__((__fallthrough__)); |
1005 | |
1006 | default: |
1007 | ucs4 = fbtk_keycode_to_ucs4(cbi->event->value.keycode, |
1008 | modifier); |
1009 | if (ucs4 != -1) |
1010 | browser_window_key_press(gw->bw, ucs4); |
1011 | break; |
1012 | } |
1013 | break; |
1014 | |
1015 | case NSFB_EVENT_KEY_UP: |
1016 | switch (cbi->event->value.keycode) { |
1017 | case NSFB_KEY_RSHIFT: |
1018 | modifier &= ~FBTK_MOD_RSHIFT; |
1019 | break; |
1020 | |
1021 | case NSFB_KEY_LSHIFT: |
1022 | modifier &= ~FBTK_MOD_LSHIFT; |
1023 | break; |
1024 | |
1025 | case NSFB_KEY_RCTRL: |
1026 | modifier &= ~FBTK_MOD_RCTRL; |
1027 | break; |
1028 | |
1029 | case NSFB_KEY_LCTRL: |
1030 | modifier &= ~FBTK_MOD_LCTRL; |
1031 | break; |
1032 | |
1033 | default: |
1034 | break; |
1035 | } |
1036 | break; |
1037 | |
1038 | default: |
1039 | break; |
1040 | } |
1041 | |
1042 | return 0; |
1043 | } |
1044 | |
1045 | static void |
1046 | fb_update_back_forward(struct gui_window *gw) |
1047 | { |
1048 | struct browser_window *bw = gw->bw; |
1049 | |
1050 | fbtk_set_bitmap(gw->back, |
1051 | (browser_window_back_available(bw)) ? |
1052 | &left_arrow : &left_arrow_g); |
1053 | fbtk_set_bitmap(gw->forward, |
1054 | (browser_window_forward_available(bw)) ? |
1055 | &right_arrow : &right_arrow_g); |
1056 | } |
1057 | |
1058 | /* left icon click routine */ |
1059 | static int |
1060 | fb_leftarrow_click(fbtk_widget_t *widget, fbtk_callback_info *cbi) |
1061 | { |
1062 | struct gui_window *gw = cbi->context; |
1063 | struct browser_window *bw = gw->bw; |
1064 | |
1065 | if (cbi->event->type != NSFB_EVENT_KEY_UP) |
1066 | return 0; |
1067 | |
1068 | if (browser_window_back_available(bw)) |
1069 | browser_window_history_back(bw, false0); |
1070 | |
1071 | fb_update_back_forward(gw); |
1072 | |
1073 | return 1; |
1074 | } |
1075 | |
1076 | /* right arrow icon click routine */ |
1077 | static int |
1078 | fb_rightarrow_click(fbtk_widget_t *widget, fbtk_callback_info *cbi) |
1079 | { |
1080 | struct gui_window *gw = cbi->context; |
1081 | struct browser_window *bw = gw->bw; |
1082 | |
1083 | if (cbi->event->type != NSFB_EVENT_KEY_UP) |
1084 | return 0; |
1085 | |
1086 | if (browser_window_forward_available(bw)) |
1087 | browser_window_history_forward(bw, false0); |
1088 | |
1089 | fb_update_back_forward(gw); |
1090 | return 1; |
1091 | |
1092 | } |
1093 | |
1094 | /* reload icon click routine */ |
1095 | static int |
1096 | fb_reload_click(fbtk_widget_t *widget, fbtk_callback_info *cbi) |
1097 | { |
1098 | struct browser_window *bw = cbi->context; |
1099 | |
1100 | if (cbi->event->type != NSFB_EVENT_KEY_UP) |
1101 | return 0; |
1102 | |
1103 | browser_window_reload(bw, true1); |
1104 | return 1; |
1105 | } |
1106 | |
1107 | /* stop icon click routine */ |
1108 | static int |
1109 | fb_stop_click(fbtk_widget_t *widget, fbtk_callback_info *cbi) |
1110 | { |
1111 | struct browser_window *bw = cbi->context; |
1112 | |
1113 | if (cbi->event->type != NSFB_EVENT_KEY_UP) |
1114 | return 0; |
1115 | |
1116 | browser_window_stop(bw); |
1117 | return 0; |
1118 | } |
1119 | |
1120 | static int |
1121 | fb_osk_click(fbtk_widget_t *widget, fbtk_callback_info *cbi) |
1122 | { |
1123 | |
1124 | if (cbi->event->type != NSFB_EVENT_KEY_UP) |
1125 | return 0; |
1126 | |
1127 | map_osk(); |
1128 | |
1129 | return 0; |
1130 | } |
1131 | |
1132 | /* close browser window icon click routine */ |
1133 | static int |
1134 | fb_close_click(fbtk_widget_t *widget, fbtk_callback_info *cbi) |
1135 | { |
1136 | if (cbi->event->type != NSFB_EVENT_KEY_UP) |
1137 | return 0; |
1138 | |
1139 | fb_complete = true1; |
1140 | |
1141 | return 0; |
1142 | } |
1143 | |
1144 | static int |
1145 | fb_scroll_callback(fbtk_widget_t *widget, fbtk_callback_info *cbi) |
1146 | { |
1147 | struct gui_window *gw = cbi->context; |
1148 | |
1149 | switch (cbi->type) { |
1150 | case FBTK_CBT_SCROLLY: |
1151 | widget_scroll_y(gw, cbi->y, true1); |
1152 | break; |
1153 | |
1154 | case FBTK_CBT_SCROLLX: |
1155 | widget_scroll_x(gw, cbi->x, true1); |
1156 | break; |
1157 | |
1158 | default: |
1159 | break; |
1160 | } |
1161 | return 0; |
1162 | } |
1163 | |
1164 | static int |
1165 | fb_url_enter(void *pw, char *text) |
1166 | { |
1167 | struct browser_window *bw = pw; |
1168 | nsurl *url; |
1169 | nserror error; |
1170 | |
1171 | error = nsurl_create(text, &url); |
1172 | if (error != NSERROR_OK) { |
1173 | fb_warn_user("Errorcode:", messages_get_errorcode(error)); |
1174 | } else { |
1175 | browser_window_navigate(bw, url, NULL((void*)0), BW_NAVIGATE_HISTORY, |
1176 | NULL((void*)0), NULL((void*)0), NULL((void*)0)); |
1177 | nsurl_unref(url); |
1178 | } |
1179 | |
1180 | return 0; |
1181 | } |
1182 | |
1183 | static int |
1184 | fb_url_move(fbtk_widget_t *widget, fbtk_callback_info *cbi) |
1185 | { |
1186 | framebuffer_set_cursor(&caret_image); |
1187 | return 0; |
1188 | } |
1189 | |
1190 | static int |
1191 | set_ptr_default_move(fbtk_widget_t *widget, fbtk_callback_info *cbi) |
1192 | { |
1193 | framebuffer_set_cursor(&pointer_image); |
1194 | return 0; |
1195 | } |
1196 | |
1197 | static int |
1198 | fb_localhistory_btn_clik(fbtk_widget_t *widget, fbtk_callback_info *cbi) |
1199 | { |
1200 | struct gui_window *gw = cbi->context; |
1201 | |
1202 | if (cbi->event->type != NSFB_EVENT_KEY_UP) |
1203 | return 0; |
1204 | |
1205 | fb_local_history_present(fbtk, gw->bw); |
1206 | |
1207 | return 0; |
1208 | } |
1209 | |
1210 | |
1211 | /** Create a toolbar window and populate it with buttons. |
1212 | * |
1213 | * The toolbar layout uses a character to define buttons type and position: |
1214 | * b - back |
1215 | * l - local history |
1216 | * f - forward |
1217 | * s - stop |
1218 | * r - refresh |
1219 | * u - url bar expands to fit remaining space |
1220 | * t - throbber/activity indicator |
1221 | * c - close the current window |
1222 | * |
1223 | * The default layout is "blfsrut" there should be no more than a |
1224 | * single url bar entry or behaviour will be undefined. |
1225 | * |
1226 | * @param gw Parent window |
1227 | * @param toolbar_height The height in pixels of the toolbar |
1228 | * @param padding The padding in pixels round each element of the toolbar |
1229 | * @param frame_col Frame colour. |
1230 | * @param toolbar_layout A string defining which buttons and controls |
1231 | * should be added to the toolbar. May be empty |
1232 | * string to disable the bar.. |
1233 | * |
1234 | */ |
1235 | static fbtk_widget_t * |
1236 | create_toolbar(struct gui_window *gw, |
1237 | int toolbar_height, |
1238 | int padding, |
1239 | colour frame_col, |
1240 | const char *toolbar_layout) |
1241 | { |
1242 | fbtk_widget_t *toolbar; |
1243 | fbtk_widget_t *widget; |
1244 | |
1245 | int xpos; /* The position of the next widget. */ |
1246 | int xlhs = 0; /* extent of the left hand side widgets */ |
1247 | int xdir = 1; /* the direction of movement + or - 1 */ |
1248 | const char *itmtype; /* type of the next item */ |
1249 | |
1250 | if (toolbar_layout == NULL((void*)0)) { |
1251 | toolbar_layout = NSFB_TOOLBAR_DEFAULT_LAYOUT"blfsrutc"; |
1252 | } |
1253 | |
1254 | NSLOG(netsurf, INFO, "Using toolbar layout %s", toolbar_layout)do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "frontends/framebuffer/gui.c", sizeof("frontends/framebuffer/gui.c" ) - 1, __PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__) - 1, 1254 , }; nslog__log(&_nslog_ctx, "Using toolbar layout %s", toolbar_layout ); } } while(0); |
1255 | |
1256 | itmtype = toolbar_layout; |
1257 | |
1258 | /* check for the toolbar being disabled */ |
1259 | if ((*itmtype == 0) || (*itmtype == 'q')) { |
1260 | return NULL((void*)0); |
1261 | } |
1262 | |
1263 | toolbar = fbtk_create_window(gw->window, 0, 0, 0, |
1264 | toolbar_height, |
1265 | frame_col); |
1266 | |
1267 | if (toolbar == NULL((void*)0)) { |
1268 | return NULL((void*)0); |
1269 | } |
1270 | |
1271 | fbtk_set_handler(toolbar, |
1272 | FBTK_CBT_POINTERENTER, |
1273 | set_ptr_default_move, |
1274 | NULL((void*)0)); |
1275 | |
1276 | |
1277 | xpos = padding; |
1278 | |
1279 | /* loop proceeds creating widget on the left hand side until |
1280 | * it runs out of layout or encounters a url bar declaration |
1281 | * wherupon it works backwards from the end of the layout |
1282 | * untill the space left is for the url bar |
1283 | */ |
1284 | while ((itmtype >= toolbar_layout) && |
1285 | (*itmtype != 0) && |
1286 | (xdir !=0)) { |
1287 | |
1288 | NSLOG(netsurf, INFO, "toolbar adding %c", *itmtype)do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "frontends/framebuffer/gui.c", sizeof("frontends/framebuffer/gui.c" ) - 1, __PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__) - 1, 1288 , }; nslog__log(&_nslog_ctx, "toolbar adding %c", *itmtype ); } } while(0); |
1289 | |
1290 | |
1291 | switch (*itmtype) { |
1292 | |
1293 | case 'b': /* back */ |
1294 | widget = fbtk_create_button(toolbar, |
1295 | (xdir == 1) ? xpos : |
1296 | xpos - left_arrow.width, |
1297 | padding, |
1298 | left_arrow.width, |
1299 | -padding, |
1300 | frame_col, |
1301 | &left_arrow, |
1302 | fb_leftarrow_click, |
1303 | gw); |
1304 | gw->back = widget; /* keep reference */ |
1305 | break; |
1306 | |
1307 | case 'l': /* local history */ |
1308 | widget = fbtk_create_button(toolbar, |
1309 | (xdir == 1) ? xpos : |
1310 | xpos - history_image.width, |
1311 | padding, |
1312 | history_image.width, |
1313 | -padding, |
1314 | frame_col, |
1315 | &history_image, |
1316 | fb_localhistory_btn_clik, |
1317 | gw); |
1318 | gw->history = widget; |
1319 | break; |
1320 | |
1321 | case 'f': /* forward */ |
1322 | widget = fbtk_create_button(toolbar, |
1323 | (xdir == 1)?xpos : |
1324 | xpos - right_arrow.width, |
1325 | padding, |
1326 | right_arrow.width, |
1327 | -padding, |
1328 | frame_col, |
1329 | &right_arrow, |
1330 | fb_rightarrow_click, |
1331 | gw); |
1332 | gw->forward = widget; |
1333 | break; |
1334 | |
1335 | case 'c': /* close the current window */ |
1336 | widget = fbtk_create_button(toolbar, |
1337 | (xdir == 1)?xpos : |
1338 | xpos - stop_image_g.width, |
1339 | padding, |
1340 | stop_image_g.width, |
1341 | -padding, |
1342 | frame_col, |
1343 | &stop_image_g, |
1344 | fb_close_click, |
1345 | gw->bw); |
1346 | gw->close = widget; |
1347 | break; |
1348 | |
1349 | case 's': /* stop */ |
1350 | widget = fbtk_create_button(toolbar, |
1351 | (xdir == 1)?xpos : |
1352 | xpos - stop_image.width, |
1353 | padding, |
1354 | stop_image.width, |
1355 | -padding, |
1356 | frame_col, |
1357 | &stop_image, |
1358 | fb_stop_click, |
1359 | gw->bw); |
1360 | gw->stop = widget; |
1361 | break; |
1362 | |
1363 | case 'r': /* reload */ |
1364 | widget = fbtk_create_button(toolbar, |
1365 | (xdir == 1)?xpos : |
1366 | xpos - reload.width, |
1367 | padding, |
1368 | reload.width, |
1369 | -padding, |
1370 | frame_col, |
1371 | &reload, |
1372 | fb_reload_click, |
1373 | gw->bw); |
1374 | gw->reload = widget; |
1375 | break; |
1376 | |
1377 | case 't': /* throbber/activity indicator */ |
1378 | widget = fbtk_create_bitmap(toolbar, |
1379 | (xdir == 1)?xpos : |
1380 | xpos - throbber0.width, |
1381 | padding, |
1382 | throbber0.width, |
1383 | -padding, |
1384 | frame_col, |
1385 | &throbber0); |
1386 | gw->throbber = widget; |
1387 | break; |
1388 | |
1389 | |
1390 | case 'u': /* url bar*/ |
1391 | if (xdir == -1) { |
1392 | /* met the u going backwards add url |
1393 | * now we know available extent |
1394 | */ |
1395 | |
1396 | widget = fbtk_create_writable_text(toolbar, |
1397 | xlhs, |
1398 | padding, |
1399 | xpos - xlhs, |
1400 | -padding, |
1401 | FB_COLOUR_WHITE0xFFFFFFFF, |
1402 | FB_COLOUR_BLACK0xFF000000, |
1403 | true1, |
1404 | fb_url_enter, |
1405 | gw->bw); |
1406 | |
1407 | fbtk_set_handler(widget, |
1408 | FBTK_CBT_POINTERENTER, |
1409 | fb_url_move, gw->bw); |
1410 | |
1411 | gw->url = widget; /* keep reference */ |
1412 | |
1413 | /* toolbar is complete */ |
1414 | xdir = 0; |
1415 | break; |
1416 | } |
1417 | /* met url going forwards, note position and |
1418 | * reverse direction |
1419 | */ |
1420 | itmtype = toolbar_layout + strlen(toolbar_layout); |
1421 | xdir = -1; |
1422 | xlhs = xpos; |
1423 | xpos = (2 * fbtk_get_width(toolbar)); |
1424 | widget = toolbar; |
1425 | break; |
1426 | |
1427 | default: |
1428 | widget = NULL((void*)0); |
1429 | xdir = 0; |
1430 | NSLOG(netsurf, INFO,do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "frontends/framebuffer/gui.c", sizeof("frontends/framebuffer/gui.c" ) - 1, __PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__) - 1, 1432 , }; nslog__log(&_nslog_ctx, "Unknown element %c in toolbar layout" , *itmtype); } } while(0) |
1431 | "Unknown element %c in toolbar layout",do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "frontends/framebuffer/gui.c", sizeof("frontends/framebuffer/gui.c" ) - 1, __PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__) - 1, 1432 , }; nslog__log(&_nslog_ctx, "Unknown element %c in toolbar layout" , *itmtype); } } while(0) |
1432 | *itmtype)do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "frontends/framebuffer/gui.c", sizeof("frontends/framebuffer/gui.c" ) - 1, __PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__) - 1, 1432 , }; nslog__log(&_nslog_ctx, "Unknown element %c in toolbar layout" , *itmtype); } } while(0); |
1433 | break; |
1434 | |
1435 | } |
1436 | |
1437 | if (widget != NULL((void*)0)) { |
1438 | xpos += (xdir * (fbtk_get_width(widget) + padding)); |
1439 | } |
1440 | |
1441 | NSLOG(netsurf, INFO, "xpos is %d", xpos)do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "frontends/framebuffer/gui.c", sizeof("frontends/framebuffer/gui.c" ) - 1, __PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__) - 1, 1441 , }; nslog__log(&_nslog_ctx, "xpos is %d", xpos); } } while (0); |
1442 | |
1443 | itmtype += xdir; |
1444 | } |
1445 | |
1446 | fbtk_set_mapping(toolbar, true1); |
1447 | |
1448 | return toolbar; |
1449 | } |
1450 | |
1451 | |
1452 | /** Resize a toolbar. |
1453 | * |
1454 | * @param gw Parent window |
1455 | * @param toolbar_height The height in pixels of the toolbar |
1456 | * @param padding The padding in pixels round each element of the toolbar |
1457 | * @param toolbar_layout A string defining which buttons and controls |
1458 | * should be added to the toolbar. May be empty |
1459 | * string to disable the bar. |
1460 | */ |
1461 | static void |
1462 | resize_toolbar(struct gui_window *gw, |
1463 | int toolbar_height, |
1464 | int padding, |
1465 | const char *toolbar_layout) |
1466 | { |
1467 | fbtk_widget_t *widget; |
1468 | |
1469 | int xpos; /* The position of the next widget. */ |
1470 | int xlhs = 0; /* extent of the left hand side widgets */ |
1471 | int xdir = 1; /* the direction of movement + or - 1 */ |
1472 | const char *itmtype; /* type of the next item */ |
1473 | int x = 0, y = 0, w = 0, h = 0; |
1474 | |
1475 | if (gw->toolbar == NULL((void*)0)) { |
1476 | return; |
1477 | } |
1478 | |
1479 | if (toolbar_layout == NULL((void*)0)) { |
1480 | toolbar_layout = NSFB_TOOLBAR_DEFAULT_LAYOUT"blfsrutc"; |
1481 | } |
1482 | |
1483 | itmtype = toolbar_layout; |
1484 | |
1485 | if (*itmtype == 0) { |
1486 | return; |
1487 | } |
1488 | |
1489 | fbtk_set_pos_and_size(gw->toolbar, 0, 0, 0, toolbar_height); |
1490 | |
1491 | xpos = padding; |
1492 | |
1493 | /* loop proceeds creating widget on the left hand side until |
1494 | * it runs out of layout or encounters a url bar declaration |
1495 | * wherupon it works backwards from the end of the layout |
1496 | * untill the space left is for the url bar |
1497 | */ |
1498 | while (itmtype >= toolbar_layout && xdir != 0) { |
1499 | |
1500 | switch (*itmtype) { |
1501 | case 'b': /* back */ |
1502 | widget = gw->back; |
1503 | x = (xdir == 1) ? xpos : xpos - left_arrow.width; |
1504 | y = padding; |
1505 | w = left_arrow.width; |
1506 | h = -padding; |
1507 | break; |
1508 | |
1509 | case 'l': /* local history */ |
1510 | widget = gw->history; |
1511 | x = (xdir == 1) ? xpos : xpos - history_image.width; |
1512 | y = padding; |
1513 | w = history_image.width; |
1514 | h = -padding; |
1515 | break; |
1516 | |
1517 | case 'f': /* forward */ |
1518 | widget = gw->forward; |
1519 | x = (xdir == 1) ? xpos : xpos - right_arrow.width; |
1520 | y = padding; |
1521 | w = right_arrow.width; |
1522 | h = -padding; |
1523 | break; |
1524 | |
1525 | case 'c': /* close the current window */ |
1526 | widget = gw->close; |
1527 | x = (xdir == 1) ? xpos : xpos - stop_image_g.width; |
1528 | y = padding; |
1529 | w = stop_image_g.width; |
1530 | h = -padding; |
1531 | break; |
1532 | |
1533 | case 's': /* stop */ |
1534 | widget = gw->stop; |
1535 | x = (xdir == 1) ? xpos : xpos - stop_image.width; |
1536 | y = padding; |
1537 | w = stop_image.width; |
1538 | h = -padding; |
1539 | break; |
1540 | |
1541 | case 'r': /* reload */ |
1542 | widget = gw->reload; |
1543 | x = (xdir == 1) ? xpos : xpos - reload.width; |
1544 | y = padding; |
1545 | w = reload.width; |
1546 | h = -padding; |
1547 | break; |
1548 | |
1549 | case 't': /* throbber/activity indicator */ |
1550 | widget = gw->throbber; |
1551 | x = (xdir == 1) ? xpos : xpos - throbber0.width; |
1552 | y = padding; |
1553 | w = throbber0.width; |
1554 | h = -padding; |
1555 | break; |
1556 | |
1557 | |
1558 | case 'u': /* url bar*/ |
1559 | if (xdir == -1) { |
1560 | /* met the u going backwards add url |
1561 | * now we know available extent |
1562 | */ |
1563 | widget = gw->url; |
1564 | x = xlhs; |
1565 | y = padding; |
1566 | w = xpos - xlhs; |
1567 | h = -padding; |
1568 | |
1569 | /* toolbar is complete */ |
1570 | xdir = 0; |
1571 | break; |
1572 | } |
1573 | /* met url going forwards, note position and |
1574 | * reverse direction |
1575 | */ |
1576 | itmtype = toolbar_layout + strlen(toolbar_layout); |
1577 | xdir = -1; |
1578 | xlhs = xpos; |
1579 | w = fbtk_get_width(gw->toolbar); |
1580 | xpos = 2 * w; |
1581 | widget = gw->toolbar; |
1582 | break; |
1583 | |
1584 | default: |
1585 | widget = NULL((void*)0); |
1586 | break; |
1587 | |
1588 | } |
1589 | |
1590 | if (widget != NULL((void*)0)) { |
1591 | if (widget != gw->toolbar) |
1592 | fbtk_set_pos_and_size(widget, x, y, w, h); |
1593 | xpos += xdir * (w + padding); |
1594 | } |
1595 | |
1596 | itmtype += xdir; |
1597 | } |
1598 | } |
1599 | |
1600 | /** Routine called when "stripped of focus" event occours for browser widget. |
1601 | * |
1602 | * @param widget The widget reciving "stripped of focus" event. |
1603 | * @param cbi The callback parameters. |
1604 | * @return The callback result. |
1605 | */ |
1606 | static int |
1607 | fb_browser_window_strip_focus(fbtk_widget_t *widget, fbtk_callback_info *cbi) |
1608 | { |
1609 | fbtk_set_caret(widget, false0, 0, 0, 0, NULL((void*)0)); |
1610 | |
1611 | return 0; |
1612 | } |
1613 | |
1614 | static void |
1615 | create_browser_widget(struct gui_window *gw, int toolbar_height, int furniture_width) |
1616 | { |
1617 | struct browser_widget_s *browser_widget; |
1618 | browser_widget = calloc(1, sizeof(struct browser_widget_s)); |
1619 | |
1620 | gw->browser = fbtk_create_user(gw->window, |
1621 | 0, |
1622 | toolbar_height, |
1623 | -furniture_width, |
1624 | -furniture_width, |
1625 | browser_widget); |
1626 | |
1627 | fbtk_set_handler(gw->browser, FBTK_CBT_REDRAW, fb_browser_window_redraw, gw); |
1628 | fbtk_set_handler(gw->browser, FBTK_CBT_DESTROY, fb_browser_window_destroy, gw); |
1629 | fbtk_set_handler(gw->browser, FBTK_CBT_INPUT, fb_browser_window_input, gw); |
1630 | fbtk_set_handler(gw->browser, FBTK_CBT_CLICK, fb_browser_window_click, gw); |
1631 | fbtk_set_handler(gw->browser, FBTK_CBT_STRIP_FOCUS, fb_browser_window_strip_focus, gw); |
1632 | fbtk_set_handler(gw->browser, FBTK_CBT_POINTERMOVE, fb_browser_window_move, gw); |
1633 | } |
1634 | |
1635 | static void |
1636 | resize_browser_widget(struct gui_window *gw, int x, int y, |
1637 | int width, int height) |
1638 | { |
1639 | fbtk_set_pos_and_size(gw->browser, x, y, width, height); |
1640 | browser_window_schedule_reformat(gw->bw); |
1641 | } |
1642 | |
1643 | static void |
1644 | create_normal_browser_window(struct gui_window *gw, int furniture_width) |
1645 | { |
1646 | fbtk_widget_t *widget; |
1647 | fbtk_widget_t *toolbar; |
1648 | int statusbar_width = 0; |
1649 | int toolbar_height = nsoption_int(fb_toolbar_size)(nsoptions[NSOPTION_fb_toolbar_size].value.i); |
1650 | |
1651 | NSLOG(netsurf, INFO, "Normal window")do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "frontends/framebuffer/gui.c", sizeof("frontends/framebuffer/gui.c" ) - 1, __PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__) - 1, 1651 , }; nslog__log(&_nslog_ctx, "Normal window"); } } while( 0); |
1652 | |
1653 | gw->window = fbtk_create_window(fbtk, 0, 0, 0, 0, 0); |
1654 | |
1655 | statusbar_width = nsoption_int(toolbar_status_size)(nsoptions[NSOPTION_toolbar_status_size].value.i) * |
1656 | fbtk_get_width(gw->window) / 10000; |
1657 | |
1658 | /* toolbar */ |
1659 | toolbar = create_toolbar(gw, |
1660 | toolbar_height, |
1661 | 2, |
1662 | FB_FRAME_COLOUR0xFFDDDDDD, |
1663 | nsoption_charp(fb_toolbar_layout)(nsoptions[NSOPTION_fb_toolbar_layout].value.s)); |
1664 | gw->toolbar = toolbar; |
1665 | |
1666 | /* set the actually created toolbar height */ |
1667 | if (toolbar != NULL((void*)0)) { |
1668 | toolbar_height = fbtk_get_height(toolbar); |
1669 | } else { |
1670 | toolbar_height = 0; |
1671 | } |
1672 | |
1673 | /* status bar */ |
1674 | gw->status = fbtk_create_text(gw->window, |
1675 | 0, |
1676 | fbtk_get_height(gw->window) - furniture_width, |
1677 | statusbar_width, furniture_width, |
1678 | FB_FRAME_COLOUR0xFFDDDDDD, FB_COLOUR_BLACK0xFF000000, |
1679 | false0); |
1680 | fbtk_set_handler(gw->status, FBTK_CBT_POINTERENTER, set_ptr_default_move, NULL((void*)0)); |
1681 | |
1682 | NSLOG(netsurf, INFO, "status bar %p at %d,%d", gw->status,do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "frontends/framebuffer/gui.c", sizeof("frontends/framebuffer/gui.c" ) - 1, __PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__) - 1, 1683 , }; nslog__log(&_nslog_ctx, "status bar %p at %d,%d", gw ->status, fbtk_get_absx(gw->status), fbtk_get_absy(gw-> status)); } } while(0) |
1683 | fbtk_get_absx(gw->status), fbtk_get_absy(gw->status))do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "frontends/framebuffer/gui.c", sizeof("frontends/framebuffer/gui.c" ) - 1, __PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__) - 1, 1683 , }; nslog__log(&_nslog_ctx, "status bar %p at %d,%d", gw ->status, fbtk_get_absx(gw->status), fbtk_get_absy(gw-> status)); } } while(0); |
1684 | |
1685 | /* create horizontal scrollbar */ |
1686 | gw->hscroll = fbtk_create_hscroll(gw->window, |
1687 | statusbar_width, |
1688 | fbtk_get_height(gw->window) - furniture_width, |
1689 | fbtk_get_width(gw->window) - statusbar_width - furniture_width, |
1690 | furniture_width, |
1691 | FB_SCROLL_COLOUR0xFFAAAAAA, |
1692 | FB_FRAME_COLOUR0xFFDDDDDD, |
1693 | fb_scroll_callback, |
1694 | gw); |
1695 | |
1696 | /* fill bottom right area */ |
1697 | |
1698 | if (nsoption_bool(fb_osk)(nsoptions[NSOPTION_fb_osk].value.b) == true1) { |
1699 | widget = fbtk_create_text_button(gw->window, |
Value stored to 'widget' is never read | |
1700 | fbtk_get_width(gw->window) - furniture_width, |
1701 | fbtk_get_height(gw->window) - furniture_width, |
1702 | furniture_width, |
1703 | furniture_width, |
1704 | FB_FRAME_COLOUR0xFFDDDDDD, FB_COLOUR_BLACK0xFF000000, |
1705 | fb_osk_click, |
1706 | NULL((void*)0)); |
1707 | widget = fbtk_create_button(gw->window, |
1708 | fbtk_get_width(gw->window) - furniture_width, |
1709 | fbtk_get_height(gw->window) - furniture_width, |
1710 | furniture_width, |
1711 | furniture_width, |
1712 | FB_FRAME_COLOUR0xFFDDDDDD, |
1713 | &osk_image, |
1714 | fb_osk_click, |
1715 | NULL((void*)0)); |
1716 | } else { |
1717 | widget = fbtk_create_fill(gw->window, |
1718 | fbtk_get_width(gw->window) - furniture_width, |
1719 | fbtk_get_height(gw->window) - furniture_width, |
1720 | furniture_width, |
1721 | furniture_width, |
1722 | FB_FRAME_COLOUR0xFFDDDDDD); |
1723 | |
1724 | fbtk_set_handler(widget, FBTK_CBT_POINTERENTER, set_ptr_default_move, NULL((void*)0)); |
1725 | } |
1726 | |
1727 | gw->bottom_right = widget; |
1728 | |
1729 | /* create vertical scrollbar */ |
1730 | gw->vscroll = fbtk_create_vscroll(gw->window, |
1731 | fbtk_get_width(gw->window) - furniture_width, |
1732 | toolbar_height, |
1733 | furniture_width, |
1734 | fbtk_get_height(gw->window) - toolbar_height - furniture_width, |
1735 | FB_SCROLL_COLOUR0xFFAAAAAA, |
1736 | FB_FRAME_COLOUR0xFFDDDDDD, |
1737 | fb_scroll_callback, |
1738 | gw); |
1739 | |
1740 | /* browser widget */ |
1741 | create_browser_widget(gw, toolbar_height, nsoption_int(fb_furniture_size)(nsoptions[NSOPTION_fb_furniture_size].value.i)); |
1742 | |
1743 | /* Give browser_window's user widget input focus */ |
1744 | fbtk_set_focus(gw->browser); |
1745 | } |
1746 | |
1747 | static void |
1748 | resize_normal_browser_window(struct gui_window *gw, int furniture_width) |
1749 | { |
1750 | bool_Bool resized; |
1751 | int width, height; |
1752 | int statusbar_width; |
1753 | int toolbar_height = fbtk_get_height(gw->toolbar); |
1754 | |
1755 | /* Resize the main window widget */ |
1756 | resized = fbtk_set_pos_and_size(gw->window, 0, 0, 0, 0); |
1757 | if (!resized) |
1758 | return; |
1759 | |
1760 | width = fbtk_get_width(gw->window); |
1761 | height = fbtk_get_height(gw->window); |
1762 | statusbar_width = nsoption_int(toolbar_status_size)(nsoptions[NSOPTION_toolbar_status_size].value.i) * width / 10000; |
1763 | |
1764 | resize_toolbar(gw, toolbar_height, 2, |
1765 | nsoption_charp(fb_toolbar_layout)(nsoptions[NSOPTION_fb_toolbar_layout].value.s)); |
1766 | fbtk_set_pos_and_size(gw->status, |
1767 | 0, height - furniture_width, |
1768 | statusbar_width, furniture_width); |
1769 | fbtk_reposition_hscroll(gw->hscroll, |
1770 | statusbar_width, height - furniture_width, |
1771 | width - statusbar_width - furniture_width, |
1772 | furniture_width); |
1773 | fbtk_set_pos_and_size(gw->bottom_right, |
1774 | width - furniture_width, height - furniture_width, |
1775 | furniture_width, furniture_width); |
1776 | fbtk_reposition_vscroll(gw->vscroll, |
1777 | width - furniture_width, |
1778 | toolbar_height, furniture_width, |
1779 | height - toolbar_height - furniture_width); |
1780 | resize_browser_widget(gw, |
1781 | 0, toolbar_height, |
1782 | width - furniture_width, |
1783 | height - furniture_width - toolbar_height); |
1784 | } |
1785 | |
1786 | static void gui_window_add_to_window_list(struct gui_window *gw) |
1787 | { |
1788 | gw->next = NULL((void*)0); |
1789 | gw->prev = NULL((void*)0); |
1790 | |
1791 | if (window_list == NULL((void*)0)) { |
1792 | window_list = gw; |
1793 | } else { |
1794 | window_list->prev = gw; |
1795 | gw->next = window_list; |
1796 | window_list = gw; |
1797 | } |
1798 | } |
1799 | |
1800 | static void gui_window_remove_from_window_list(struct gui_window *gw) |
1801 | { |
1802 | struct gui_window *list; |
1803 | |
1804 | for (list = window_list; list != NULL((void*)0); list = list->next) { |
1805 | if (list != gw) |
1806 | continue; |
1807 | |
1808 | if (list == window_list) { |
1809 | window_list = list->next; |
1810 | if (window_list != NULL((void*)0)) |
1811 | window_list->prev = NULL((void*)0); |
1812 | } else { |
1813 | list->prev->next = list->next; |
1814 | if (list->next != NULL((void*)0)) { |
1815 | list->next->prev = list->prev; |
1816 | } |
1817 | } |
1818 | break; |
1819 | } |
1820 | } |
1821 | |
1822 | |
1823 | static struct gui_window * |
1824 | gui_window_create(struct browser_window *bw, |
1825 | struct gui_window *existing, |
1826 | gui_window_create_flags flags) |
1827 | { |
1828 | struct gui_window *gw; |
1829 | |
1830 | gw = calloc(1, sizeof(struct gui_window)); |
1831 | |
1832 | if (gw == NULL((void*)0)) |
1833 | return NULL((void*)0); |
1834 | |
1835 | /* associate the gui window with the underlying browser window |
1836 | */ |
1837 | gw->bw = bw; |
1838 | |
1839 | create_normal_browser_window(gw, nsoption_int(fb_furniture_size)(nsoptions[NSOPTION_fb_furniture_size].value.i)); |
1840 | |
1841 | /* map and request redraw of gui window */ |
1842 | fbtk_set_mapping(gw->window, true1); |
1843 | |
1844 | /* Add it to the window list */ |
1845 | gui_window_add_to_window_list(gw); |
1846 | |
1847 | return gw; |
1848 | } |
1849 | |
1850 | static void |
1851 | gui_window_destroy(struct gui_window *gw) |
1852 | { |
1853 | gui_window_remove_from_window_list(gw); |
1854 | |
1855 | fbtk_destroy_widget(gw->window); |
1856 | |
1857 | free(gw); |
1858 | } |
1859 | |
1860 | |
1861 | /** |
1862 | * Invalidates an area of a framebuffer browser window |
1863 | * |
1864 | * \param g The netsurf window being invalidated. |
1865 | * \param rect area to redraw or NULL for the entire window area |
1866 | * \return NSERROR_OK on success or appropriate error code |
1867 | */ |
1868 | static nserror |
1869 | fb_window_invalidate_area(struct gui_window *g, const struct rect *rect) |
1870 | { |
1871 | struct browser_widget_s *bwidget = fbtk_get_userpw(g->browser); |
1872 | |
1873 | if (rect != NULL((void*)0)) { |
1874 | fb_queue_redraw(g->browser, |
1875 | rect->x0 - bwidget->scrollx, |
1876 | rect->y0 - bwidget->scrolly, |
1877 | rect->x1 - bwidget->scrollx, |
1878 | rect->y1 - bwidget->scrolly); |
1879 | } else { |
1880 | fb_queue_redraw(g->browser, |
1881 | 0, |
1882 | 0, |
1883 | fbtk_get_width(g->browser), |
1884 | fbtk_get_height(g->browser)); |
1885 | } |
1886 | return NSERROR_OK; |
1887 | } |
1888 | |
1889 | static bool_Bool |
1890 | gui_window_get_scroll(struct gui_window *g, int *sx, int *sy) |
1891 | { |
1892 | struct browser_widget_s *bwidget = fbtk_get_userpw(g->browser); |
1893 | |
1894 | *sx = bwidget->scrollx; |
1895 | *sy = bwidget->scrolly; |
1896 | |
1897 | return true1; |
1898 | } |
1899 | |
1900 | /** |
1901 | * Set the scroll position of a framebuffer browser window. |
1902 | * |
1903 | * Scrolls the viewport to ensure the specified rectangle of the |
1904 | * content is shown. The framebuffer implementation scrolls the contents so |
1905 | * the specified point in the content is at the top of the viewport. |
1906 | * |
1907 | * \param gw gui_window to scroll |
1908 | * \param rect The rectangle to ensure is shown. |
1909 | * \return NSERROR_OK on success or apropriate error code. |
1910 | */ |
1911 | static nserror |
1912 | gui_window_set_scroll(struct gui_window *gw, const struct rect *rect) |
1913 | { |
1914 | struct browser_widget_s *bwidget = fbtk_get_userpw(gw->browser); |
1915 | |
1916 | assert(bwidget)((bwidget) ? (void) (0) : __assert_fail ("bwidget", "frontends/framebuffer/gui.c" , 1916, __extension__ __PRETTY_FUNCTION__)); |
1917 | |
1918 | widget_scroll_x(gw, rect->x0, true1); |
1919 | widget_scroll_y(gw, rect->y0, true1); |
1920 | |
1921 | return NSERROR_OK; |
1922 | } |
1923 | |
1924 | |
1925 | /** |
1926 | * Find the current dimensions of a framebuffer browser window content area. |
1927 | * |
1928 | * \param gw The gui window to measure content area of. |
1929 | * \param width receives width of window |
1930 | * \param height receives height of window |
1931 | * \return NSERROR_OK on sucess and width and height updated. |
1932 | */ |
1933 | static nserror |
1934 | gui_window_get_dimensions(struct gui_window *gw, int *width, int *height) |
1935 | { |
1936 | *width = fbtk_get_width(gw->browser); |
1937 | *height = fbtk_get_height(gw->browser); |
1938 | |
1939 | return NSERROR_OK; |
1940 | } |
1941 | |
1942 | static void |
1943 | gui_window_update_extent(struct gui_window *gw) |
1944 | { |
1945 | int w, h; |
1946 | browser_window_get_extents(gw->bw, true1, &w, &h); |
1947 | |
1948 | fbtk_set_scroll_parameters(gw->hscroll, 0, w, |
1949 | fbtk_get_width(gw->browser), 100); |
1950 | |
1951 | fbtk_set_scroll_parameters(gw->vscroll, 0, h, |
1952 | fbtk_get_height(gw->browser), 100); |
1953 | } |
1954 | |
1955 | static void |
1956 | gui_window_set_status(struct gui_window *g, const char *text) |
1957 | { |
1958 | fbtk_set_text(g->status, text); |
1959 | } |
1960 | |
1961 | static void |
1962 | gui_window_set_pointer(struct gui_window *g, gui_pointer_shape shape) |
1963 | { |
1964 | switch (shape) { |
1965 | case GUI_POINTER_POINT: |
1966 | framebuffer_set_cursor(&hand_image); |
1967 | break; |
1968 | |
1969 | case GUI_POINTER_CARET: |
1970 | framebuffer_set_cursor(&caret_image); |
1971 | break; |
1972 | |
1973 | case GUI_POINTER_MENU: |
1974 | framebuffer_set_cursor(&menu_image); |
1975 | break; |
1976 | |
1977 | case GUI_POINTER_PROGRESS: |
1978 | framebuffer_set_cursor(&progress_image); |
1979 | break; |
1980 | |
1981 | case GUI_POINTER_MOVE: |
1982 | framebuffer_set_cursor(&move_image); |
1983 | break; |
1984 | |
1985 | default: |
1986 | framebuffer_set_cursor(&pointer_image); |
1987 | break; |
1988 | } |
1989 | } |
1990 | |
1991 | static nserror |
1992 | gui_window_set_url(struct gui_window *g, nsurl *url) |
1993 | { |
1994 | fbtk_set_text(g->url, nsurl_access(url)); |
1995 | return NSERROR_OK; |
1996 | } |
1997 | |
1998 | static void |
1999 | throbber_advance(void *pw) |
2000 | { |
2001 | struct gui_window *g = pw; |
2002 | struct fbtk_bitmap *image; |
2003 | |
2004 | switch (g->throbber_index) { |
2005 | case 0: |
2006 | image = &throbber1; |
2007 | g->throbber_index = 1; |
2008 | break; |
2009 | |
2010 | case 1: |
2011 | image = &throbber2; |
2012 | g->throbber_index = 2; |
2013 | break; |
2014 | |
2015 | case 2: |
2016 | image = &throbber3; |
2017 | g->throbber_index = 3; |
2018 | break; |
2019 | |
2020 | case 3: |
2021 | image = &throbber4; |
2022 | g->throbber_index = 4; |
2023 | break; |
2024 | |
2025 | case 4: |
2026 | image = &throbber5; |
2027 | g->throbber_index = 5; |
2028 | break; |
2029 | |
2030 | case 5: |
2031 | image = &throbber6; |
2032 | g->throbber_index = 6; |
2033 | break; |
2034 | |
2035 | case 6: |
2036 | image = &throbber7; |
2037 | g->throbber_index = 7; |
2038 | break; |
2039 | |
2040 | case 7: |
2041 | image = &throbber8; |
2042 | g->throbber_index = 0; |
2043 | break; |
2044 | |
2045 | default: |
2046 | return; |
2047 | } |
2048 | |
2049 | if (g->throbber_index >= 0) { |
2050 | fbtk_set_bitmap(g->throbber, image); |
2051 | framebuffer_schedule(100, throbber_advance, g); |
2052 | } |
2053 | } |
2054 | |
2055 | static void |
2056 | gui_window_start_throbber(struct gui_window *g) |
2057 | { |
2058 | g->throbber_index = 0; |
2059 | framebuffer_schedule(100, throbber_advance, g); |
2060 | } |
2061 | |
2062 | static void |
2063 | gui_window_stop_throbber(struct gui_window *gw) |
2064 | { |
2065 | gw->throbber_index = -1; |
2066 | fbtk_set_bitmap(gw->throbber, &throbber0); |
2067 | |
2068 | fb_update_back_forward(gw); |
2069 | |
2070 | } |
2071 | |
2072 | static void |
2073 | gui_window_remove_caret_cb(fbtk_widget_t *widget) |
2074 | { |
2075 | struct browser_widget_s *bwidget = fbtk_get_userpw(widget); |
2076 | int c_x, c_y, c_h; |
2077 | |
2078 | if (fbtk_get_caret(widget, &c_x, &c_y, &c_h)) { |
2079 | /* browser window already had caret: |
2080 | * redraw its area to remove it first */ |
2081 | fb_queue_redraw(widget, |
2082 | c_x - bwidget->scrollx, |
2083 | c_y - bwidget->scrolly, |
2084 | c_x + 1 - bwidget->scrollx, |
2085 | c_y + c_h - bwidget->scrolly); |
2086 | } |
2087 | } |
2088 | |
2089 | static void |
2090 | gui_window_place_caret(struct gui_window *g, int x, int y, int height, |
2091 | const struct rect *clip) |
2092 | { |
2093 | struct browser_widget_s *bwidget = fbtk_get_userpw(g->browser); |
2094 | |
2095 | /* set new pos */ |
2096 | fbtk_set_caret(g->browser, true1, x, y, height, |
2097 | gui_window_remove_caret_cb); |
2098 | |
2099 | /* redraw new caret pos */ |
2100 | fb_queue_redraw(g->browser, |
2101 | x - bwidget->scrollx, |
2102 | y - bwidget->scrolly, |
2103 | x + 1 - bwidget->scrollx, |
2104 | y + height - bwidget->scrolly); |
2105 | } |
2106 | |
2107 | static void |
2108 | gui_window_remove_caret(struct gui_window *g) |
2109 | { |
2110 | int c_x, c_y, c_h; |
2111 | |
2112 | if (fbtk_get_caret(g->browser, &c_x, &c_y, &c_h)) { |
2113 | /* browser window owns the caret, so can remove it */ |
2114 | fbtk_set_caret(g->browser, false0, 0, 0, 0, NULL((void*)0)); |
2115 | } |
2116 | } |
2117 | |
2118 | /** |
2119 | * process miscellaneous window events |
2120 | * |
2121 | * \param gw The window receiving the event. |
2122 | * \param event The event code. |
2123 | * \return NSERROR_OK when processed ok |
2124 | */ |
2125 | static nserror |
2126 | gui_window_event(struct gui_window *gw, enum gui_window_event event) |
2127 | { |
2128 | switch (event) { |
2129 | case GW_EVENT_UPDATE_EXTENT: |
2130 | gui_window_update_extent(gw); |
2131 | break; |
2132 | |
2133 | case GW_EVENT_REMOVE_CARET: |
2134 | gui_window_remove_caret(gw); |
2135 | break; |
2136 | |
2137 | case GW_EVENT_START_THROBBER: |
2138 | gui_window_start_throbber(gw); |
2139 | break; |
2140 | |
2141 | case GW_EVENT_STOP_THROBBER: |
2142 | gui_window_stop_throbber(gw); |
2143 | break; |
2144 | |
2145 | default: |
2146 | break; |
2147 | } |
2148 | return NSERROR_OK; |
2149 | } |
2150 | |
2151 | static struct gui_window_table framebuffer_window_table = { |
2152 | .create = gui_window_create, |
2153 | .destroy = gui_window_destroy, |
2154 | .invalidate = fb_window_invalidate_area, |
2155 | .get_scroll = gui_window_get_scroll, |
2156 | .set_scroll = gui_window_set_scroll, |
2157 | .get_dimensions = gui_window_get_dimensions, |
2158 | .event = gui_window_event, |
2159 | |
2160 | .set_url = gui_window_set_url, |
2161 | .set_status = gui_window_set_status, |
2162 | .set_pointer = gui_window_set_pointer, |
2163 | .place_caret = gui_window_place_caret, |
2164 | }; |
2165 | |
2166 | |
2167 | static struct gui_misc_table framebuffer_misc_table = { |
2168 | .schedule = framebuffer_schedule, |
2169 | |
2170 | .quit = gui_quit, |
2171 | }; |
2172 | |
2173 | /** |
2174 | * Entry point from OS. |
2175 | * |
2176 | * /param argc The number of arguments in the string vector. |
2177 | * /param argv The argument string vector. |
2178 | * /return The return code to the OS |
2179 | */ |
2180 | int |
2181 | main(int argc, char** argv) |
2182 | { |
2183 | struct browser_window *bw; |
2184 | char *options; |
2185 | char *messages; |
2186 | nsurl *url; |
2187 | nserror ret; |
2188 | nsfb_t *nsfb; |
2189 | struct netsurf_table framebuffer_table = { |
2190 | .misc = &framebuffer_misc_table, |
2191 | .window = &framebuffer_window_table, |
2192 | .corewindow = framebuffer_core_window_table, |
2193 | .clipboard = framebuffer_clipboard_table, |
2194 | .fetch = framebuffer_fetch_table, |
2195 | .utf8 = framebuffer_utf8_table, |
2196 | .bitmap = framebuffer_bitmap_table, |
2197 | .layout = framebuffer_layout_table, |
2198 | }; |
2199 | |
2200 | ret = netsurf_register(&framebuffer_table); |
2201 | if (ret != NSERROR_OK) { |
2202 | die("NetSurf operation table failed registration"); |
2203 | } |
2204 | |
2205 | respaths = fb_init_resource_path(NETSURF_FB_RESPATH"${HOME}/.netsurf/:${NETSURFRES}:/var/lib/jenkins/artifacts-x86_64-linux-gnu/share/netsurf:./frontends/framebuffer/res"":"NETSURF_FB_FONTPATH"/usr/share/fonts/truetype/dejavu:/usr/share/fonts/truetype/msttcorefonts"); |
2206 | |
2207 | /* initialise logging. Not fatal if it fails but not much we |
2208 | * can do about it either. |
2209 | */ |
2210 | nslog_init(nslog_stream_configure, &argc, argv); |
2211 | |
2212 | /* user options setup */ |
2213 | ret = nsoption_init(set_defaults, &nsoptions, &nsoptions_default); |
2214 | if (ret != NSERROR_OK) { |
2215 | die("Options failed to initialise"); |
2216 | } |
2217 | options = filepath_find(respaths, "Choices"); |
2218 | nsoption_read(options, nsoptions); |
2219 | free(options); |
2220 | nsoption_commandline(&argc, argv, nsoptions); |
2221 | |
2222 | /* message init */ |
2223 | messages = filepath_find(respaths, "Messages"); |
2224 | ret = messages_add_from_file(messages); |
2225 | free(messages); |
2226 | if (ret != NSERROR_OK) { |
2227 | fprintf(stderrstderr, "Message translations failed to load\n"); |
2228 | } |
2229 | |
2230 | /* common initialisation */ |
2231 | ret = netsurf_init(NULL((void*)0)); |
2232 | if (ret != NSERROR_OK) { |
2233 | die("NetSurf failed to initialise"); |
2234 | } |
2235 | |
2236 | /* Override, since we have no support for non-core SELECT menu */ |
2237 | nsoption_set_bool(core_select_menu, true)nsoptions[NSOPTION_core_select_menu].value.b = 1; |
2238 | |
2239 | if (process_cmdline(argc,argv) != true1) |
2240 | die("unable to process command line.\n"); |
2241 | |
2242 | nsfb = framebuffer_initialise(fename, fewidth, feheight, febpp); |
2243 | if (nsfb == NULL((void*)0)) |
2244 | die("Unable to initialise framebuffer"); |
2245 | |
2246 | framebuffer_set_cursor(&pointer_image); |
2247 | |
2248 | if (fb_font_init() == false0) |
2249 | die("Unable to initialise the font system"); |
2250 | |
2251 | fbtk = fbtk_init(nsfb); |
2252 | |
2253 | fbtk_enable_oskb(fbtk); |
2254 | |
2255 | urldb_load_cookies(nsoption_charp(cookie_file)(nsoptions[NSOPTION_cookie_file].value.s)); |
2256 | |
2257 | /* create an initial browser window */ |
2258 | |
2259 | NSLOG(netsurf, INFO, "calling browser_window_create")do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "frontends/framebuffer/gui.c", sizeof("frontends/framebuffer/gui.c" ) - 1, __PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__) - 1, 2259 , }; nslog__log(&_nslog_ctx, "calling browser_window_create" ); } } while(0); |
2260 | |
2261 | ret = nsurl_create(feurl, &url); |
2262 | if (ret == NSERROR_OK) { |
2263 | ret = browser_window_create(BW_CREATE_HISTORY, |
2264 | url, |
2265 | NULL((void*)0), |
2266 | NULL((void*)0), |
2267 | &bw); |
2268 | nsurl_unref(url); |
2269 | } |
2270 | if (ret != NSERROR_OK) { |
2271 | fb_warn_user("Errorcode:", messages_get_errorcode(ret)); |
2272 | } else { |
2273 | framebuffer_run(); |
2274 | |
2275 | browser_window_destroy(bw); |
2276 | } |
2277 | |
2278 | netsurf_exit(); |
2279 | |
2280 | if (fb_font_finalise() == false0) |
2281 | NSLOG(netsurf, INFO, "Font finalisation failed.")do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "frontends/framebuffer/gui.c", sizeof("frontends/framebuffer/gui.c" ) - 1, __PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__) - 1, 2281 , }; nslog__log(&_nslog_ctx, "Font finalisation failed.") ; } } while(0); |
2282 | |
2283 | /* finalise options */ |
2284 | nsoption_finalise(nsoptions, nsoptions_default); |
2285 | |
2286 | /* finalise logging */ |
2287 | nslog_finalise(); |
2288 | |
2289 | return 0; |
2290 | } |
2291 | |
2292 | void gui_resize(fbtk_widget_t *root, int width, int height) |
2293 | { |
2294 | struct gui_window *gw; |
2295 | nsfb_t *nsfb = fbtk_get_nsfb(root); |
2296 | |
2297 | /* Enforce a minimum */ |
2298 | if (width < 300) |
2299 | width = 300; |
2300 | if (height < 200) |
2301 | height = 200; |
2302 | |
2303 | if (framebuffer_resize(nsfb, width, height, febpp) == false0) { |
2304 | return; |
2305 | } |
2306 | |
2307 | fbtk_set_pos_and_size(root, 0, 0, width, height); |
2308 | |
2309 | fewidth = width; |
2310 | feheight = height; |
2311 | |
2312 | for (gw = window_list; gw != NULL((void*)0); gw = gw->next) { |
2313 | resize_normal_browser_window(gw, |
2314 | nsoption_int(fb_furniture_size)(nsoptions[NSOPTION_fb_furniture_size].value.i)); |
2315 | } |
2316 | |
2317 | fbtk_request_redraw(root); |
2318 | } |
2319 | |
2320 | |
2321 | /* |
2322 | * Local Variables: |
2323 | * c-basic-offset:8 |
2324 | * End: |
2325 | */ |