Subversion Repositories Kolibri OS

Rev

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