Subversion Repositories Kolibri OS

Rev

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