Subversion Repositories Kolibri OS

Rev

Rev 3584 | Go to most recent revision | Details | Compare with Previous | 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
 
3624 sourcerer 430
	fename = "kolibri";
431
	febpp = 32;
3584 sourcerer 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
 
3624 sourcerer 546
	//extern nsfb_surface_rtns_t sdl_rtns;
3584 sourcerer 547
	extern nsfb_surface_rtns_t ram_rtns;
548
	extern nsfb_surface_rtns_t able_rtns;
3624 sourcerer 549
	extern nsfb_surface_rtns_t kolibri_rtns;
3584 sourcerer 550
 
3624 sourcerer 551
	//_nsfb_register_surface(NSFB_SURFACE_SDL, &sdl_rtns, "sdl");
3584 sourcerer 552
	_nsfb_register_surface(NSFB_SURFACE_RAM, &ram_rtns, "ram");
3624 sourcerer 553
	_nsfb_register_surface(NSFB_SURFACE_ABLE, &able_rtns, "able");
554
	_nsfb_register_surface(NSFB_SURFACE_KOLIBRI, &kolibri_rtns, "kolibri");
3584 sourcerer 555
 
3624 sourcerer 556
	respaths = fb_init_resource("/hd0/1/res/:/bd0/1/res/:/tmp9/1/netsurf/res/:res/:fonts/");
3584 sourcerer 557
 
558
	options = filepath_find(respaths, "Choices");
559
	messages = filepath_find(respaths, "messages");
560
 
561
	netsurf_init(&argc, &argv, options, "res/messages");
562
 
563
	LOG(("NS init okay"));
564
 
565
	free(messages);
566
	free(options);
567
 
568
	LOG(("freed opts and msgs, start gui init"));
569
 
570
 
571
	gui_init(argc, argv);
572
 
573
	LOG(("calling browser_window_create in MAIN()"));
574
	bw = browser_window_create(feurl, 0, 0, true, false);
575
 
576
 
577
	LOG(("NS main loop..."));
578
 
579
	netsurf_main_loop();
580
 
581
	browser_window_destroy(bw);
582
 
583
	netsurf_exit();
584
 
585
	return 0;
586
}
587
 
588
 
589
void
590
gui_poll(bool active)
591
{
592
	LOG(("GUI poll in"));
593
 
594
	nsfb_event_t event;
595
	int timeout; /* timeout in miliseconds */
596
 
597
LOG(("schedule run"));
598
	/* run the scheduler and discover how long to wait for the next event */
599
	timeout = schedule_run();
600
 
601
	/* if active do not wait for event, return immediately */
602
	if (active)
603
		timeout = 0;
604
 
605
LOG(("redraw pending"));
606
	/* if redraws are pending do not wait for event, return immediately */
607
	if (fbtk_get_redraw_pending(fbtk))
608
		timeout = 0;
609
 
610
LOG(("fbtk event"));
611
	if (fbtk_event(fbtk, &event, timeout)) {
612
		if ((event.type == NSFB_EVENT_CONTROL) &&
613
		    (event.value.controlcode ==  NSFB_CONTROL_QUIT))
614
			netsurf_quit = true;
615
	}
616
 
617
LOG(("fbtk redraw"));
618
	fbtk_redraw(fbtk);
619
 
620
LOG(("GUI poll out success"));
621
}
622
 
623
void
624
gui_quit(void)
625
{
626
	LOG(("gui_quit"));
627
 
628
	urldb_save_cookies(nsoption_charp(cookie_jar));
629
 
630
	framebuffer_finalise();
631
}
632
 
633
/* called back when click in browser window */
634
static int
635
fb_browser_window_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
636
{
637
	struct gui_window *gw = cbi->context;
638
	struct browser_widget_s *bwidget = fbtk_get_userpw(widget);
639
	float scale = gw->bw->scale;
640
	int x = (cbi->x + bwidget->scrollx) / scale;
641
	int y = (cbi->y + bwidget->scrolly) / scale;
642
 
643
	if (cbi->event->type != NSFB_EVENT_KEY_DOWN &&
644
	    cbi->event->type != NSFB_EVENT_KEY_UP)
645
		return 0;
646
 
647
	LOG(("browser window clicked at %d,%d", cbi->x, cbi->y));
648
 
649
	switch (cbi->event->type) {
650
	case NSFB_EVENT_KEY_DOWN:
651
		switch (cbi->event->value.keycode) {
652
		case NSFB_KEY_MOUSE_1:
653
			browser_window_mouse_click(gw->bw,
654
					BROWSER_MOUSE_PRESS_1, x, y);
655
			gui_drag.state = GUI_DRAG_PRESSED;
656
			gui_drag.button = 1;
657
			gui_drag.x = x;
658
			gui_drag.y = y;
659
			break;
660
 
661
		case NSFB_KEY_MOUSE_3:
662
			browser_window_mouse_click(gw->bw,
663
					BROWSER_MOUSE_PRESS_2, x, y);
664
			gui_drag.state = GUI_DRAG_PRESSED;
665
			gui_drag.button = 2;
666
			gui_drag.x = x;
667
			gui_drag.y = y;
668
			break;
669
 
670
		case NSFB_KEY_MOUSE_4:
671
			/* scroll up */
672
			if (browser_window_scroll_at_point(gw->bw, x, y,
673
					0, -100) == false)
674
				widget_scroll_y(gw, -100, false);
675
			break;
676
 
677
		case NSFB_KEY_MOUSE_5:
678
			/* scroll down */
679
			if (browser_window_scroll_at_point(gw->bw, x, y,
680
					0, 100) == false)
681
				widget_scroll_y(gw, 100, false);
682
			break;
683
 
684
		default:
685
			break;
686
 
687
		}
688
 
689
		break;
690
	case NSFB_EVENT_KEY_UP:
691
		switch (cbi->event->value.keycode) {
692
		case NSFB_KEY_MOUSE_1:
693
			if (gui_drag.state == GUI_DRAG_DRAG) {
694
				/* End of a drag, rather than click */
695
 
696
				if (gui_drag.grabbed_pointer) {
697
					/* need to ungrab pointer */
698
					fbtk_tgrab_pointer(widget);
699
					gui_drag.grabbed_pointer = false;
700
				}
701
 
702
				gui_drag.state = GUI_DRAG_NONE;
703
 
704
				/* Tell core */
705
				browser_window_mouse_track(gw->bw, 0, x, y);
706
				break;
707
			}
708
			/* This is a click;
709
			 * clear PRESSED state and pass to core */
710
			gui_drag.state = GUI_DRAG_NONE;
711
			browser_window_mouse_click(gw->bw,
712
					BROWSER_MOUSE_CLICK_1, x, y);
713
			break;
714
 
715
		case NSFB_KEY_MOUSE_3:
716
			if (gui_drag.state == GUI_DRAG_DRAG) {
717
				/* End of a drag, rather than click */
718
				gui_drag.state = GUI_DRAG_NONE;
719
 
720
				if (gui_drag.grabbed_pointer) {
721
					/* need to ungrab pointer */
722
					fbtk_tgrab_pointer(widget);
723
					gui_drag.grabbed_pointer = false;
724
				}
725
 
726
				/* Tell core */
727
				browser_window_mouse_track(gw->bw, 0, x, y);
728
				break;
729
			}
730
			/* This is a click;
731
			 * clear PRESSED state and pass to core */
732
			gui_drag.state = GUI_DRAG_NONE;
733
			browser_window_mouse_click(gw->bw,
734
					BROWSER_MOUSE_CLICK_2, x, y);
735
			break;
736
 
737
		default:
738
			break;
739
 
740
		}
741
 
742
		break;
743
	default:
744
		break;
745
 
746
	}
747
	return 1;
748
}
749
 
750
/* called back when movement in browser window */
751
static int
752
fb_browser_window_move(fbtk_widget_t *widget, fbtk_callback_info *cbi)
753
{
754
	browser_mouse_state mouse = 0;
755
	struct gui_window *gw = cbi->context;
756
	struct browser_widget_s *bwidget = fbtk_get_userpw(widget);
757
	int x = (cbi->x + bwidget->scrollx) / gw->bw->scale;
758
	int y = (cbi->y + bwidget->scrolly) / gw->bw->scale;
759
 
760
	if (gui_drag.state == GUI_DRAG_PRESSED &&
761
			(abs(x - gui_drag.x) > 5 ||
762
			 abs(y - gui_drag.y) > 5)) {
763
		/* Drag started */
764
		if (gui_drag.button == 1) {
765
			browser_window_mouse_click(gw->bw,
766
					BROWSER_MOUSE_DRAG_1,
767
					gui_drag.x, gui_drag.y);
768
		} else {
769
			browser_window_mouse_click(gw->bw,
770
					BROWSER_MOUSE_DRAG_2,
771
					gui_drag.x, gui_drag.y);
772
		}
773
		gui_drag.grabbed_pointer = fbtk_tgrab_pointer(widget);
774
		gui_drag.state = GUI_DRAG_DRAG;
775
	}
776
 
777
	if (gui_drag.state == GUI_DRAG_DRAG) {
778
		/* set up mouse state */
779
		mouse |= BROWSER_MOUSE_DRAG_ON;
780
 
781
		if (gui_drag.button == 1)
782
			mouse |= BROWSER_MOUSE_HOLDING_1;
783
		else
784
			mouse |= BROWSER_MOUSE_HOLDING_2;
785
	}
786
 
787
	browser_window_mouse_track(gw->bw, mouse, x, y);
788
 
789
	return 0;
790
}
791
 
792
 
793
static int
794
fb_browser_window_input(fbtk_widget_t *widget, fbtk_callback_info *cbi)
795
{
796
	struct gui_window *gw = cbi->context;
797
	static fbtk_modifier_type modifier = FBTK_MOD_CLEAR;
798
	int ucs4 = -1;
799
 
800
	LOG(("got value %d", cbi->event->value.keycode));
801
 
802
	switch (cbi->event->type) {
803
	case NSFB_EVENT_KEY_DOWN:
804
		switch (cbi->event->value.keycode) {
805
 
806
		case NSFB_KEY_PAGEUP:
807
			if (browser_window_key_press(gw->bw,
808
					KEY_PAGE_UP) == false)
809
				widget_scroll_y(gw, -fbtk_get_height(
810
						gw->browser), false);
811
			break;
812
 
813
		case NSFB_KEY_PAGEDOWN:
814
			if (browser_window_key_press(gw->bw,
815
					KEY_PAGE_DOWN) == false)
816
				widget_scroll_y(gw, fbtk_get_height(
817
						gw->browser), false);
818
			break;
819
 
820
		case NSFB_KEY_RIGHT:
821
			if (modifier & FBTK_MOD_RCTRL ||
822
					modifier & FBTK_MOD_LCTRL) {
823
				/* CTRL held */
824
				if (browser_window_key_press(gw->bw,
825
						KEY_LINE_END) == false)
826
					widget_scroll_x(gw, INT_MAX, true);
827
 
828
			} else if (modifier & FBTK_MOD_RSHIFT ||
829
					modifier & FBTK_MOD_LSHIFT) {
830
				/* SHIFT held */
831
				if (browser_window_key_press(gw->bw,
832
						KEY_WORD_RIGHT) == false)
833
					widget_scroll_x(gw, fbtk_get_width(
834
						gw->browser), false);
835
 
836
			} else {
837
				/* no modifier */
838
				if (browser_window_key_press(gw->bw,
839
						KEY_RIGHT) == false)
840
					widget_scroll_x(gw, 100, false);
841
			}
842
			break;
843
 
844
		case NSFB_KEY_LEFT:
845
			if (modifier & FBTK_MOD_RCTRL ||
846
					modifier & FBTK_MOD_LCTRL) {
847
				/* CTRL held */
848
				if (browser_window_key_press(gw->bw,
849
						KEY_LINE_START) == false)
850
					widget_scroll_x(gw, 0, true);
851
 
852
			} else if (modifier & FBTK_MOD_RSHIFT ||
853
					modifier & FBTK_MOD_LSHIFT) {
854
				/* SHIFT held */
855
				if (browser_window_key_press(gw->bw,
856
						KEY_WORD_LEFT) == false)
857
					widget_scroll_x(gw, -fbtk_get_width(
858
						gw->browser), false);
859
 
860
			} else {
861
				/* no modifier */
862
				if (browser_window_key_press(gw->bw,
863
						KEY_LEFT) == false)
864
					widget_scroll_x(gw, -100, false);
865
			}
866
			break;
867
 
868
		case NSFB_KEY_UP:
869
			if (browser_window_key_press(gw->bw,
870
					KEY_UP) == false)
871
				widget_scroll_y(gw, -100, false);
872
			break;
873
 
874
		case NSFB_KEY_DOWN:
875
			if (browser_window_key_press(gw->bw,
876
					KEY_DOWN) == false)
877
				widget_scroll_y(gw, 100, false);
878
			break;
879
 
880
		case NSFB_KEY_RSHIFT:
881
			modifier |= FBTK_MOD_RSHIFT;
882
			break;
883
 
884
		case NSFB_KEY_LSHIFT:
885
			modifier |= FBTK_MOD_LSHIFT;
886
			break;
887
 
888
		case NSFB_KEY_RCTRL:
889
			modifier |= FBTK_MOD_RCTRL;
890
			break;
891
 
892
		case NSFB_KEY_LCTRL:
893
			modifier |= FBTK_MOD_LCTRL;
894
			break;
895
 
896
		default:
897
			ucs4 = fbtk_keycode_to_ucs4(cbi->event->value.keycode,
898
						    modifier);
899
			if (ucs4 != -1)
900
				browser_window_key_press(gw->bw, ucs4);
901
			break;
902
		}
903
		break;
904
 
905
	case NSFB_EVENT_KEY_UP:
906
		switch (cbi->event->value.keycode) {
907
		case NSFB_KEY_RSHIFT:
908
			modifier &= ~FBTK_MOD_RSHIFT;
909
			break;
910
 
911
		case NSFB_KEY_LSHIFT:
912
			modifier &= ~FBTK_MOD_LSHIFT;
913
			break;
914
 
915
		case NSFB_KEY_RCTRL:
916
			modifier &= ~FBTK_MOD_RCTRL;
917
			break;
918
 
919
		case NSFB_KEY_LCTRL:
920
			modifier &= ~FBTK_MOD_LCTRL;
921
			break;
922
 
923
		default:
924
			break;
925
		}
926
		break;
927
 
928
	default:
929
		break;
930
	}
931
 
932
	return 0;
933
}
934
 
935
static void
936
fb_update_back_forward(struct gui_window *gw)
937
{
938
	struct browser_window *bw = gw->bw;
939
 
940
	fbtk_set_bitmap(gw->back,
941
			(browser_window_back_available(bw)) ?
942
			&left_arrow : &left_arrow_g);
943
	fbtk_set_bitmap(gw->forward,
944
			(browser_window_forward_available(bw)) ?
945
			&right_arrow : &right_arrow_g);
946
}
947
 
948
/* left icon click routine */
949
static int
950
fb_leftarrow_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
951
{
952
	struct gui_window *gw = cbi->context;
953
	struct browser_window *bw = gw->bw;
954
 
955
	if (cbi->event->type != NSFB_EVENT_KEY_UP)
956
		return 0;
957
 
958
	if (history_back_available(bw->history))
959
		history_back(bw, bw->history);
960
 
961
	fb_update_back_forward(gw);
962
 
963
	return 1;
964
}
965
 
966
/* right arrow icon click routine */
967
static int
968
fb_rightarrow_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
969
{
970
	struct gui_window *gw = cbi->context;
971
	struct browser_window *bw = gw->bw;
972
 
973
	if (cbi->event->type != NSFB_EVENT_KEY_UP)
974
		return 0;
975
 
976
	if (history_forward_available(bw->history))
977
		history_forward(bw, bw->history);
978
 
979
	fb_update_back_forward(gw);
980
	return 1;
981
 
982
}
983
 
984
/* reload icon click routine */
985
static int
986
fb_reload_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
987
{
988
	struct browser_window *bw = cbi->context;
989
 
990
	if (cbi->event->type != NSFB_EVENT_KEY_UP)
991
		return 0;
992
 
993
	browser_window_reload(bw, true);
994
	return 1;
995
}
996
 
997
/* stop icon click routine */
998
static int
999
fb_stop_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
1000
{
1001
	struct browser_window *bw = cbi->context;
1002
 
1003
	if (cbi->event->type != NSFB_EVENT_KEY_UP)
1004
		return 0;
1005
 
1006
	browser_window_stop(bw);
1007
	return 0;
1008
}
1009
 
1010
static int
1011
fb_osk_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
1012
{
1013
 
1014
	if (cbi->event->type != NSFB_EVENT_KEY_UP)
1015
		return 0;
1016
 
1017
	map_osk();
1018
 
1019
	return 0;
1020
}
1021
 
1022
/* close browser window icon click routine */
1023
static int
1024
fb_close_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
1025
{
1026
	if (cbi->event->type != NSFB_EVENT_KEY_UP)
1027
		return 0;
1028
 
1029
	netsurf_quit = true;
1030
	return 0;
1031
}
1032
 
1033
static int
1034
fb_scroll_callback(fbtk_widget_t *widget, fbtk_callback_info *cbi)
1035
{
1036
	struct gui_window *gw = cbi->context;
1037
 
1038
	switch (cbi->type) {
1039
	case FBTK_CBT_SCROLLY:
1040
		widget_scroll_y(gw, cbi->y, true);
1041
		break;
1042
 
1043
	case FBTK_CBT_SCROLLX:
1044
		widget_scroll_x(gw, cbi->x, true);
1045
		break;
1046
 
1047
	default:
1048
		break;
1049
	}
1050
	return 0;
1051
}
1052
 
1053
static int
1054
fb_url_enter(void *pw, char *text)
1055
{
1056
	struct browser_window *bw = pw;
1057
	browser_window_go(bw, text, 0, true);
1058
	return 0;
1059
}
1060
 
1061
static int
1062
fb_url_move(fbtk_widget_t *widget, fbtk_callback_info *cbi)
1063
{
1064
	framebuffer_set_cursor(&caret_image);
1065
	return 0;
1066
}
1067
 
1068
static int
1069
set_ptr_default_move(fbtk_widget_t *widget, fbtk_callback_info *cbi)
1070
{
1071
	framebuffer_set_cursor(&pointer_image);
1072
	return 0;
1073
}
1074
 
1075
static int
1076
fb_localhistory_btn_clik(fbtk_widget_t *widget, fbtk_callback_info *cbi)
1077
{
1078
	struct gui_window *gw = cbi->context;
1079
 
1080
	if (cbi->event->type != NSFB_EVENT_KEY_UP)
1081
		return 0;
1082
 
1083
	fb_localhistory_map(gw->localhistory);
1084
 
1085
	return 0;
1086
}
1087
 
1088
 
1089
/** Create a toolbar window and populate it with buttons.
1090
 *
1091
 * The toolbar layout uses a character to define buttons type and position:
1092
 * b - back
1093
 * l - local history
1094
 * f - forward
1095
 * s - stop
1096
 * r - refresh
1097
 * u - url bar expands to fit remaining space
1098
 * t - throbber/activity indicator
1099
 * c - close the current window
1100
 *
1101
 * The default layout is "blfsrut" there should be no more than a
1102
 * single url bar entry or behaviour will be undefined.
1103
 *
1104
 * @param gw Parent window
1105
 * @param toolbar_height The height in pixels of the toolbar
1106
 * @param padding The padding in pixels round each element of the toolbar
1107
 * @param frame_col Frame colour.
1108
 * @param toolbar_layout A string defining which buttons and controls
1109
 *                       should be added to the toolbar. May be empty
1110
 *                       string to disable the bar..
1111
 *
1112
 */
1113
static fbtk_widget_t *
1114
create_toolbar(struct gui_window *gw,
1115
	       int toolbar_height,
1116
	       int padding,
1117
	       colour frame_col,
1118
	       const char *toolbar_layout)
1119
{
1120
	fbtk_widget_t *toolbar;
1121
	fbtk_widget_t *widget;
1122
 
1123
	int xpos; /* The position of the next widget. */
1124
	int xlhs = 0; /* extent of the left hand side widgets */
1125
	int xdir = 1; /* the direction of movement + or - 1 */
1126
	const char *itmtype; /* type of the next item */
1127
 
1128
	if (toolbar_layout == NULL) {
1129
		toolbar_layout = NSFB_TOOLBAR_DEFAULT_LAYOUT;
1130
	}
1131
 
1132
	LOG(("Using toolbar layout %s", toolbar_layout));
1133
 
1134
	itmtype = toolbar_layout;
1135
 
1136
	if (*itmtype == 0) {
1137
		return NULL;
1138
	}
1139
 
1140
	toolbar = fbtk_create_window(gw->window, 0, 0, 0,
1141
				     toolbar_height,
1142
				     frame_col);
1143
 
1144
	if (toolbar == NULL) {
1145
		return NULL;
1146
	}
1147
 
1148
	fbtk_set_handler(toolbar,
1149
			 FBTK_CBT_POINTERENTER,
1150
			 set_ptr_default_move,
1151
			 NULL);
1152
 
1153
 
1154
	xpos = padding;
1155
 
1156
	/* loop proceeds creating widget on the left hand side until
1157
	 * it runs out of layout or encounters a url bar declaration
1158
	 * wherupon it works backwards from the end of the layout
1159
	 * untill the space left is for the url bar
1160
	 */
1161
	while ((itmtype >= toolbar_layout) &&
1162
	       (*itmtype != 0) &&
1163
	       (xdir !=0)) {
1164
 
1165
		LOG(("toolbar adding %c", *itmtype));
1166
 
1167
 
1168
		switch (*itmtype) {
1169
 
1170
		case 'b': /* back */
1171
			widget = fbtk_create_button(toolbar,
1172
						    (xdir == 1) ? xpos :
1173
						     xpos - left_arrow.width,
1174
						    padding,
1175
						    left_arrow.width,
1176
						    -padding,
1177
						    frame_col,
1178
						    &left_arrow,
1179
						    fb_leftarrow_click,
1180
						    gw);
1181
			gw->back = widget; /* keep reference */
1182
			break;
1183
 
1184
		case 'l': /* local history */
1185
			widget = fbtk_create_button(toolbar,
1186
						    (xdir == 1) ? xpos :
1187
						     xpos - history_image.width,
1188
						    padding,
1189
						    history_image.width,
1190
						    -padding,
1191
						    frame_col,
1192
						    &history_image,
1193
						    fb_localhistory_btn_clik,
1194
						    gw);
1195
			break;
1196
 
1197
		case 'f': /* forward */
1198
			widget = fbtk_create_button(toolbar,
1199
						    (xdir == 1)?xpos :
1200
						     xpos - right_arrow.width,
1201
						    padding,
1202
						    right_arrow.width,
1203
						    -padding,
1204
						    frame_col,
1205
						    &right_arrow,
1206
						    fb_rightarrow_click,
1207
						    gw);
1208
			gw->forward = widget;
1209
			break;
1210
 
1211
		case 'c': /* close the current window */
1212
			widget = fbtk_create_button(toolbar,
1213
						    (xdir == 1)?xpos :
1214
						     xpos - stop_image_g.width,
1215
						    padding,
1216
						    stop_image_g.width,
1217
						    -padding,
1218
						    frame_col,
1219
						    &stop_image_g,
1220
						    fb_close_click,
1221
						    gw->bw);
1222
			break;
1223
 
1224
		case 's': /* stop  */
1225
			widget = fbtk_create_button(toolbar,
1226
						    (xdir == 1)?xpos :
1227
						     xpos - stop_image.width,
1228
						    padding,
1229
						    stop_image.width,
1230
						    -padding,
1231
						    frame_col,
1232
						    &stop_image,
1233
						    fb_stop_click,
1234
						    gw->bw);
1235
			break;
1236
 
1237
		case 'r': /* reload */
1238
			widget = fbtk_create_button(toolbar,
1239
						    (xdir == 1)?xpos :
1240
						     xpos - reload.width,
1241
						    padding,
1242
						    reload.width,
1243
						    -padding,
1244
						    frame_col,
1245
						    &reload,
1246
						    fb_reload_click,
1247
						    gw->bw);
1248
			break;
1249
 
1250
		case 't': /* throbber/activity indicator */
1251
			widget = fbtk_create_bitmap(toolbar,
1252
						    (xdir == 1)?xpos :
1253
						     xpos - throbber0.width,
1254
						    padding,
1255
						    throbber0.width,
1256
						    -padding,
1257
						    frame_col,
1258
						    &throbber0);
1259
			gw->throbber = widget;
1260
			break;
1261
 
1262
 
1263
		case 'u': /* url bar*/
1264
			if (xdir == -1) {
1265
				/* met the u going backwards add url
1266
				 * now we know available extent
1267
				 */
1268
 
1269
				widget = fbtk_create_writable_text(toolbar,
1270
						   xlhs,
1271
						   padding,
1272
						   xpos - xlhs,
1273
						   -padding,
1274
						   FB_COLOUR_WHITE,
1275
						   FB_COLOUR_BLACK,
1276
						   true,
1277
						   fb_url_enter,
1278
						   gw->bw);
1279
 
1280
				fbtk_set_handler(widget,
1281
						 FBTK_CBT_POINTERENTER,
1282
						 fb_url_move, gw->bw);
1283
 
1284
				gw->url = widget; /* keep reference */
1285
 
1286
				/* toolbar is complete */
1287
				xdir = 0;
1288
				break;
1289
			}
1290
			/* met url going forwards, note position and
1291
			 * reverse direction
1292
			 */
1293
			itmtype = toolbar_layout + strlen(toolbar_layout);
1294
			xdir = -1;
1295
			xlhs = xpos;
1296
			xpos = (2 * fbtk_get_width(toolbar));
1297
			widget = toolbar;
1298
			break;
1299
 
1300
		default:
1301
			widget = NULL;
1302
			xdir = 0;
1303
			LOG(("Unknown element %c in toolbar layout", *itmtype));
1304
		        break;
1305
 
1306
		}
1307
 
1308
		if (widget != NULL) {
1309
			xpos += (xdir * (fbtk_get_width(widget) + padding));
1310
		}
1311
 
1312
		LOG(("xpos is %d",xpos));
1313
 
1314
		itmtype += xdir;
1315
	}
1316
 
1317
	fbtk_set_mapping(toolbar, true);
1318
 
1319
	return toolbar;
1320
}
1321
 
1322
/** Routine called when "stripped of focus" event occours for browser widget.
1323
 *
1324
 * @param widget The widget reciving "stripped of focus" event.
1325
 * @param cbi The callback parameters.
1326
 * @return The callback result.
1327
 */
1328
static int
1329
fb_browser_window_strip_focus(fbtk_widget_t *widget, fbtk_callback_info *cbi)
1330
{
1331
	fbtk_set_caret(widget, false, 0, 0, 0, NULL);
1332
 
1333
	return 0;
1334
}
1335
 
1336
static void
1337
create_browser_widget(struct gui_window *gw, int toolbar_height, int furniture_width)
1338
{
1339
	struct browser_widget_s *browser_widget;
1340
	browser_widget = calloc(1, sizeof(struct browser_widget_s));
1341
 
1342
	gw->browser = fbtk_create_user(gw->window,
1343
				       0,
1344
				       toolbar_height,
1345
				       -furniture_width,
1346
				       -furniture_width,
1347
				       browser_widget);
1348
 
1349
	fbtk_set_handler(gw->browser, FBTK_CBT_REDRAW, fb_browser_window_redraw, gw);
1350
	fbtk_set_handler(gw->browser, FBTK_CBT_INPUT, fb_browser_window_input, gw);
1351
	fbtk_set_handler(gw->browser, FBTK_CBT_CLICK, fb_browser_window_click, gw);
1352
	fbtk_set_handler(gw->browser, FBTK_CBT_STRIP_FOCUS, fb_browser_window_strip_focus, gw);
1353
	fbtk_set_handler(gw->browser, FBTK_CBT_POINTERMOVE, fb_browser_window_move, gw);
1354
}
1355
 
1356
static void
1357
create_normal_browser_window(struct gui_window *gw, int furniture_width)
1358
{
1359
	LOG(("enter norm win"));
1360
	fbtk_widget_t *widget;
1361
	fbtk_widget_t *toolbar;
1362
	int statusbar_width = 0;
1363
	int toolbar_height = 30; //nsoption_int(fb_toolbar_size);
1364
 
1365
	LOG(("Normal window"));
1366
 
1367
	gw->window = fbtk_create_window(fbtk, 0, 0, 0, 0, 0);
1368
 
1369
	statusbar_width = nsoption_int(toolbar_status_width) *
1370
		fbtk_get_width(gw->window) / 10000;
1371
 
1372
LOG(("STUB options"));
1373
 
1374
 
1375
 
1376
	nsoptions.fb_depth = 16;
1377
	nsoptions.fb_refresh = 70;
1378
	nsoptions.fb_device = NULL;
1379
	nsoptions.fb_input_devpath = NULL;
1380
	nsoptions.fb_input_glob = NULL;
1381
	nsoptions.fb_furniture_size = 18;
1382
	nsoptions.fb_toolbar_size = 30;
1383
	nsoptions.fb_toolbar_layout = NULL;
1384
	nsoptions.fb_osk = false;
1385
 
1386
 
1387
 
1388
	/* toolbar */
1389
	LOG(("toolbar"));
1390
 
1391
 
1392
 
1393
	toolbar = create_toolbar(gw,
1394
				 toolbar_height,
1395
				 2,
1396
				 FB_FRAME_COLOUR,
1397
				 nsoption_charp(fb_toolbar_layout));
1398
 
1399
	/* set the actually created toolbar height */
1400
	if (toolbar != NULL) {
1401
		toolbar_height = fbtk_get_height(toolbar);
1402
	} else {
1403
		toolbar_height = 0;
1404
	}
1405
 
1406
	LOG(("statbar"));
1407
	/* status bar */
1408
	gw->status = fbtk_create_text(gw->window,
1409
				      0,
1410
				      fbtk_get_height(gw->window) - furniture_width,
1411
				      statusbar_width, furniture_width,
1412
				      FB_FRAME_COLOUR, FB_COLOUR_BLACK,
1413
				      false);
1414
 
1415
	LOG(("handler"));
1416
	fbtk_set_handler(gw->status, FBTK_CBT_POINTERENTER, set_ptr_default_move, NULL);
1417
 
1418
	LOG(("status bar %p at %d,%d", gw->status, fbtk_get_absx(gw->status), fbtk_get_absy(gw->status)));
1419
 
1420
	/* create horizontal scrollbar */
1421
	LOG(("hor sb"));
1422
 
1423
	gw->hscroll = fbtk_create_hscroll(gw->window,
1424
					  statusbar_width,
1425
					  fbtk_get_height(gw->window) - furniture_width,
1426
					  fbtk_get_width(gw->window) - statusbar_width - furniture_width,
1427
					  furniture_width,
1428
					  FB_SCROLL_COLOUR,
1429
					  FB_FRAME_COLOUR,
1430
					  fb_scroll_callback,
1431
					  gw);
1432
 
1433
	/* fill bottom right area */
1434
	LOG(("fill bottom"));
1435
 
1436
	if (nsoption_bool(fb_osk) == true) {
1437
		widget = fbtk_create_text_button(gw->window,
1438
						 fbtk_get_width(gw->window) - furniture_width,
1439
						 fbtk_get_height(gw->window) - furniture_width,
1440
						 furniture_width,
1441
						 furniture_width,
1442
						 FB_FRAME_COLOUR, FB_COLOUR_BLACK,
1443
						 fb_osk_click,
1444
						 NULL);
1445
		widget = fbtk_create_button(gw->window,
1446
				fbtk_get_width(gw->window) - furniture_width,
1447
				fbtk_get_height(gw->window) - furniture_width,
1448
				furniture_width,
1449
				furniture_width,
1450
				FB_FRAME_COLOUR,
1451
				&osk_image,
1452
				fb_osk_click,
1453
				NULL);
1454
	} else {
1455
		widget = fbtk_create_fill(gw->window,
1456
					  fbtk_get_width(gw->window) - furniture_width,
1457
					  fbtk_get_height(gw->window) - furniture_width,
1458
					  furniture_width,
1459
					  furniture_width,
1460
					  FB_FRAME_COLOUR);
1461
 
1462
		fbtk_set_handler(widget, FBTK_CBT_POINTERENTER, set_ptr_default_move, NULL);
1463
	}
1464
 
1465
	LOG(("vsb GUI"));
1466
	/* create vertical scrollbar */
1467
	gw->vscroll = fbtk_create_vscroll(gw->window,
1468
					  fbtk_get_width(gw->window) - furniture_width,
1469
					  toolbar_height,
1470
					  furniture_width,
1471
					  fbtk_get_height(gw->window) - toolbar_height - furniture_width,
1472
					  FB_SCROLL_COLOUR,
1473
					  FB_FRAME_COLOUR,
1474
					  fb_scroll_callback,
1475
					  gw);
1476
 
1477
	LOG(("BRO widget"));
1478
	/* browser widget */
1479
	create_browser_widget(gw, toolbar_height, nsoption_int(fb_furniture_size));
1480
 
1481
	LOG(("set focus"));
1482
	/* Give browser_window's user widget input focus */
1483
	fbtk_set_focus(gw->browser);
1484
	LOG(("GUI OK"));
1485
}
1486
 
1487
 
1488
struct gui_window *
1489
gui_create_browser_window(struct browser_window *bw,
1490
			  struct browser_window *clone,
1491
			  bool new_tab)
1492
{
1493
	struct gui_window *gw;
1494
	LOG(("GCBW calloc"));
1495
 
1496
	gw = calloc(1, sizeof(struct gui_window));
1497
 
1498
	if (gw == NULL)
1499
		return NULL;
1500
 
1501
	/* seems we need to associate the gui window with the underlying
1502
	 * browser window
1503
	 */
1504
	LOG(("GCBW next.."));
1505
 
1506
 
1507
	gw->bw = bw;
1508
 
1509
	LOG(("fb_furn_size is STUB now!..."));
1510
 
1511
	 //nsoption_int(fb_furniture_size);
1512
	LOG(("GCBW create normal window..."));
1513
 
1514
 
1515
	create_normal_browser_window(gw, 18); //nsoption_int(fb_furniture_size));
1516
	LOG(("GCBW create local history..."));
1517
 
1518
	gw->localhistory = fb_create_localhistory(bw, fbtk, nsoption_int(fb_furniture_size));
1519
 
1520
	/* map and request redraw of gui window */
1521
	LOG(("GCBW set mapping"));
1522
 
1523
	fbtk_set_mapping(gw->window, true);
1524
	LOG(("GCBW OK!"));
1525
 
1526
 
1527
	return gw;
1528
}
1529
 
1530
void
1531
gui_window_destroy(struct gui_window *gw)
1532
{
1533
	fbtk_destroy_widget(gw->window);
1534
 
1535
	free(gw);
1536
 
1537
 
1538
}
1539
 
1540
void
1541
gui_window_set_title(struct gui_window *g, const char *title)
1542
{
1543
	LOG(("%p, %s", g, title));
1544
}
1545
 
1546
void
1547
gui_window_redraw_window(struct gui_window *g)
1548
{
1549
	fb_queue_redraw(g->browser, 0, 0, fbtk_get_width(g->browser), fbtk_get_height(g->browser) );
1550
}
1551
 
1552
void
1553
gui_window_update_box(struct gui_window *g, const struct rect *rect)
1554
{
1555
	struct browser_widget_s *bwidget = fbtk_get_userpw(g->browser);
1556
	fb_queue_redraw(g->browser,
1557
			rect->x0 - bwidget->scrollx,
1558
			rect->y0 - bwidget->scrolly,
1559
			rect->x1 - bwidget->scrollx,
1560
			rect->y1 - bwidget->scrolly);
1561
}
1562
 
1563
bool
1564
gui_window_get_scroll(struct gui_window *g, int *sx, int *sy)
1565
{
1566
	struct browser_widget_s *bwidget = fbtk_get_userpw(g->browser);
1567
 
1568
	*sx = bwidget->scrollx / g->bw->scale;
1569
	*sy = bwidget->scrolly / g->bw->scale;
1570
 
1571
	return true;
1572
}
1573
 
1574
void
1575
gui_window_set_scroll(struct gui_window *gw, int sx, int sy)
1576
{
1577
	struct browser_widget_s *bwidget = fbtk_get_userpw(gw->browser);
1578
 
1579
	assert(bwidget);
1580
 
1581
	widget_scroll_x(gw, sx * gw->bw->scale, true);
1582
	widget_scroll_y(gw, sy * gw->bw->scale, true);
1583
}
1584
 
1585
void
1586
gui_window_scroll_visible(struct gui_window *g, int x0, int y0,
1587
			  int x1, int y1)
1588
{
1589
	LOG(("%s:(%p, %d, %d, %d, %d)", __func__, g, x0, y0, x1, y1));
1590
}
1591
 
1592
void
1593
gui_window_get_dimensions(struct gui_window *g,
1594
			  int *width,
1595
			  int *height,
1596
			  bool scaled)
1597
{
1598
	*width = fbtk_get_width(g->browser);
1599
	*height = fbtk_get_height(g->browser);
1600
 
1601
	if (scaled) {
1602
		*width /= g->bw->scale;
1603
		*height /= g->bw->scale;
1604
	}
1605
}
1606
 
1607
void
1608
gui_window_update_extent(struct gui_window *gw)
1609
{
1610
	float scale = gw->bw->scale;
1611
 
1612
	fbtk_set_scroll_parameters(gw->hscroll, 0,
1613
			content_get_width(gw->bw->current_content) * scale,
1614
			fbtk_get_width(gw->browser), 100);
1615
 
1616
	fbtk_set_scroll_parameters(gw->vscroll, 0,
1617
			content_get_height(gw->bw->current_content) * scale,
1618
			fbtk_get_height(gw->browser), 100);
1619
}
1620
 
1621
void
1622
gui_window_set_status(struct gui_window *g, const char *text)
1623
{
1624
	fbtk_set_text(g->status, text);
1625
}
1626
 
1627
void
1628
gui_window_set_pointer(struct gui_window *g, gui_pointer_shape shape)
1629
{
1630
	switch (shape) {
1631
	case GUI_POINTER_POINT:
1632
		framebuffer_set_cursor(&hand_image);
1633
		break;
1634
 
1635
	case GUI_POINTER_CARET:
1636
		framebuffer_set_cursor(&caret_image);
1637
		break;
1638
 
1639
	case GUI_POINTER_MENU:
1640
		framebuffer_set_cursor(&menu_image);
1641
		break;
1642
 
1643
	case GUI_POINTER_PROGRESS:
1644
		framebuffer_set_cursor(&progress_image);
1645
		break;
1646
 
1647
	case GUI_POINTER_MOVE:
1648
		framebuffer_set_cursor(&move_image);
1649
		break;
1650
 
1651
	default:
1652
		framebuffer_set_cursor(&pointer_image);
1653
		break;
1654
	}
1655
}
1656
 
1657
void
1658
gui_window_hide_pointer(struct gui_window *g)
1659
{
1660
}
1661
 
1662
void
1663
gui_window_set_url(struct gui_window *g, const char *url)
1664
{
1665
	fbtk_set_text(g->url, url);
1666
}
1667
 
1668
static void
1669
throbber_advance(void *pw)
1670
{
1671
	struct gui_window *g = pw;
1672
	struct fbtk_bitmap *image;
1673
 
1674
	switch (g->throbber_index) {
1675
	case 0:
1676
		image = &throbber1;
1677
		g->throbber_index = 1;
1678
		break;
1679
 
1680
	case 1:
1681
		image = &throbber2;
1682
		g->throbber_index = 2;
1683
		break;
1684
 
1685
	case 2:
1686
		image = &throbber3;
1687
		g->throbber_index = 3;
1688
		break;
1689
 
1690
	case 3:
1691
		image = &throbber4;
1692
		g->throbber_index = 4;
1693
		break;
1694
 
1695
	case 4:
1696
		image = &throbber5;
1697
		g->throbber_index = 5;
1698
		break;
1699
 
1700
	case 5:
1701
		image = &throbber6;
1702
		g->throbber_index = 6;
1703
		break;
1704
 
1705
	case 6:
1706
		image = &throbber7;
1707
		g->throbber_index = 7;
1708
		break;
1709
 
1710
	case 7:
1711
		image = &throbber8;
1712
		g->throbber_index = 0;
1713
		break;
1714
 
1715
	default:
1716
		return;
1717
	}
1718
 
1719
	if (g->throbber_index >= 0) {
1720
		fbtk_set_bitmap(g->throbber, image);
1721
		schedule(10, throbber_advance, g);
1722
	}
1723
}
1724
 
1725
void
1726
gui_window_start_throbber(struct gui_window *g)
1727
{
1728
	g->throbber_index = 0;
1729
	schedule(10, throbber_advance, g);
1730
}
1731
 
1732
void
1733
gui_window_stop_throbber(struct gui_window *gw)
1734
{
1735
	gw->throbber_index = -1;
1736
	fbtk_set_bitmap(gw->throbber, &throbber0);
1737
 
1738
	fb_update_back_forward(gw);
1739
 
1740
}
1741
 
1742
static void
1743
gui_window_remove_caret_cb(fbtk_widget_t *widget)
1744
{
1745
	struct browser_widget_s *bwidget = fbtk_get_userpw(widget);
1746
	int c_x, c_y, c_h;
1747
 
1748
	if (fbtk_get_caret(widget, &c_x, &c_y, &c_h)) {
1749
		/* browser window already had caret:
1750
		 * redraw its area to remove it first */
1751
		fb_queue_redraw(widget,
1752
				c_x - bwidget->scrollx,
1753
				c_y - bwidget->scrolly,
1754
				c_x + 1 - bwidget->scrollx,
1755
				c_y + c_h - bwidget->scrolly);
1756
	}
1757
}
1758
 
1759
void
1760
gui_window_place_caret(struct gui_window *g, int x, int y, int height)
1761
{
1762
	struct browser_widget_s *bwidget = fbtk_get_userpw(g->browser);
1763
 
1764
	/* set new pos */
1765
	fbtk_set_caret(g->browser, true, x, y, height,
1766
			gui_window_remove_caret_cb);
1767
 
1768
	/* redraw new caret pos */
1769
	fb_queue_redraw(g->browser,
1770
			x - bwidget->scrollx,
1771
			y - bwidget->scrolly,
1772
			x + 1 - bwidget->scrollx,
1773
			y + height - bwidget->scrolly);
1774
}
1775
 
1776
void
1777
gui_window_remove_caret(struct gui_window *g)
1778
{
1779
	int c_x, c_y, c_h;
1780
 
1781
	if (fbtk_get_caret(g->browser, &c_x, &c_y, &c_h)) {
1782
		/* browser window owns the caret, so can remove it */
1783
		fbtk_set_caret(g->browser, false, 0, 0, 0, NULL);
1784
	}
1785
}
1786
 
1787
void
1788
gui_window_new_content(struct gui_window *g)
1789
{
1790
}
1791
 
1792
bool
1793
gui_window_scroll_start(struct gui_window *g)
1794
{
1795
	return true;
1796
}
1797
 
1798
bool
1799
gui_window_drag_start(struct gui_window *g, gui_drag_type type,
1800
                      const struct rect *rect)
1801
{
1802
	return true;
1803
}
1804
 
1805
void
1806
gui_window_save_link(struct gui_window *g, const char *url, const char *title)
1807
{
1808
}
1809
 
1810
/**
1811
 * set favicon
1812
 */
1813
void
1814
gui_window_set_icon(struct gui_window *g, hlcache_handle *icon)
1815
{
1816
}
1817
 
1818
/**
1819
 * set gui display of a retrieved favicon representing the search provider
1820
 * \param ico may be NULL for local calls; then access current cache from
1821
 * search_web_ico()
1822
 */
1823
void
1824
gui_window_set_search_ico(hlcache_handle *ico)
1825
{
1826
}
1827
 
1828
struct gui_download_window *
1829
gui_download_window_create(download_context *ctx, struct gui_window *parent)
1830
{
1831
	return NULL;
1832
}
1833
 
1834
nserror
1835
gui_download_window_data(struct gui_download_window *dw,
1836
			 const char *data,
1837
			 unsigned int size)
1838
{
1839
	return NSERROR_OK;
1840
}
1841
 
1842
void
1843
gui_download_window_error(struct gui_download_window *dw,
1844
			  const char *error_msg)
1845
{
1846
}
1847
 
1848
void
1849
gui_download_window_done(struct gui_download_window *dw)
1850
{
1851
}
1852
 
1853
void
1854
gui_drag_save_object(gui_save_type type,
1855
		     hlcache_handle *c,
1856
		     struct gui_window *w)
1857
{
1858
}
1859
 
1860
void
1861
gui_drag_save_selection(struct selection *s, struct gui_window *g)
1862
{
1863
}
1864
 
1865
void
1866
gui_start_selection(struct gui_window *g)
1867
{
1868
}
1869
 
1870
void
1871
gui_clear_selection(struct gui_window *g)
1872
{
1873
}
1874
 
1875
void
1876
gui_create_form_select_menu(struct browser_window *bw,
1877
			    struct form_control *control)
1878
{
1879
}
1880
 
1881
void
1882
gui_launch_url(const char *url)
1883
{
1884
}
1885
 
1886
void
1887
gui_cert_verify(nsurl *url,
1888
		const struct ssl_cert_info *certs,
1889
		unsigned long num,
1890
		nserror (*cb)(bool proceed, void *pw),
1891
		void *cbpw)
1892
{
1893
	cb(false, cbpw);
1894
}
1895
 
1896
/*
1897
 * Local Variables:
1898
 * c-basic-offset:8
1899
 * End:
1900
 */