Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3584 sourcerer 1
/*
2
 * Copyright 2008 Vincent Sanders 
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 .
17
 */
18
 
19
#include 
20
#include 
21
#include 
22
#include 
23
#include 
24
#include 
25
#include 
26
#include 
27
#include 
28
#include 
29
 
30
#include 
31
#include 
32
#include 
33
 
34
#include "desktop/browser_private.h"
35
#include "desktop/gui.h"
36
#include "desktop/mouse.h"
37
#include "desktop/plotters.h"
38
#include "desktop/netsurf.h"
39
#include "desktop/options.h"
40
#include "utils/filepath.h"
41
#include "utils/log.h"
42
#include "utils/messages.h"
43
#include "utils/schedule.h"
44
#include "utils/types.h"
45
#include "utils/url.h"
46
#include "utils/utils.h"
47
#include "desktop/textinput.h"
48
#include "render/form.h"
49
 
50
#include "framebuffer/gui.h"
51
#include "framebuffer/fbtk.h"
52
#include "framebuffer/framebuffer.h"
53
#include "framebuffer/schedule.h"
54
#include "framebuffer/findfile.h"
55
#include "framebuffer/image_data.h"
56
#include "framebuffer/font.h"
57
 
58
 
59
 
60
 
61
#include "content/urldb.h"
62
#include "desktop/history_core.h"
63
#include "content/fetch.h"
64
 
65
#define NSFB_TOOLBAR_DEFAULT_LAYOUT "blfsrut"
66
 
67
fbtk_widget_t *fbtk;
68
 
69
struct gui_window *input_window = NULL;
70
struct gui_window *search_current_window;
71
struct gui_window *window_list = NULL;
72
 
73
/* private data for browser user widget */
74
struct browser_widget_s {
75
	struct browser_window *bw; /**< The browser window connected to this gui window */
76
	int scrollx, scrolly; /**< scroll offsets. */
77
 
78
	/* Pending window redraw state. */
79
	bool redraw_required; /**< flag indicating the foreground loop
80
			       * needs to redraw the browser widget.
81
			       */
82
	bbox_t redraw_box; /**< Area requiring redraw. */
83
	bool pan_required; /**< flag indicating the foreground loop
84
			    * needs to pan the window.
85
			    */
86
	int panx, pany; /**< Panning required. */
87
};
88
 
89
static struct gui_drag {
90
	enum state {
91
		GUI_DRAG_NONE,
92
		GUI_DRAG_PRESSED,
93
		GUI_DRAG_DRAG
94
	} state;
95
	int button;
96
	int x;
97
	int y;
98
	bool grabbed_pointer;
99
} gui_drag;
100
 
101
 
102
/* queue a redraw operation, co-ordinates are relative to the window */
103
static void
104
fb_queue_redraw(struct fbtk_widget_s *widget, int x0, int y0, int x1, int y1)
105
{
106
	struct browser_widget_s *bwidget = fbtk_get_userpw(widget);
107
 
108
	bwidget->redraw_box.x0 = min(bwidget->redraw_box.x0, x0);
109
	bwidget->redraw_box.y0 = min(bwidget->redraw_box.y0, y0);
110
	bwidget->redraw_box.x1 = max(bwidget->redraw_box.x1, x1);
111
	bwidget->redraw_box.y1 = max(bwidget->redraw_box.y1, y1);
112
 
113
	if (fbtk_clip_to_widget(widget, &bwidget->redraw_box)) {
114
		bwidget->redraw_required = true;
115
		fbtk_request_redraw(widget);
116
	} else {
117
		bwidget->redraw_box.y0 = bwidget->redraw_box.x0 = INT_MAX;
118
		bwidget->redraw_box.y1 = bwidget->redraw_box.x1 = -(INT_MAX);
119
		bwidget->redraw_required = false;
120
	}
121
}
122
 
123
/* queue a window scroll */
124
static void
125
widget_scroll_y(struct gui_window *gw, int y, bool abs)
126
{
127
	struct browser_widget_s *bwidget = fbtk_get_userpw(gw->browser);
128
	int content_height;
129
	int height;
130
	float scale = gw->bw->scale;
131
 
132
	LOG(("window scroll"));
133
	if (abs) {
134
		bwidget->pany = y - bwidget->scrolly;
135
	} else {
136
		bwidget->pany += y;
137
	}
138
 
139
	content_height = content_get_height(gw->bw->current_content) * scale;
140
 
141
	height = fbtk_get_height(gw->browser);
142
 
143
	/* dont pan off the top */
144
	if ((bwidget->scrolly + bwidget->pany) < 0)
145
		bwidget->pany = -bwidget->scrolly;
146
 
147
	/* do not pan off the bottom of the content */
148
	if ((bwidget->scrolly + bwidget->pany) > (content_height - height))
149
		bwidget->pany = (content_height - height) - bwidget->scrolly;
150
 
151
	if (bwidget->pany == 0)
152
		return;
153
 
154
	bwidget->pan_required = true;
155
 
156
	fbtk_request_redraw(gw->browser);
157
 
158
	fbtk_set_scroll_position(gw->vscroll, bwidget->scrolly + bwidget->pany);
159
}
160
 
161
/* queue a window scroll */
162
static void
163
widget_scroll_x(struct gui_window *gw, int x, bool abs)
164
{
165
	struct browser_widget_s *bwidget = fbtk_get_userpw(gw->browser);
166
	int content_width;
167
	int width;
168
	float scale = gw->bw->scale;
169
 
170
	if (abs) {
171
		bwidget->panx = x - bwidget->scrollx;
172
	} else {
173
		bwidget->panx += x;
174
	}
175
 
176
	content_width = content_get_width(gw->bw->current_content) * scale;
177
 
178
	width = fbtk_get_width(gw->browser);
179
 
180
	/* dont pan off the left */
181
	if ((bwidget->scrollx + bwidget->panx) < 0)
182
		bwidget->panx = - bwidget->scrollx;
183
 
184
	/* do not pan off the right of the content */
185
	if ((bwidget->scrollx + bwidget->panx) > (content_width - width))
186
		bwidget->panx = (content_width - width) - bwidget->scrollx;
187
 
188
	if (bwidget->panx == 0)
189
		return;
190
 
191
	bwidget->pan_required = true;
192
 
193
	fbtk_request_redraw(gw->browser);
194
 
195
	fbtk_set_scroll_position(gw->hscroll, bwidget->scrollx + bwidget->panx);
196
}
197
 
198
static void
199
fb_pan(fbtk_widget_t *widget,
200
       struct browser_widget_s *bwidget,
201
       struct browser_window *bw)
202
{
203
	int x;
204
	int y;
205
	int width;
206
	int height;
207
	nsfb_bbox_t srcbox;
208
	nsfb_bbox_t dstbox;
209
 
210
	nsfb_t *nsfb = fbtk_get_nsfb(widget);
211
 
212
	height = fbtk_get_height(widget);
213
	width = fbtk_get_width(widget);
214
 
215
	LOG(("panning %d, %d", bwidget->panx, bwidget->pany));
216
 
217
	x = fbtk_get_absx(widget);
218
	y = fbtk_get_absy(widget);
219
 
220
	/* if the pan exceeds the viewport size just redraw the whole area */
221
	if (bwidget->pany >= height || bwidget->pany <= -height ||
222
	    bwidget->panx >= width || bwidget->panx <= -width) {
223
 
224
		bwidget->scrolly += bwidget->pany;
225
		bwidget->scrollx += bwidget->panx;
226
		fb_queue_redraw(widget, 0, 0, width, height);
227
 
228
		/* ensure we don't try to scroll again */
229
		bwidget->panx = 0;
230
		bwidget->pany = 0;
231
		bwidget->pan_required = false;
232
		return;
233
	}
234
 
235
	if (bwidget->pany < 0) {
236
		/* pan up by less then viewport height */
237
		srcbox.x0 = x;
238
		srcbox.y0 = y;
239
		srcbox.x1 = srcbox.x0 + width;
240
		srcbox.y1 = srcbox.y0 + height + bwidget->pany;
241
 
242
		dstbox.x0 = x;
243
		dstbox.y0 = y - bwidget->pany;
244
		dstbox.x1 = dstbox.x0 + width;
245
		dstbox.y1 = dstbox.y0 + height + bwidget->pany;
246
 
247
		/* move part that remains visible up */
248
		nsfb_plot_copy(nsfb, &srcbox, nsfb, &dstbox);
249
 
250
		/* redraw newly exposed area */
251
		bwidget->scrolly += bwidget->pany;
252
		fb_queue_redraw(widget, 0, 0, width, - bwidget->pany);
253
 
254
	} else if (bwidget->pany > 0) {
255
		/* pan down by less then viewport height */
256
		srcbox.x0 = x;
257
		srcbox.y0 = y + bwidget->pany;
258
		srcbox.x1 = srcbox.x0 + width;
259
		srcbox.y1 = srcbox.y0 + height - bwidget->pany;
260
 
261
		dstbox.x0 = x;
262
		dstbox.y0 = y;
263
		dstbox.x1 = dstbox.x0 + width;
264
		dstbox.y1 = dstbox.y0 + height - bwidget->pany;
265
 
266
		/* move part that remains visible down */
267
		nsfb_plot_copy(nsfb, &srcbox, nsfb, &dstbox);
268
 
269
		/* redraw newly exposed area */
270
		bwidget->scrolly += bwidget->pany;
271
		fb_queue_redraw(widget, 0, height - bwidget->pany,
272
				width, height);
273
	}
274
 
275
	if (bwidget->panx < 0) {
276
		/* pan left by less then viewport width */
277
		srcbox.x0 = x;
278
		srcbox.y0 = y;
279
		srcbox.x1 = srcbox.x0 + width + bwidget->panx;
280
		srcbox.y1 = srcbox.y0 + height;
281
 
282
		dstbox.x0 = x - bwidget->panx;
283
		dstbox.y0 = y;
284
		dstbox.x1 = dstbox.x0 + width + bwidget->panx;
285
		dstbox.y1 = dstbox.y0 + height;
286
 
287
		/* move part that remains visible left */
288
		nsfb_plot_copy(nsfb, &srcbox, nsfb, &dstbox);
289
 
290
		/* redraw newly exposed area */
291
		bwidget->scrollx += bwidget->panx;
292
		fb_queue_redraw(widget, 0, 0, -bwidget->panx, height);
293
 
294
	} else if (bwidget->panx > 0) {
295
		/* pan right by less then viewport width */
296
		srcbox.x0 = x + bwidget->panx;
297
		srcbox.y0 = y;
298
		srcbox.x1 = srcbox.x0 + width - bwidget->panx;
299
		srcbox.y1 = srcbox.y0 + height;
300
 
301
		dstbox.x0 = x;
302
		dstbox.y0 = y;
303
		dstbox.x1 = dstbox.x0 + width - bwidget->panx;
304
		dstbox.y1 = dstbox.y0 + height;
305
 
306
		/* move part that remains visible right */
307
		nsfb_plot_copy(nsfb, &srcbox, nsfb, &dstbox);
308
 
309
		/* redraw newly exposed area */
310
		bwidget->scrollx += bwidget->panx;
311
		fb_queue_redraw(widget, width - bwidget->panx, 0,
312
				width, height);
313
	}
314
 
315
	bwidget->pan_required = false;
316
	bwidget->panx = 0;
317
	bwidget->pany = 0;
318
}
319
 
320
static void
321
fb_redraw(fbtk_widget_t *widget,
322
	  struct browser_widget_s *bwidget,
323
	  struct browser_window *bw)
324
{
325
	int x;
326
	int y;
327
	int caret_x, caret_y, caret_h;
328
	struct rect clip;
329
	struct redraw_context ctx = {
330
		.interactive = true,
331
		.background_images = true,
332
		.plot = &fb_plotters
333
	};
334
	nsfb_t *nsfb = fbtk_get_nsfb(widget);
335
 
336
	LOG(("%d,%d to %d,%d",
337
	     bwidget->redraw_box.x0,
338
	     bwidget->redraw_box.y0,
339
	     bwidget->redraw_box.x1,
340
	     bwidget->redraw_box.y1));
341
 
342
	x = fbtk_get_absx(widget);
343
	y = fbtk_get_absy(widget);
344
 
345
	/* adjust clipping co-ordinates according to window location */
346
	bwidget->redraw_box.y0 += y;
347
	bwidget->redraw_box.y1 += y;
348
	bwidget->redraw_box.x0 += x;
349
	bwidget->redraw_box.x1 += x;
350
 
351
	nsfb_claim(nsfb, &bwidget->redraw_box);
352
 
353
	/* redraw bounding box is relative to window */
354
	clip.x0 = bwidget->redraw_box.x0;
355
	clip.y0 = bwidget->redraw_box.y0;
356
	clip.x1 = bwidget->redraw_box.x1;
357
	clip.y1 = bwidget->redraw_box.y1;
358
 
359
	browser_window_redraw(bw,
360
			(x - bwidget->scrollx) / bw->scale,
361
			(y - bwidget->scrolly) / bw->scale,
362
			&clip, &ctx);
363
 
364
	if (fbtk_get_caret(widget, &caret_x, &caret_y, &caret_h)) {
365
		/* This widget has caret, so render it */
366
		nsfb_bbox_t line;
367
		nsfb_plot_pen_t pen;
368
 
369
		line.x0 = x - bwidget->scrollx + caret_x;
370
		line.y0 = y - bwidget->scrolly + caret_y;
371
		line.x1 = x - bwidget->scrollx + caret_x;
372
		line.y1 = y - bwidget->scrolly + caret_y + caret_h;
373
 
374
		pen.stroke_type = NFSB_PLOT_OPTYPE_SOLID;
375
		pen.stroke_width = 1;
376
		pen.stroke_colour = 0xFF0000FF;
377
 
378
		nsfb_plot_line(nsfb, &line, &pen);
379
	}
380
	///STUB???
381
	nsfb_update(fbtk_get_nsfb(widget), &bwidget->redraw_box);
382
 
383
	bwidget->redraw_box.y0 = bwidget->redraw_box.x0 = INT_MAX;
384
	bwidget->redraw_box.y1 = bwidget->redraw_box.x1 = INT_MIN;
385
	bwidget->redraw_required = false;
386
}
387
 
388
static int
389
fb_browser_window_redraw(fbtk_widget_t *widget, fbtk_callback_info *cbi)
390
{
391
	struct gui_window *gw = cbi->context;
392
	struct browser_widget_s *bwidget;
393
 
394
	bwidget = fbtk_get_userpw(widget);
395
	if (bwidget == NULL) {
396
		LOG(("browser widget from widget %p was null", widget));
397
		return -1;
398
	}
399
 
400
	if (bwidget->pan_required) {
401
		fb_pan(widget, bwidget, gw->bw);
402
	}
403
 
404
	if (bwidget->redraw_required) {
405
		fb_redraw(widget, bwidget, gw->bw);
406
	} else {
407
		bwidget->redraw_box.x0 = 0;
408
		bwidget->redraw_box.y0 = 0;
409
		bwidget->redraw_box.x1 = fbtk_get_width(widget);
410
		bwidget->redraw_box.y1 = fbtk_get_height(widget);
411
		fb_redraw(widget, bwidget, gw->bw);
412
	}
413
	return 0;
414
}
415
 
416
 
417
static const char *fename;
418
static int febpp;
419
static int fewidth;
420
static int feheight;
421
static const char *feurl;
422
 
423
static bool
424
process_cmdline(int argc, char** argv)
425
{
426
	int opt;
427
 
428
	LOG(("argc %d, argv %p", argc, argv));
429
 
430
	fename = "sdl";
431
	febpp = 16;
432
 
433
	if ((nsoption_int(window_width) != 0) &&
434
	    (nsoption_int(window_height) != 0)) {
435
		fewidth = nsoption_int(window_width);
436
		feheight = nsoption_int(window_height);
437
	} else {
438
		fewidth = 800; //640;
439
		feheight = 560; //400;
440
	}
441
 
442
	if ((nsoption_charp(homepage_url) != NULL) &&
443
	    (nsoption_charp(homepage_url)[0] != '\0')) {
444
		feurl = nsoption_charp(homepage_url);
445
	} else {
446
		feurl = "about:about";
447
	}
448
 
449
	while((opt = getopt(argc, argv, "f:b:w:h:")) != -1) {
450
		switch (opt) {
451
		case 'f':
452
			fename = optarg;
453
			break;
454
 
455
		case 'b':
456
			febpp = atoi(optarg);
457
			break;
458
 
459
		case 'w':
460
			fewidth = atoi(optarg);
461
			break;
462
 
463
		case 'h':
464
			feheight = atoi(optarg);
465
			break;
466
 
467
		default:
468
			fprintf(stderr,
469
				"Usage: %s [-f frontend] [-b bpp] url\n",
470
				argv[0]);
471
			return false;
472
		}
473
	}
474
 
475
	if (optind < argc) {
476
		feurl = argv[optind];
477
	}
478
 
479
	return true;
480
}
481
 
482
/* Documented in desktop/options.h */
483
void gui_options_init_defaults(void)
484
{
485
	/* Set defaults for absent option strings */
486
	nsoption_setnull_charp(cookie_file, strdup("~/.netsurf/Cookies"));
487
	nsoption_setnull_charp(cookie_jar, strdup("~/.netsurf/Cookies"));
488
 
489
	if (nsoption_charp(cookie_file) == NULL ||
490
			nsoption_charp(cookie_jar == NULL)) {
491
		die("Failed initialising cookie options");
492
	}
493
}
494
 
495
static void
496
gui_init(int argc, char** argv)
497
{
498
	nsfb_t *nsfb;
499
 
500
	/* Override, since we have no support for non-core SELECT menu */
501
	nsoption_set_bool(core_select_menu, true);
502
 
503
	if (process_cmdline(argc,argv) != true)
504
		die("unable to process command line.\n");
505
 
506
	nsfb = framebuffer_initialise(fename, fewidth, feheight, febpp);
507
	if (nsfb == NULL)
508
		die("Unable to initialise framebuffer");
509
 
510
	framebuffer_set_cursor(&pointer_image);
511
 
512
	if (fb_font_init() == false)
513
		die("Unable to initialise the font system");
514
 
515
	fbtk = fbtk_init(nsfb);
516
 
517
	fbtk_enable_oskb(fbtk);
518
 
519
	urldb_load_cookies(nsoption_charp(cookie_file));
520
}
521
 
522
/** Entry point from OS.
523
 *
524
 * /param argc The number of arguments in the string vector.
525
 * /param argv The argument string vector.
526
 * /return The return code to the OS
527
 */
528
 
529
#include 
530
 
531
int
532
main(int argc, char** argv)
533
{
534
	struct browser_window *bw;
535
	char *options;
536
	char *messages;
537
 
538
	setbuf(stderr, NULL);
539
 
540
	freopen( "stderr.log", "w", stderr );
541
	freopen( "stdout.log", "w", stdout );
542
 
543
 
544
	LOG(("Registering surfaces for SDL and RAM.."));
545
 
546
	extern nsfb_surface_rtns_t sdl_rtns;
547
	extern nsfb_surface_rtns_t ram_rtns;
548
	extern nsfb_surface_rtns_t able_rtns;
549
 
550
	_nsfb_register_surface(NSFB_SURFACE_SDL, &sdl_rtns, "sdl");
551
	_nsfb_register_surface(NSFB_SURFACE_RAM, &ram_rtns, "ram");
552
	_nsfb_register_surface(NSFB_SURFACE_RAM, &able_rtns, "able");
553
 
554
	respaths = fb_init_resource("/tmp9/1/netsurf/res/:res/:fonts/");
555
 
556
	options = filepath_find(respaths, "Choices");
557
	messages = filepath_find(respaths, "messages");
558
 
559
	netsurf_init(&argc, &argv, options, "res/messages");
560
 
561
	LOG(("NS init okay"));
562
 
563
	free(messages);
564
	free(options);
565
 
566
	LOG(("freed opts and msgs, start gui init"));
567
 
568
 
569
	gui_init(argc, argv);
570
 
571
	LOG(("calling browser_window_create in MAIN()"));
572
	bw = browser_window_create(feurl, 0, 0, true, false);
573
 
574
 
575
	LOG(("NS main loop..."));
576
 
577
	netsurf_main_loop();
578
 
579
	browser_window_destroy(bw);
580
 
581
	netsurf_exit();
582
 
583
	return 0;
584
}
585
 
586
 
587
void
588
gui_poll(bool active)
589
{
590
	LOG(("GUI poll in"));
591
 
592
	nsfb_event_t event;
593
	int timeout; /* timeout in miliseconds */
594
 
595
LOG(("schedule run"));
596
	/* run the scheduler and discover how long to wait for the next event */
597
	timeout = schedule_run();
598
 
599
	/* if active do not wait for event, return immediately */
600
	if (active)
601
		timeout = 0;
602
 
603
LOG(("redraw pending"));
604
	/* if redraws are pending do not wait for event, return immediately */
605
	if (fbtk_get_redraw_pending(fbtk))
606
		timeout = 0;
607
 
608
LOG(("fbtk event"));
609
	if (fbtk_event(fbtk, &event, timeout)) {
610
		if ((event.type == NSFB_EVENT_CONTROL) &&
611
		    (event.value.controlcode ==  NSFB_CONTROL_QUIT))
612
			netsurf_quit = true;
613
	}
614
 
615
LOG(("fbtk redraw"));
616
	fbtk_redraw(fbtk);
617
 
618
LOG(("GUI poll out success"));
619
}
620
 
621
void
622
gui_quit(void)
623
{
624
	LOG(("gui_quit"));
625
 
626
	urldb_save_cookies(nsoption_charp(cookie_jar));
627
 
628
	framebuffer_finalise();
629
}
630
 
631
/* called back when click in browser window */
632
static int
633
fb_browser_window_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
634
{
635
	struct gui_window *gw = cbi->context;
636
	struct browser_widget_s *bwidget = fbtk_get_userpw(widget);
637
	float scale = gw->bw->scale;
638
	int x = (cbi->x + bwidget->scrollx) / scale;
639
	int y = (cbi->y + bwidget->scrolly) / scale;
640
 
641
	if (cbi->event->type != NSFB_EVENT_KEY_DOWN &&
642
	    cbi->event->type != NSFB_EVENT_KEY_UP)
643
		return 0;
644
 
645
	LOG(("browser window clicked at %d,%d", cbi->x, cbi->y));
646
 
647
	switch (cbi->event->type) {
648
	case NSFB_EVENT_KEY_DOWN:
649
		switch (cbi->event->value.keycode) {
650
		case NSFB_KEY_MOUSE_1:
651
			browser_window_mouse_click(gw->bw,
652
					BROWSER_MOUSE_PRESS_1, x, y);
653
			gui_drag.state = GUI_DRAG_PRESSED;
654
			gui_drag.button = 1;
655
			gui_drag.x = x;
656
			gui_drag.y = y;
657
			break;
658
 
659
		case NSFB_KEY_MOUSE_3:
660
			browser_window_mouse_click(gw->bw,
661
					BROWSER_MOUSE_PRESS_2, x, y);
662
			gui_drag.state = GUI_DRAG_PRESSED;
663
			gui_drag.button = 2;
664
			gui_drag.x = x;
665
			gui_drag.y = y;
666
			break;
667
 
668
		case NSFB_KEY_MOUSE_4:
669
			/* scroll up */
670
			if (browser_window_scroll_at_point(gw->bw, x, y,
671
					0, -100) == false)
672
				widget_scroll_y(gw, -100, false);
673
			break;
674
 
675
		case NSFB_KEY_MOUSE_5:
676
			/* scroll down */
677
			if (browser_window_scroll_at_point(gw->bw, x, y,
678
					0, 100) == false)
679
				widget_scroll_y(gw, 100, false);
680
			break;
681
 
682
		default:
683
			break;
684
 
685
		}
686
 
687
		break;
688
	case NSFB_EVENT_KEY_UP:
689
		switch (cbi->event->value.keycode) {
690
		case NSFB_KEY_MOUSE_1:
691
			if (gui_drag.state == GUI_DRAG_DRAG) {
692
				/* End of a drag, rather than click */
693
 
694
				if (gui_drag.grabbed_pointer) {
695
					/* need to ungrab pointer */
696
					fbtk_tgrab_pointer(widget);
697
					gui_drag.grabbed_pointer = false;
698
				}
699
 
700
				gui_drag.state = GUI_DRAG_NONE;
701
 
702
				/* Tell core */
703
				browser_window_mouse_track(gw->bw, 0, x, y);
704
				break;
705
			}
706
			/* This is a click;
707
			 * clear PRESSED state and pass to core */
708
			gui_drag.state = GUI_DRAG_NONE;
709
			browser_window_mouse_click(gw->bw,
710
					BROWSER_MOUSE_CLICK_1, x, y);
711
			break;
712
 
713
		case NSFB_KEY_MOUSE_3:
714
			if (gui_drag.state == GUI_DRAG_DRAG) {
715
				/* End of a drag, rather than click */
716
				gui_drag.state = GUI_DRAG_NONE;
717
 
718
				if (gui_drag.grabbed_pointer) {
719
					/* need to ungrab pointer */
720
					fbtk_tgrab_pointer(widget);
721
					gui_drag.grabbed_pointer = false;
722
				}
723
 
724
				/* Tell core */
725
				browser_window_mouse_track(gw->bw, 0, x, y);
726
				break;
727
			}
728
			/* This is a click;
729
			 * clear PRESSED state and pass to core */
730
			gui_drag.state = GUI_DRAG_NONE;
731
			browser_window_mouse_click(gw->bw,
732
					BROWSER_MOUSE_CLICK_2, x, y);
733
			break;
734
 
735
		default:
736
			break;
737
 
738
		}
739
 
740
		break;
741
	default:
742
		break;
743
 
744
	}
745
	return 1;
746
}
747
 
748
/* called back when movement in browser window */
749
static int
750
fb_browser_window_move(fbtk_widget_t *widget, fbtk_callback_info *cbi)
751
{
752
	browser_mouse_state mouse = 0;
753
	struct gui_window *gw = cbi->context;
754
	struct browser_widget_s *bwidget = fbtk_get_userpw(widget);
755
	int x = (cbi->x + bwidget->scrollx) / gw->bw->scale;
756
	int y = (cbi->y + bwidget->scrolly) / gw->bw->scale;
757
 
758
	if (gui_drag.state == GUI_DRAG_PRESSED &&
759
			(abs(x - gui_drag.x) > 5 ||
760
			 abs(y - gui_drag.y) > 5)) {
761
		/* Drag started */
762
		if (gui_drag.button == 1) {
763
			browser_window_mouse_click(gw->bw,
764
					BROWSER_MOUSE_DRAG_1,
765
					gui_drag.x, gui_drag.y);
766
		} else {
767
			browser_window_mouse_click(gw->bw,
768
					BROWSER_MOUSE_DRAG_2,
769
					gui_drag.x, gui_drag.y);
770
		}
771
		gui_drag.grabbed_pointer = fbtk_tgrab_pointer(widget);
772
		gui_drag.state = GUI_DRAG_DRAG;
773
	}
774
 
775
	if (gui_drag.state == GUI_DRAG_DRAG) {
776
		/* set up mouse state */
777
		mouse |= BROWSER_MOUSE_DRAG_ON;
778
 
779
		if (gui_drag.button == 1)
780
			mouse |= BROWSER_MOUSE_HOLDING_1;
781
		else
782
			mouse |= BROWSER_MOUSE_HOLDING_2;
783
	}
784
 
785
	browser_window_mouse_track(gw->bw, mouse, x, y);
786
 
787
	return 0;
788
}
789
 
790
 
791
static int
792
fb_browser_window_input(fbtk_widget_t *widget, fbtk_callback_info *cbi)
793
{
794
	struct gui_window *gw = cbi->context;
795
	static fbtk_modifier_type modifier = FBTK_MOD_CLEAR;
796
	int ucs4 = -1;
797
 
798
	LOG(("got value %d", cbi->event->value.keycode));
799
 
800
	switch (cbi->event->type) {
801
	case NSFB_EVENT_KEY_DOWN:
802
		switch (cbi->event->value.keycode) {
803
 
804
		case NSFB_KEY_PAGEUP:
805
			if (browser_window_key_press(gw->bw,
806
					KEY_PAGE_UP) == false)
807
				widget_scroll_y(gw, -fbtk_get_height(
808
						gw->browser), false);
809
			break;
810
 
811
		case NSFB_KEY_PAGEDOWN:
812
			if (browser_window_key_press(gw->bw,
813
					KEY_PAGE_DOWN) == false)
814
				widget_scroll_y(gw, fbtk_get_height(
815
						gw->browser), false);
816
			break;
817
 
818
		case NSFB_KEY_RIGHT:
819
			if (modifier & FBTK_MOD_RCTRL ||
820
					modifier & FBTK_MOD_LCTRL) {
821
				/* CTRL held */
822
				if (browser_window_key_press(gw->bw,
823
						KEY_LINE_END) == false)
824
					widget_scroll_x(gw, INT_MAX, true);
825
 
826
			} else if (modifier & FBTK_MOD_RSHIFT ||
827
					modifier & FBTK_MOD_LSHIFT) {
828
				/* SHIFT held */
829
				if (browser_window_key_press(gw->bw,
830
						KEY_WORD_RIGHT) == false)
831
					widget_scroll_x(gw, fbtk_get_width(
832
						gw->browser), false);
833
 
834
			} else {
835
				/* no modifier */
836
				if (browser_window_key_press(gw->bw,
837
						KEY_RIGHT) == false)
838
					widget_scroll_x(gw, 100, false);
839
			}
840
			break;
841
 
842
		case NSFB_KEY_LEFT:
843
			if (modifier & FBTK_MOD_RCTRL ||
844
					modifier & FBTK_MOD_LCTRL) {
845
				/* CTRL held */
846
				if (browser_window_key_press(gw->bw,
847
						KEY_LINE_START) == false)
848
					widget_scroll_x(gw, 0, true);
849
 
850
			} else if (modifier & FBTK_MOD_RSHIFT ||
851
					modifier & FBTK_MOD_LSHIFT) {
852
				/* SHIFT held */
853
				if (browser_window_key_press(gw->bw,
854
						KEY_WORD_LEFT) == false)
855
					widget_scroll_x(gw, -fbtk_get_width(
856
						gw->browser), false);
857
 
858
			} else {
859
				/* no modifier */
860
				if (browser_window_key_press(gw->bw,
861
						KEY_LEFT) == false)
862
					widget_scroll_x(gw, -100, false);
863
			}
864
			break;
865
 
866
		case NSFB_KEY_UP:
867
			if (browser_window_key_press(gw->bw,
868
					KEY_UP) == false)
869
				widget_scroll_y(gw, -100, false);
870
			break;
871
 
872
		case NSFB_KEY_DOWN:
873
			if (browser_window_key_press(gw->bw,
874
					KEY_DOWN) == false)
875
				widget_scroll_y(gw, 100, false);
876
			break;
877
 
878
		case NSFB_KEY_RSHIFT:
879
			modifier |= FBTK_MOD_RSHIFT;
880
			break;
881
 
882
		case NSFB_KEY_LSHIFT:
883
			modifier |= FBTK_MOD_LSHIFT;
884
			break;
885
 
886
		case NSFB_KEY_RCTRL:
887
			modifier |= FBTK_MOD_RCTRL;
888
			break;
889
 
890
		case NSFB_KEY_LCTRL:
891
			modifier |= FBTK_MOD_LCTRL;
892
			break;
893
 
894
		default:
895
			ucs4 = fbtk_keycode_to_ucs4(cbi->event->value.keycode,
896
						    modifier);
897
			if (ucs4 != -1)
898
				browser_window_key_press(gw->bw, ucs4);
899
			break;
900
		}
901
		break;
902
 
903
	case NSFB_EVENT_KEY_UP:
904
		switch (cbi->event->value.keycode) {
905
		case NSFB_KEY_RSHIFT:
906
			modifier &= ~FBTK_MOD_RSHIFT;
907
			break;
908
 
909
		case NSFB_KEY_LSHIFT:
910
			modifier &= ~FBTK_MOD_LSHIFT;
911
			break;
912
 
913
		case NSFB_KEY_RCTRL:
914
			modifier &= ~FBTK_MOD_RCTRL;
915
			break;
916
 
917
		case NSFB_KEY_LCTRL:
918
			modifier &= ~FBTK_MOD_LCTRL;
919
			break;
920
 
921
		default:
922
			break;
923
		}
924
		break;
925
 
926
	default:
927
		break;
928
	}
929
 
930
	return 0;
931
}
932
 
933
static void
934
fb_update_back_forward(struct gui_window *gw)
935
{
936
	struct browser_window *bw = gw->bw;
937
 
938
	fbtk_set_bitmap(gw->back,
939
			(browser_window_back_available(bw)) ?
940
			&left_arrow : &left_arrow_g);
941
	fbtk_set_bitmap(gw->forward,
942
			(browser_window_forward_available(bw)) ?
943
			&right_arrow : &right_arrow_g);
944
}
945
 
946
/* left icon click routine */
947
static int
948
fb_leftarrow_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
949
{
950
	struct gui_window *gw = cbi->context;
951
	struct browser_window *bw = gw->bw;
952
 
953
	if (cbi->event->type != NSFB_EVENT_KEY_UP)
954
		return 0;
955
 
956
	if (history_back_available(bw->history))
957
		history_back(bw, bw->history);
958
 
959
	fb_update_back_forward(gw);
960
 
961
	return 1;
962
}
963
 
964
/* right arrow icon click routine */
965
static int
966
fb_rightarrow_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
967
{
968
	struct gui_window *gw = cbi->context;
969
	struct browser_window *bw = gw->bw;
970
 
971
	if (cbi->event->type != NSFB_EVENT_KEY_UP)
972
		return 0;
973
 
974
	if (history_forward_available(bw->history))
975
		history_forward(bw, bw->history);
976
 
977
	fb_update_back_forward(gw);
978
	return 1;
979
 
980
}
981
 
982
/* reload icon click routine */
983
static int
984
fb_reload_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
985
{
986
	struct browser_window *bw = cbi->context;
987
 
988
	if (cbi->event->type != NSFB_EVENT_KEY_UP)
989
		return 0;
990
 
991
	browser_window_reload(bw, true);
992
	return 1;
993
}
994
 
995
/* stop icon click routine */
996
static int
997
fb_stop_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
998
{
999
	struct browser_window *bw = cbi->context;
1000
 
1001
	if (cbi->event->type != NSFB_EVENT_KEY_UP)
1002
		return 0;
1003
 
1004
	browser_window_stop(bw);
1005
	return 0;
1006
}
1007
 
1008
static int
1009
fb_osk_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
1010
{
1011
 
1012
	if (cbi->event->type != NSFB_EVENT_KEY_UP)
1013
		return 0;
1014
 
1015
	map_osk();
1016
 
1017
	return 0;
1018
}
1019
 
1020
/* close browser window icon click routine */
1021
static int
1022
fb_close_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
1023
{
1024
	if (cbi->event->type != NSFB_EVENT_KEY_UP)
1025
		return 0;
1026
 
1027
	netsurf_quit = true;
1028
	return 0;
1029
}
1030
 
1031
static int
1032
fb_scroll_callback(fbtk_widget_t *widget, fbtk_callback_info *cbi)
1033
{
1034
	struct gui_window *gw = cbi->context;
1035
 
1036
	switch (cbi->type) {
1037
	case FBTK_CBT_SCROLLY:
1038
		widget_scroll_y(gw, cbi->y, true);
1039
		break;
1040
 
1041
	case FBTK_CBT_SCROLLX:
1042
		widget_scroll_x(gw, cbi->x, true);
1043
		break;
1044
 
1045
	default:
1046
		break;
1047
	}
1048
	return 0;
1049
}
1050
 
1051
static int
1052
fb_url_enter(void *pw, char *text)
1053
{
1054
	struct browser_window *bw = pw;
1055
	browser_window_go(bw, text, 0, true);
1056
	return 0;
1057
}
1058
 
1059
static int
1060
fb_url_move(fbtk_widget_t *widget, fbtk_callback_info *cbi)
1061
{
1062
	framebuffer_set_cursor(&caret_image);
1063
	return 0;
1064
}
1065
 
1066
static int
1067
set_ptr_default_move(fbtk_widget_t *widget, fbtk_callback_info *cbi)
1068
{
1069
	framebuffer_set_cursor(&pointer_image);
1070
	return 0;
1071
}
1072
 
1073
static int
1074
fb_localhistory_btn_clik(fbtk_widget_t *widget, fbtk_callback_info *cbi)
1075
{
1076
	struct gui_window *gw = cbi->context;
1077
 
1078
	if (cbi->event->type != NSFB_EVENT_KEY_UP)
1079
		return 0;
1080
 
1081
	fb_localhistory_map(gw->localhistory);
1082
 
1083
	return 0;
1084
}
1085
 
1086
 
1087
/** Create a toolbar window and populate it with buttons.
1088
 *
1089
 * The toolbar layout uses a character to define buttons type and position:
1090
 * b - back
1091
 * l - local history
1092
 * f - forward
1093
 * s - stop
1094
 * r - refresh
1095
 * u - url bar expands to fit remaining space
1096
 * t - throbber/activity indicator
1097
 * c - close the current window
1098
 *
1099
 * The default layout is "blfsrut" there should be no more than a
1100
 * single url bar entry or behaviour will be undefined.
1101
 *
1102
 * @param gw Parent window
1103
 * @param toolbar_height The height in pixels of the toolbar
1104
 * @param padding The padding in pixels round each element of the toolbar
1105
 * @param frame_col Frame colour.
1106
 * @param toolbar_layout A string defining which buttons and controls
1107
 *                       should be added to the toolbar. May be empty
1108
 *                       string to disable the bar..
1109
 *
1110
 */
1111
static fbtk_widget_t *
1112
create_toolbar(struct gui_window *gw,
1113
	       int toolbar_height,
1114
	       int padding,
1115
	       colour frame_col,
1116
	       const char *toolbar_layout)
1117
{
1118
	fbtk_widget_t *toolbar;
1119
	fbtk_widget_t *widget;
1120
 
1121
	int xpos; /* The position of the next widget. */
1122
	int xlhs = 0; /* extent of the left hand side widgets */
1123
	int xdir = 1; /* the direction of movement + or - 1 */
1124
	const char *itmtype; /* type of the next item */
1125
 
1126
	if (toolbar_layout == NULL) {
1127
		toolbar_layout = NSFB_TOOLBAR_DEFAULT_LAYOUT;
1128
	}
1129
 
1130
	LOG(("Using toolbar layout %s", toolbar_layout));
1131
 
1132
	itmtype = toolbar_layout;
1133
 
1134
	if (*itmtype == 0) {
1135
		return NULL;
1136
	}
1137
 
1138
	toolbar = fbtk_create_window(gw->window, 0, 0, 0,
1139
				     toolbar_height,
1140
				     frame_col);
1141
 
1142
	if (toolbar == NULL) {
1143
		return NULL;
1144
	}
1145
 
1146
	fbtk_set_handler(toolbar,
1147
			 FBTK_CBT_POINTERENTER,
1148
			 set_ptr_default_move,
1149
			 NULL);
1150
 
1151
 
1152
	xpos = padding;
1153
 
1154
	/* loop proceeds creating widget on the left hand side until
1155
	 * it runs out of layout or encounters a url bar declaration
1156
	 * wherupon it works backwards from the end of the layout
1157
	 * untill the space left is for the url bar
1158
	 */
1159
	while ((itmtype >= toolbar_layout) &&
1160
	       (*itmtype != 0) &&
1161
	       (xdir !=0)) {
1162
 
1163
		LOG(("toolbar adding %c", *itmtype));
1164
 
1165
 
1166
		switch (*itmtype) {
1167
 
1168
		case 'b': /* back */
1169
			widget = fbtk_create_button(toolbar,
1170
						    (xdir == 1) ? xpos :
1171
						     xpos - left_arrow.width,
1172
						    padding,
1173
						    left_arrow.width,
1174
						    -padding,
1175
						    frame_col,
1176
						    &left_arrow,
1177
						    fb_leftarrow_click,
1178
						    gw);
1179
			gw->back = widget; /* keep reference */
1180
			break;
1181
 
1182
		case 'l': /* local history */
1183
			widget = fbtk_create_button(toolbar,
1184
						    (xdir == 1) ? xpos :
1185
						     xpos - history_image.width,
1186
						    padding,
1187
						    history_image.width,
1188
						    -padding,
1189
						    frame_col,
1190
						    &history_image,
1191
						    fb_localhistory_btn_clik,
1192
						    gw);
1193
			break;
1194
 
1195
		case 'f': /* forward */
1196
			widget = fbtk_create_button(toolbar,
1197
						    (xdir == 1)?xpos :
1198
						     xpos - right_arrow.width,
1199
						    padding,
1200
						    right_arrow.width,
1201
						    -padding,
1202
						    frame_col,
1203
						    &right_arrow,
1204
						    fb_rightarrow_click,
1205
						    gw);
1206
			gw->forward = widget;
1207
			break;
1208
 
1209
		case 'c': /* close the current window */
1210
			widget = fbtk_create_button(toolbar,
1211
						    (xdir == 1)?xpos :
1212
						     xpos - stop_image_g.width,
1213
						    padding,
1214
						    stop_image_g.width,
1215
						    -padding,
1216
						    frame_col,
1217
						    &stop_image_g,
1218
						    fb_close_click,
1219
						    gw->bw);
1220
			break;
1221
 
1222
		case 's': /* stop  */
1223
			widget = fbtk_create_button(toolbar,
1224
						    (xdir == 1)?xpos :
1225
						     xpos - stop_image.width,
1226
						    padding,
1227
						    stop_image.width,
1228
						    -padding,
1229
						    frame_col,
1230
						    &stop_image,
1231
						    fb_stop_click,
1232
						    gw->bw);
1233
			break;
1234
 
1235
		case 'r': /* reload */
1236
			widget = fbtk_create_button(toolbar,
1237
						    (xdir == 1)?xpos :
1238
						     xpos - reload.width,
1239
						    padding,
1240
						    reload.width,
1241
						    -padding,
1242
						    frame_col,
1243
						    &reload,
1244
						    fb_reload_click,
1245
						    gw->bw);
1246
			break;
1247
 
1248
		case 't': /* throbber/activity indicator */
1249
			widget = fbtk_create_bitmap(toolbar,
1250
						    (xdir == 1)?xpos :
1251
						     xpos - throbber0.width,
1252
						    padding,
1253
						    throbber0.width,
1254
						    -padding,
1255
						    frame_col,
1256
						    &throbber0);
1257
			gw->throbber = widget;
1258
			break;
1259
 
1260
 
1261
		case 'u': /* url bar*/
1262
			if (xdir == -1) {
1263
				/* met the u going backwards add url
1264
				 * now we know available extent
1265
				 */
1266
 
1267
				widget = fbtk_create_writable_text(toolbar,
1268
						   xlhs,
1269
						   padding,
1270
						   xpos - xlhs,
1271
						   -padding,
1272
						   FB_COLOUR_WHITE,
1273
						   FB_COLOUR_BLACK,
1274
						   true,
1275
						   fb_url_enter,
1276
						   gw->bw);
1277
 
1278
				fbtk_set_handler(widget,
1279
						 FBTK_CBT_POINTERENTER,
1280
						 fb_url_move, gw->bw);
1281
 
1282
				gw->url = widget; /* keep reference */
1283
 
1284
				/* toolbar is complete */
1285
				xdir = 0;
1286
				break;
1287
			}
1288
			/* met url going forwards, note position and
1289
			 * reverse direction
1290
			 */
1291
			itmtype = toolbar_layout + strlen(toolbar_layout);
1292
			xdir = -1;
1293
			xlhs = xpos;
1294
			xpos = (2 * fbtk_get_width(toolbar));
1295
			widget = toolbar;
1296
			break;
1297
 
1298
		default:
1299
			widget = NULL;
1300
			xdir = 0;
1301
			LOG(("Unknown element %c in toolbar layout", *itmtype));
1302
		        break;
1303
 
1304
		}
1305
 
1306
		if (widget != NULL) {
1307
			xpos += (xdir * (fbtk_get_width(widget) + padding));
1308
		}
1309
 
1310
		LOG(("xpos is %d",xpos));
1311
 
1312
		itmtype += xdir;
1313
	}
1314
 
1315
	fbtk_set_mapping(toolbar, true);
1316
 
1317
	return toolbar;
1318
}
1319
 
1320
/** Routine called when "stripped of focus" event occours for browser widget.
1321
 *
1322
 * @param widget The widget reciving "stripped of focus" event.
1323
 * @param cbi The callback parameters.
1324
 * @return The callback result.
1325
 */
1326
static int
1327
fb_browser_window_strip_focus(fbtk_widget_t *widget, fbtk_callback_info *cbi)
1328
{
1329
	fbtk_set_caret(widget, false, 0, 0, 0, NULL);
1330
 
1331
	return 0;
1332
}
1333
 
1334
static void
1335
create_browser_widget(struct gui_window *gw, int toolbar_height, int furniture_width)
1336
{
1337
	struct browser_widget_s *browser_widget;
1338
	browser_widget = calloc(1, sizeof(struct browser_widget_s));
1339
 
1340
	gw->browser = fbtk_create_user(gw->window,
1341
				       0,
1342
				       toolbar_height,
1343
				       -furniture_width,
1344
				       -furniture_width,
1345
				       browser_widget);
1346
 
1347
	fbtk_set_handler(gw->browser, FBTK_CBT_REDRAW, fb_browser_window_redraw, gw);
1348
	fbtk_set_handler(gw->browser, FBTK_CBT_INPUT, fb_browser_window_input, gw);
1349
	fbtk_set_handler(gw->browser, FBTK_CBT_CLICK, fb_browser_window_click, gw);
1350
	fbtk_set_handler(gw->browser, FBTK_CBT_STRIP_FOCUS, fb_browser_window_strip_focus, gw);
1351
	fbtk_set_handler(gw->browser, FBTK_CBT_POINTERMOVE, fb_browser_window_move, gw);
1352
}
1353
 
1354
static void
1355
create_normal_browser_window(struct gui_window *gw, int furniture_width)
1356
{
1357
	LOG(("enter norm win"));
1358
	fbtk_widget_t *widget;
1359
	fbtk_widget_t *toolbar;
1360
	int statusbar_width = 0;
1361
	int toolbar_height = 30; //nsoption_int(fb_toolbar_size);
1362
 
1363
	LOG(("Normal window"));
1364
 
1365
	gw->window = fbtk_create_window(fbtk, 0, 0, 0, 0, 0);
1366
 
1367
	statusbar_width = nsoption_int(toolbar_status_width) *
1368
		fbtk_get_width(gw->window) / 10000;
1369
 
1370
LOG(("STUB options"));
1371
 
1372
 
1373
 
1374
	nsoptions.fb_depth = 16;
1375
	nsoptions.fb_refresh = 70;
1376
	nsoptions.fb_device = NULL;
1377
	nsoptions.fb_input_devpath = NULL;
1378
	nsoptions.fb_input_glob = NULL;
1379
	nsoptions.fb_furniture_size = 18;
1380
	nsoptions.fb_toolbar_size = 30;
1381
	nsoptions.fb_toolbar_layout = NULL;
1382
	nsoptions.fb_osk = false;
1383
 
1384
 
1385
 
1386
	/* toolbar */
1387
	LOG(("toolbar"));
1388
 
1389
 
1390
 
1391
	toolbar = create_toolbar(gw,
1392
				 toolbar_height,
1393
				 2,
1394
				 FB_FRAME_COLOUR,
1395
				 nsoption_charp(fb_toolbar_layout));
1396
 
1397
	/* set the actually created toolbar height */
1398
	if (toolbar != NULL) {
1399
		toolbar_height = fbtk_get_height(toolbar);
1400
	} else {
1401
		toolbar_height = 0;
1402
	}
1403
 
1404
	LOG(("statbar"));
1405
	/* status bar */
1406
	gw->status = fbtk_create_text(gw->window,
1407
				      0,
1408
				      fbtk_get_height(gw->window) - furniture_width,
1409
				      statusbar_width, furniture_width,
1410
				      FB_FRAME_COLOUR, FB_COLOUR_BLACK,
1411
				      false);
1412
 
1413
	LOG(("handler"));
1414
	fbtk_set_handler(gw->status, FBTK_CBT_POINTERENTER, set_ptr_default_move, NULL);
1415
 
1416
	LOG(("status bar %p at %d,%d", gw->status, fbtk_get_absx(gw->status), fbtk_get_absy(gw->status)));
1417
 
1418
	/* create horizontal scrollbar */
1419
	LOG(("hor sb"));
1420
 
1421
	gw->hscroll = fbtk_create_hscroll(gw->window,
1422
					  statusbar_width,
1423
					  fbtk_get_height(gw->window) - furniture_width,
1424
					  fbtk_get_width(gw->window) - statusbar_width - furniture_width,
1425
					  furniture_width,
1426
					  FB_SCROLL_COLOUR,
1427
					  FB_FRAME_COLOUR,
1428
					  fb_scroll_callback,
1429
					  gw);
1430
 
1431
	/* fill bottom right area */
1432
	LOG(("fill bottom"));
1433
 
1434
	if (nsoption_bool(fb_osk) == true) {
1435
		widget = fbtk_create_text_button(gw->window,
1436
						 fbtk_get_width(gw->window) - furniture_width,
1437
						 fbtk_get_height(gw->window) - furniture_width,
1438
						 furniture_width,
1439
						 furniture_width,
1440
						 FB_FRAME_COLOUR, FB_COLOUR_BLACK,
1441
						 fb_osk_click,
1442
						 NULL);
1443
		widget = fbtk_create_button(gw->window,
1444
				fbtk_get_width(gw->window) - furniture_width,
1445
				fbtk_get_height(gw->window) - furniture_width,
1446
				furniture_width,
1447
				furniture_width,
1448
				FB_FRAME_COLOUR,
1449
				&osk_image,
1450
				fb_osk_click,
1451
				NULL);
1452
	} else {
1453
		widget = fbtk_create_fill(gw->window,
1454
					  fbtk_get_width(gw->window) - furniture_width,
1455
					  fbtk_get_height(gw->window) - furniture_width,
1456
					  furniture_width,
1457
					  furniture_width,
1458
					  FB_FRAME_COLOUR);
1459
 
1460
		fbtk_set_handler(widget, FBTK_CBT_POINTERENTER, set_ptr_default_move, NULL);
1461
	}
1462
 
1463
	LOG(("vsb GUI"));
1464
	/* create vertical scrollbar */
1465
	gw->vscroll = fbtk_create_vscroll(gw->window,
1466
					  fbtk_get_width(gw->window) - furniture_width,
1467
					  toolbar_height,
1468
					  furniture_width,
1469
					  fbtk_get_height(gw->window) - toolbar_height - furniture_width,
1470
					  FB_SCROLL_COLOUR,
1471
					  FB_FRAME_COLOUR,
1472
					  fb_scroll_callback,
1473
					  gw);
1474
 
1475
	LOG(("BRO widget"));
1476
	/* browser widget */
1477
	create_browser_widget(gw, toolbar_height, nsoption_int(fb_furniture_size));
1478
 
1479
	LOG(("set focus"));
1480
	/* Give browser_window's user widget input focus */
1481
	fbtk_set_focus(gw->browser);
1482
	LOG(("GUI OK"));
1483
}
1484
 
1485
 
1486
struct gui_window *
1487
gui_create_browser_window(struct browser_window *bw,
1488
			  struct browser_window *clone,
1489
			  bool new_tab)
1490
{
1491
	struct gui_window *gw;
1492
	LOG(("GCBW calloc"));
1493
 
1494
	gw = calloc(1, sizeof(struct gui_window));
1495
 
1496
	if (gw == NULL)
1497
		return NULL;
1498
 
1499
	/* seems we need to associate the gui window with the underlying
1500
	 * browser window
1501
	 */
1502
	LOG(("GCBW next.."));
1503
 
1504
 
1505
	gw->bw = bw;
1506
 
1507
	LOG(("fb_furn_size is STUB now!..."));
1508
 
1509
	 //nsoption_int(fb_furniture_size);
1510
	LOG(("GCBW create normal window..."));
1511
 
1512
 
1513
	create_normal_browser_window(gw, 18); //nsoption_int(fb_furniture_size));
1514
	LOG(("GCBW create local history..."));
1515
 
1516
	gw->localhistory = fb_create_localhistory(bw, fbtk, nsoption_int(fb_furniture_size));
1517
 
1518
	/* map and request redraw of gui window */
1519
	LOG(("GCBW set mapping"));
1520
 
1521
	fbtk_set_mapping(gw->window, true);
1522
	LOG(("GCBW OK!"));
1523
 
1524
 
1525
	return gw;
1526
}
1527
 
1528
void
1529
gui_window_destroy(struct gui_window *gw)
1530
{
1531
	fbtk_destroy_widget(gw->window);
1532
 
1533
	free(gw);
1534
 
1535
 
1536
}
1537
 
1538
void
1539
gui_window_set_title(struct gui_window *g, const char *title)
1540
{
1541
	LOG(("%p, %s", g, title));
1542
}
1543
 
1544
void
1545
gui_window_redraw_window(struct gui_window *g)
1546
{
1547
	fb_queue_redraw(g->browser, 0, 0, fbtk_get_width(g->browser), fbtk_get_height(g->browser) );
1548
}
1549
 
1550
void
1551
gui_window_update_box(struct gui_window *g, const struct rect *rect)
1552
{
1553
	struct browser_widget_s *bwidget = fbtk_get_userpw(g->browser);
1554
	fb_queue_redraw(g->browser,
1555
			rect->x0 - bwidget->scrollx,
1556
			rect->y0 - bwidget->scrolly,
1557
			rect->x1 - bwidget->scrollx,
1558
			rect->y1 - bwidget->scrolly);
1559
}
1560
 
1561
bool
1562
gui_window_get_scroll(struct gui_window *g, int *sx, int *sy)
1563
{
1564
	struct browser_widget_s *bwidget = fbtk_get_userpw(g->browser);
1565
 
1566
	*sx = bwidget->scrollx / g->bw->scale;
1567
	*sy = bwidget->scrolly / g->bw->scale;
1568
 
1569
	return true;
1570
}
1571
 
1572
void
1573
gui_window_set_scroll(struct gui_window *gw, int sx, int sy)
1574
{
1575
	struct browser_widget_s *bwidget = fbtk_get_userpw(gw->browser);
1576
 
1577
	assert(bwidget);
1578
 
1579
	widget_scroll_x(gw, sx * gw->bw->scale, true);
1580
	widget_scroll_y(gw, sy * gw->bw->scale, true);
1581
}
1582
 
1583
void
1584
gui_window_scroll_visible(struct gui_window *g, int x0, int y0,
1585
			  int x1, int y1)
1586
{
1587
	LOG(("%s:(%p, %d, %d, %d, %d)", __func__, g, x0, y0, x1, y1));
1588
}
1589
 
1590
void
1591
gui_window_get_dimensions(struct gui_window *g,
1592
			  int *width,
1593
			  int *height,
1594
			  bool scaled)
1595
{
1596
	*width = fbtk_get_width(g->browser);
1597
	*height = fbtk_get_height(g->browser);
1598
 
1599
	if (scaled) {
1600
		*width /= g->bw->scale;
1601
		*height /= g->bw->scale;
1602
	}
1603
}
1604
 
1605
void
1606
gui_window_update_extent(struct gui_window *gw)
1607
{
1608
	float scale = gw->bw->scale;
1609
 
1610
	fbtk_set_scroll_parameters(gw->hscroll, 0,
1611
			content_get_width(gw->bw->current_content) * scale,
1612
			fbtk_get_width(gw->browser), 100);
1613
 
1614
	fbtk_set_scroll_parameters(gw->vscroll, 0,
1615
			content_get_height(gw->bw->current_content) * scale,
1616
			fbtk_get_height(gw->browser), 100);
1617
}
1618
 
1619
void
1620
gui_window_set_status(struct gui_window *g, const char *text)
1621
{
1622
	fbtk_set_text(g->status, text);
1623
}
1624
 
1625
void
1626
gui_window_set_pointer(struct gui_window *g, gui_pointer_shape shape)
1627
{
1628
	switch (shape) {
1629
	case GUI_POINTER_POINT:
1630
		framebuffer_set_cursor(&hand_image);
1631
		break;
1632
 
1633
	case GUI_POINTER_CARET:
1634
		framebuffer_set_cursor(&caret_image);
1635
		break;
1636
 
1637
	case GUI_POINTER_MENU:
1638
		framebuffer_set_cursor(&menu_image);
1639
		break;
1640
 
1641
	case GUI_POINTER_PROGRESS:
1642
		framebuffer_set_cursor(&progress_image);
1643
		break;
1644
 
1645
	case GUI_POINTER_MOVE:
1646
		framebuffer_set_cursor(&move_image);
1647
		break;
1648
 
1649
	default:
1650
		framebuffer_set_cursor(&pointer_image);
1651
		break;
1652
	}
1653
}
1654
 
1655
void
1656
gui_window_hide_pointer(struct gui_window *g)
1657
{
1658
}
1659
 
1660
void
1661
gui_window_set_url(struct gui_window *g, const char *url)
1662
{
1663
	fbtk_set_text(g->url, url);
1664
}
1665
 
1666
static void
1667
throbber_advance(void *pw)
1668
{
1669
	struct gui_window *g = pw;
1670
	struct fbtk_bitmap *image;
1671
 
1672
	switch (g->throbber_index) {
1673
	case 0:
1674
		image = &throbber1;
1675
		g->throbber_index = 1;
1676
		break;
1677
 
1678
	case 1:
1679
		image = &throbber2;
1680
		g->throbber_index = 2;
1681
		break;
1682
 
1683
	case 2:
1684
		image = &throbber3;
1685
		g->throbber_index = 3;
1686
		break;
1687
 
1688
	case 3:
1689
		image = &throbber4;
1690
		g->throbber_index = 4;
1691
		break;
1692
 
1693
	case 4:
1694
		image = &throbber5;
1695
		g->throbber_index = 5;
1696
		break;
1697
 
1698
	case 5:
1699
		image = &throbber6;
1700
		g->throbber_index = 6;
1701
		break;
1702
 
1703
	case 6:
1704
		image = &throbber7;
1705
		g->throbber_index = 7;
1706
		break;
1707
 
1708
	case 7:
1709
		image = &throbber8;
1710
		g->throbber_index = 0;
1711
		break;
1712
 
1713
	default:
1714
		return;
1715
	}
1716
 
1717
	if (g->throbber_index >= 0) {
1718
		fbtk_set_bitmap(g->throbber, image);
1719
		schedule(10, throbber_advance, g);
1720
	}
1721
}
1722
 
1723
void
1724
gui_window_start_throbber(struct gui_window *g)
1725
{
1726
	g->throbber_index = 0;
1727
	schedule(10, throbber_advance, g);
1728
}
1729
 
1730
void
1731
gui_window_stop_throbber(struct gui_window *gw)
1732
{
1733
	gw->throbber_index = -1;
1734
	fbtk_set_bitmap(gw->throbber, &throbber0);
1735
 
1736
	fb_update_back_forward(gw);
1737
 
1738
}
1739
 
1740
static void
1741
gui_window_remove_caret_cb(fbtk_widget_t *widget)
1742
{
1743
	struct browser_widget_s *bwidget = fbtk_get_userpw(widget);
1744
	int c_x, c_y, c_h;
1745
 
1746
	if (fbtk_get_caret(widget, &c_x, &c_y, &c_h)) {
1747
		/* browser window already had caret:
1748
		 * redraw its area to remove it first */
1749
		fb_queue_redraw(widget,
1750
				c_x - bwidget->scrollx,
1751
				c_y - bwidget->scrolly,
1752
				c_x + 1 - bwidget->scrollx,
1753
				c_y + c_h - bwidget->scrolly);
1754
	}
1755
}
1756
 
1757
void
1758
gui_window_place_caret(struct gui_window *g, int x, int y, int height)
1759
{
1760
	struct browser_widget_s *bwidget = fbtk_get_userpw(g->browser);
1761
 
1762
	/* set new pos */
1763
	fbtk_set_caret(g->browser, true, x, y, height,
1764
			gui_window_remove_caret_cb);
1765
 
1766
	/* redraw new caret pos */
1767
	fb_queue_redraw(g->browser,
1768
			x - bwidget->scrollx,
1769
			y - bwidget->scrolly,
1770
			x + 1 - bwidget->scrollx,
1771
			y + height - bwidget->scrolly);
1772
}
1773
 
1774
void
1775
gui_window_remove_caret(struct gui_window *g)
1776
{
1777
	int c_x, c_y, c_h;
1778
 
1779
	if (fbtk_get_caret(g->browser, &c_x, &c_y, &c_h)) {
1780
		/* browser window owns the caret, so can remove it */
1781
		fbtk_set_caret(g->browser, false, 0, 0, 0, NULL);
1782
	}
1783
}
1784
 
1785
void
1786
gui_window_new_content(struct gui_window *g)
1787
{
1788
}
1789
 
1790
bool
1791
gui_window_scroll_start(struct gui_window *g)
1792
{
1793
	return true;
1794
}
1795
 
1796
bool
1797
gui_window_drag_start(struct gui_window *g, gui_drag_type type,
1798
                      const struct rect *rect)
1799
{
1800
	return true;
1801
}
1802
 
1803
void
1804
gui_window_save_link(struct gui_window *g, const char *url, const char *title)
1805
{
1806
}
1807
 
1808
/**
1809
 * set favicon
1810
 */
1811
void
1812
gui_window_set_icon(struct gui_window *g, hlcache_handle *icon)
1813
{
1814
}
1815
 
1816
/**
1817
 * set gui display of a retrieved favicon representing the search provider
1818
 * \param ico may be NULL for local calls; then access current cache from
1819
 * search_web_ico()
1820
 */
1821
void
1822
gui_window_set_search_ico(hlcache_handle *ico)
1823
{
1824
}
1825
 
1826
struct gui_download_window *
1827
gui_download_window_create(download_context *ctx, struct gui_window *parent)
1828
{
1829
	return NULL;
1830
}
1831
 
1832
nserror
1833
gui_download_window_data(struct gui_download_window *dw,
1834
			 const char *data,
1835
			 unsigned int size)
1836
{
1837
	return NSERROR_OK;
1838
}
1839
 
1840
void
1841
gui_download_window_error(struct gui_download_window *dw,
1842
			  const char *error_msg)
1843
{
1844
}
1845
 
1846
void
1847
gui_download_window_done(struct gui_download_window *dw)
1848
{
1849
}
1850
 
1851
void
1852
gui_drag_save_object(gui_save_type type,
1853
		     hlcache_handle *c,
1854
		     struct gui_window *w)
1855
{
1856
}
1857
 
1858
void
1859
gui_drag_save_selection(struct selection *s, struct gui_window *g)
1860
{
1861
}
1862
 
1863
void
1864
gui_start_selection(struct gui_window *g)
1865
{
1866
}
1867
 
1868
void
1869
gui_clear_selection(struct gui_window *g)
1870
{
1871
}
1872
 
1873
void
1874
gui_create_form_select_menu(struct browser_window *bw,
1875
			    struct form_control *control)
1876
{
1877
}
1878
 
1879
void
1880
gui_launch_url(const char *url)
1881
{
1882
}
1883
 
1884
void
1885
gui_cert_verify(nsurl *url,
1886
		const struct ssl_cert_info *certs,
1887
		unsigned long num,
1888
		nserror (*cb)(bool proceed, void *pw),
1889
		void *cbpw)
1890
{
1891
	cb(false, cbpw);
1892
}
1893
 
1894
/*
1895
 * Local Variables:
1896
 * c-basic-offset:8
1897
 * End:
1898
 */