NetSurf
theme.c
Go to the documentation of this file.
1/*
2 * Copyright 2010 Chris Young <chris@unsatisfactorysoftware.co.uk>
3 *
4 * This file is part of NetSurf, http://www.netsurf-browser.org/
5 *
6 * NetSurf is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * NetSurf is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include "amiga/os3support.h"
20
21#include <stdlib.h>
22#include <string.h>
23
24#include <proto/clicktab.h>
25#include <proto/datatypes.h>
26#include <proto/dos.h>
27#include <proto/exec.h>
28#include <proto/graphics.h>
29#include <proto/icon.h>
30#include <proto/intuition.h>
31
32#include <gadgets/clicktab.h>
33#include <gadgets/space.h>
34#ifdef __amigaos4__
35#include <graphics/blitattr.h>
36#endif
37#include <intuition/pointerclass.h>
38#include <workbench/icon.h>
39
40#include "utils/messages.h"
41#include "utils/nsoption.h"
42#include "utils/utils.h"
43#include "desktop/searchweb.h"
44#include "netsurf/mouse.h"
45#include "netsurf/window.h"
46
47#include "amiga/gui.h"
48#include "amiga/drag.h"
49#include "amiga/bitmap.h"
50#include "amiga/plotters.h"
51#include "amiga/schedule.h"
52#include "amiga/theme.h"
53#include "amiga/misc.h"
54
55static struct BitMap *throbber = NULL;
56static struct bitmap *throbber_nsbm = NULL;
57static int throbber_frames = 1;
59static Object *mouseptrobj[AMI_LASTPOINTER+1];
60static struct BitMap *mouseptrbm[AMI_LASTPOINTER+1];
61
62const char *ptrs[AMI_LASTPOINTER+1] = {
63 "ptr_default",
64 "ptr_point",
65 "ptr_caret",
66 "ptr_menu",
67 "ptr_up",
68 "ptr_down",
69 "ptr_left",
70 "ptr_right",
71 "ptr_rightup",
72 "ptr_leftdown",
73 "ptr_leftup",
74 "ptr_rightdown",
75 "ptr_cross",
76 "ptr_move",
77 "ptr_wait",
78 "ptr_help",
79 "ptr_nodrop",
80 "ptr_notallowed",
81 "ptr_progress",
82 "ptr_blank",
83 "ptr_drag"};
84
85const char *ptrs32[AMI_LASTPOINTER+1] = {
86 "ptr32_default",
87 "ptr32_point",
88 "ptr32_caret",
89 "ptr32_menu",
90 "ptr32_up",
91 "ptr32_down",
92 "ptr32_left",
93 "ptr32_right",
94 "ptr32_rightup",
95 "ptr32_leftdown",
96 "ptr32_leftup",
97 "ptr32_rightdown",
98 "ptr32_cross",
99 "ptr32_move",
100 "ptr32_wait",
101 "ptr32_help",
102 "ptr32_nodrop",
103 "ptr32_notallowed",
104 "ptr32_progress",
105 "ptr32_blank",
106 "ptr32_drag"};
107
108#ifdef __amigaos4__
109/* Mapping from NetSurf to AmigaOS mouse pointers */
110int osmouseptr[AMI_LASTPOINTER+1] = {
111 POINTERTYPE_NORMAL,
112 POINTERTYPE_LINK,
113 POINTERTYPE_TEXT,
114 POINTERTYPE_CONTEXTMENU,
115 POINTERTYPE_NORTHRESIZE,
116 POINTERTYPE_SOUTHRESIZE,
117 POINTERTYPE_WESTRESIZE,
118 POINTERTYPE_EASTRESIZE,
119 POINTERTYPE_NORTHEASTRESIZE,
120 POINTERTYPE_SOUTHWESTRESIZE,
121 POINTERTYPE_NORTHWESTRESIZE,
122 POINTERTYPE_SOUTHEASTRESIZE,
123 POINTERTYPE_CROSS,
124 POINTERTYPE_HAND,
125 POINTERTYPE_BUSY,
126 POINTERTYPE_HELP,
127 POINTERTYPE_NODROP,
128 POINTERTYPE_NOTALLOWED,
129 POINTERTYPE_PROGRESS,
130 POINTERTYPE_NONE,
131 POINTERTYPE_DRAGANDDROP};
132#endif
133
135{
136 char themefile[1024];
137 BPTR lock = 0;
138
139 strcpy(themefile,nsoption_charp(theme));
140 AddPart(themefile,"Theme",100);
141
142 lock = Lock(themefile,ACCESS_READ);
143
144 if(!lock)
145 {
146 amiga_warn_user("ThemeApplyErr",nsoption_charp(theme));
147 strcpy(themefile,"PROGDIR:Resources/Themes/Default/Theme");
148 nsoption_set_charp(theme, (char *)strdup("PROGDIR:Resources/Themes/Default"));
149 }
150 else
151 {
152 UnLock(lock);
153 }
154
155 lock = Lock(themefile,ACCESS_READ);
156 if(lock)
157 {
158 UnLock(lock);
159 messages_add_from_file(themefile);
160 }
161}
162
164{
166}
167
169{
171}
172
174{
175 char throbberfile[1024];
176 struct bitmap *bm;
177
178 ami_get_theme_filename(throbberfile,"theme_throbber",false);
179 throbber_frames=atoi(messages_get("theme_throbber_frames"));
180 if(throbber_frames == 0) throbber_frames = 1;
181 throbber_update_interval = atoi(messages_get("theme_throbber_delay"));
183
184 bm = ami_bitmap_from_datatype(throbberfile);
187
188 throbber_nsbm = bm;
189}
190
192{
194 throbber_nsbm = NULL;
195 throbber = NULL;
196}
197
198void ami_get_theme_filename(char *filename, const char *themestring, bool protocol)
199{
200 if(protocol)
201 strcpy(filename,"file:///");
202 else
203 strcpy(filename,"");
204
205 if(messages_get(themestring)[0] == '*')
206 {
207 strncat(filename,messages_get(themestring)+1,100);
208 }
209 else
210 {
211 strcat(filename, nsoption_charp(theme));
212 AddPart(filename, messages_get(themestring), 100);
213 }
214}
215
217{
219}
220
221void ami_update_pointer(struct Window *win, gui_pointer_shape shape)
222{
223 if(ami_drag_has_data()) return; /**\todo check this shouldn't be drag_in_progress */
224
225 if(LIB_IS_AT_LEAST((struct Library *)IntuitionBase, 53, 42)) {
226#ifdef __amigaos4__
227 BOOL ptr_delay = FALSE;
228 if(shape == GUI_POINTER_WAIT) ptr_delay = TRUE;
229
230 SetWindowPointer(win,
231 WA_PointerType, osmouseptr[shape],
232 WA_PointerDelay, ptr_delay,
233 TAG_DONE);
234#endif
235 } else {
236 if(nsoption_bool(os_mouse_pointers))
237 {
238 switch(shape)
239 {
241 SetWindowPointer(win, TAG_DONE);
242 break;
243
244 case GUI_POINTER_WAIT:
245 SetWindowPointer(win,
246 WA_BusyPointer, TRUE,
247 WA_PointerDelay, TRUE,
248 TAG_DONE);
249 break;
250
251 default:
252 if(mouseptrobj[shape]) {
253 SetWindowPointer(win, WA_Pointer, mouseptrobj[shape], TAG_DONE);
254 } else {
255 SetWindowPointer(win, TAG_DONE);
256 }
257 break;
258 }
259 }
260 else
261 {
262 if(mouseptrobj[shape])
263 {
264 SetWindowPointer(win, WA_Pointer, mouseptrobj[shape], TAG_DONE);
265 }
266 else
267 {
268 if(shape == GUI_POINTER_WAIT)
269 {
270 SetWindowPointer(win,
271 WA_BusyPointer, TRUE,
272 WA_PointerDelay, TRUE,
273 TAG_DONE);
274 }
275 else
276 {
277 SetWindowPointer(win, TAG_DONE);
278 }
279 }
280 }
281 }
282}
283
285{
286 if(LIB_IS_AT_LEAST((struct Library *)IntuitionBase, 53, 42)) return;
287
288 int i;
289 struct RastPort mouseptr;
290 struct DiskObject *dobj;
291 uint32 format = IDFMT_BITMAPPED;
292 int32 mousexpt=0,mouseypt=0;
293
294 InitRastPort(&mouseptr);
295
296 for(i=0; i<=AMI_LASTPOINTER; i++) {
297 BPTR ptrfile;
298 mouseptrbm[i] = NULL;
299 mouseptrobj[i] = NULL;
300 char ptrfname[1024];
301
302#ifdef __amigaos4__
303 if(nsoption_bool(truecolour_mouse_pointers)) {
304 ami_get_theme_filename((char *)&ptrfname,ptrs32[i], false);
305 if((dobj = GetIconTags(ptrfname,ICONGETA_UseFriendBitMap,TRUE,TAG_DONE))) {
306 if(IconControl(dobj, ICONCTRLA_GetImageDataFormat, &format, TAG_DONE)) {
307 if(IDFMT_DIRECTMAPPED == format) {
308 int32 width = 0, height = 0;
309 uint8* data = 0;
310 IconControl(dobj,
311 ICONCTRLA_GetWidth, &width,
312 ICONCTRLA_GetHeight, &height,
313 ICONCTRLA_GetImageData1, &data,
314 TAG_DONE);
315
316 if ((width > 0) && (width <= 64) && (height > 0) && (height <= 64) && data) {
317 STRPTR tooltype;
318
319 if((tooltype = FindToolType(dobj->do_ToolTypes, "XOFFSET")))
320 mousexpt = atoi(tooltype);
321
322 if((tooltype = FindToolType(dobj->do_ToolTypes, "YOFFSET")))
323 mouseypt = atoi(tooltype);
324
325 if ((mousexpt < 0) || (mousexpt >= width))
326 mousexpt = 0;
327 if ((mouseypt < 0) || (mouseypt >= height))
328 mouseypt = 0;
329
330 static uint8 dummyPlane[64 * 64 / 8];
331 static struct BitMap dummyBitMap = { 64 / 8, 64, 0, 2, 0, { dummyPlane, dummyPlane, 0, 0, 0, 0, 0, 0 }, };
332
333 mouseptrobj[i] = NewObject(NULL, "pointerclass",
334 POINTERA_BitMap, &dummyBitMap,
335 POINTERA_XOffset, -mousexpt,
336 POINTERA_YOffset, -mouseypt,
337 POINTERA_WordWidth, (width + 15) / 16,
338 POINTERA_XResolution, POINTERXRESN_SCREENRES,
339 POINTERA_YResolution, POINTERYRESN_SCREENRESASPECT,
340 POINTERA_ImageData, data,
341 POINTERA_Width, width,
342 POINTERA_Height, height,
343 TAG_DONE);
344 }
345 }
346 }
347 }
348 }
349#endif
350
351 if(!mouseptrobj[i])
352 {
353 ami_get_theme_filename(ptrfname,ptrs[i], false);
354 if((ptrfile = Open(ptrfname,MODE_OLDFILE)))
355 {
356 int mx,my;
357 UBYTE *pprefsbuf = malloc(1061);
358 Read(ptrfile, pprefsbuf, 1061);
359
360 mouseptrbm[i] = malloc(sizeof(struct BitMap));
361 InitBitMap(mouseptrbm[i], 2, 32, 32);
362 mouseptrbm[i]->Planes[0] = AllocRaster(32, 32);
363 mouseptrbm[i]->Planes[1] = AllocRaster(32, 32);
364 mouseptr.BitMap = mouseptrbm[i];
365
366 for(my=0;my<32;my++)
367 {
368 for(mx=0;mx<32;mx++)
369 {
370 SetAPen(&mouseptr,pprefsbuf[(my*(33))+mx]-'0');
371 WritePixel(&mouseptr,mx,my);
372 }
373 }
374
375 mousexpt = ((pprefsbuf[1056]-'0')*10)+(pprefsbuf[1057]-'0');
376 mouseypt = ((pprefsbuf[1059]-'0')*10)+(pprefsbuf[1060]-'0');
377
378 mouseptrobj[i] = NewObject(NULL,"pointerclass",
379 POINTERA_BitMap,mouseptrbm[i],
380 POINTERA_WordWidth,2,
381 POINTERA_XOffset,-mousexpt,
382 POINTERA_YOffset,-mouseypt,
383 POINTERA_XResolution,POINTERXRESN_SCREENRES,
384 POINTERA_YResolution,POINTERYRESN_SCREENRESASPECT,
385 TAG_DONE);
386
387 free(pprefsbuf);
388 Close(ptrfile);
389 }
390
391 }
392
393 } // for
394}
395
397{
398 if(LIB_IS_AT_LEAST((struct Library *)IntuitionBase, 53, 42)) return;
399
400 int i;
401
402 for(i=0;i<=AMI_LASTPOINTER;i++)
403 {
404 if(mouseptrbm[i])
405 {
406 FreeRaster(mouseptrbm[i]->Planes[0],32,32);
407 FreeRaster(mouseptrbm[i]->Planes[1],32,32);
408 free(mouseptrbm[i]);
409 }
410 }
411}
412
414{
415 if(!g) return;
416 if(nsoption_bool(kiosk_mode)) return;
417
418#ifdef __amigaos4__
420 {
421 SetClickTabNodeAttrs(ami_gui_get_tab_node(g), TNA_Flagged, TRUE, TAG_DONE);
423 ami_gui_get_window(g), NULL);
424 }
425#endif
426
427 ami_gui_set_throbbing(g, true);
430}
431
433{
434 struct IBox *bbox;
435
436 if(!g) return;
437 if(nsoption_bool(kiosk_mode)) return;
438
439#ifdef __amigaos4__
441 {
442 SetClickTabNodeAttrs(ami_gui_get_tab_node(g), TNA_Flagged, FALSE, TAG_DONE);
444 ami_gui_get_window(g), NULL);
445 }
446#endif
447
450 amiga_warn_user("NoMemory", "");
451 return;
452 }
453
454 if(throbber != NULL) {
455 BltBitMapRastPort(throbber, 0, 0, ami_gui_get_window(g)->RPort,
456 bbox->Left, bbox->Top,
458 0x0C0);
459 }
461 }
462
463 ami_gui_set_throbbing(g, false);
465}
466
467static void ami_throbber_update(void *p)
468{
469 struct gui_window *g = (struct gui_window *)p;
470 struct IBox *bbox;
471 int frame = 0;
472
473 if(!g) return;
475
476 if(ami_gui_get_throbbing(g) == true) {
478 ami_gui_set_throbber_frame(g, frame + 1);
481 }
482
485 amiga_warn_user("NoMemory", "");
486 return;
487 }
488
489 if(throbber != NULL) {
490#ifdef __amigaos4__
491 BltBitMapTags(BLITA_SrcX, ami_theme_throbber_get_width() * frame,
492 BLITA_SrcY, 0,
493 BLITA_DestX, bbox->Left,
494 BLITA_DestY, bbox->Top,
495 BLITA_Width, ami_theme_throbber_get_width(),
496 BLITA_Height, ami_theme_throbber_get_height(),
497 BLITA_Source, throbber,
498 BLITA_Dest, ami_gui_get_window(g)->RPort,
499 BLITA_SrcType, BLITT_BITMAP,
500 BLITA_DestType, BLITT_RASTPORT,
501 // BLITA_UseSrcAlpha, TRUE,
502 TAG_DONE);
503#else
504 BltBitMapRastPort(throbber, ami_theme_throbber_get_width() * frame,
505 0, ami_gui_get_window(g)->RPort,
506 bbox->Left, bbox->Top,
508 0xC0);
509#endif
510 }
512 }
513
515}
516
518{
520}
521
struct Window * ami_gui_get_window(struct gui_window *gw)
Get window from gui_window.
Definition: gui.c:576
struct Node * ami_gui_get_tab_node(struct gui_window *gw)
Get tab node from gui_window.
Definition: gui.c:462
void ami_gui_set_throbbing(struct gui_window *gw, bool throbbing)
Set throbbing status in gui_window.
Definition: gui.c:514
void ami_set_pointer(struct gui_window_2 *gwin, gui_pointer_shape shape, bool update)
Definition: gui.c:688
bool ami_gui_get_throbbing(struct gui_window *gw)
Get throbbing status from gui_window.
Definition: gui.c:508
nserror ami_gui_get_space_box(Object *obj, struct IBox **bbox)
Compatibility function to get space.gadget render area.
Definition: gui.c:1857
Object * ami_gui2_get_object(struct gui_window_2 *gwin, int object_type)
Get object from gui_window.
Definition: gui.c:534
int ami_gui_get_throbber_frame(struct gui_window *gw)
Get throbbing frame from gui_window.
Definition: gui.c:520
ULONG ami_gui2_get_tabs(struct gui_window_2 *gwin)
Get tabs from gui_window_2.
Definition: gui.c:468
void ami_gui_free_space_box(struct IBox *bbox)
Free any data obtained via ami_gui_get_space_box().
Definition: gui.c:1874
struct gui_window_2 * ami_gui_get_gui_window_2(struct gui_window *gw)
Get gui_window_2 from gui_window.
Definition: gui.c:437
void ami_gui_set_throbber_frame(struct gui_window *gw, int frame)
Set throbbing frame in gui_window.
Definition: gui.c:527
#define IS_CURRENT_GW(GWIN, GW)
Definition: gui.h:78
@ AMI_GAD_TABS
Definition: gui.h:44
@ AMI_GAD_THROBBER
Definition: gui.h:43
nserror amiga_warn_user(const char *warning, const char *detail)
Warn the user of an event.
Definition: misc.c:79
bool ami_plot_screen_is_palettemapped(void)
Definition: plotters.c:610
nserror ami_schedule(int t, void(*callback)(void *p), void *p)
Schedule a callback.
Definition: schedule.c:331
void ami_mouse_pointers_free(void)
Definition: theme.c:396
void gui_window_stop_throbber(struct gui_window *g)
Definition: theme.c:432
void ami_theme_throbber_free(void)
Definition: theme.c:191
void gui_window_set_pointer(struct gui_window *g, gui_pointer_shape shape)
Change mouse pointer shape.
Definition: theme.c:216
int ami_theme_throbber_get_width(void)
Definition: theme.c:163
const char * ptrs32[AMI_LASTPOINTER+1]
Definition: theme.c:85
static Object * mouseptrobj[AMI_LASTPOINTER+1]
Definition: theme.c:59
void gui_window_start_throbber(struct gui_window *g)
Definition: theme.c:413
static struct BitMap * mouseptrbm[AMI_LASTPOINTER+1]
Definition: theme.c:60
static void ami_throbber_update(void *p)
Definition: theme.c:467
static int throbber_update_interval
Definition: theme.c:58
static int throbber_frames
Definition: theme.c:57
void ami_theme_init(void)
Definition: theme.c:134
void ami_init_mouse_pointers(void)
Definition: theme.c:284
const char * ptrs[AMI_LASTPOINTER+1]
Definition: theme.c:62
void ami_theme_throbber_setup(void)
Definition: theme.c:173
void ami_throbber_redraw_schedule(int t, struct gui_window *g)
Definition: theme.c:517
int ami_theme_throbber_get_height(void)
Definition: theme.c:168
static struct bitmap * throbber_nsbm
Definition: theme.c:56
void ami_update_pointer(struct Window *win, gui_pointer_shape shape)
Definition: theme.c:221
void ami_get_theme_filename(char *filename, const char *themestring, bool protocol)
Definition: theme.c:198
bool ami_drag_has_data(void)
Definition: drag.c:329
@ NSERROR_OK
No error.
Definition: errors.h:30
struct BitMap * ami_bitmap_get_native(struct bitmap *bitmap, int width, int height, bool palette_mapped, struct BitMap *friendbm)
Definition: bitmap.c:666
int bitmap_get_width(void *bitmap)
get width of a bitmap.
Definition: bitmap.c:319
int bitmap_get_height(void *bitmap)
get height of a bitmap.
Definition: bitmap.c:336
struct bitmap * ami_bitmap_from_datatype(char *filename)
Definition: bitmap.c:407
void amiga_bitmap_destroy(void *bitmap)
Free a bitmap.
Definition: bitmap.c:213
#define AMI_LASTPOINTER
Definition: theme.h:29
Core mouse and pointer states.
gui_pointer_shape
Definition: mouse.h:89
@ GUI_POINTER_WAIT
Definition: mouse.h:104
@ GUI_POINTER_DEFAULT
Definition: mouse.h:90
Interface to platform-specific graphical user interface window operations.
nserror messages_add_from_file(const char *path)
Read keys and values from messages file into the standard Messages hash.
Definition: messages.c:177
const char * messages_get(const char *key)
Fast lookup of a message by key from the standard Messages hash.
Definition: messages.c:241
Localised message support (interface).
APTR NewObject(struct IClass *classPtr, CONST_STRPTR classID, ULONG tagList,...)
Definition: os3support.c:434
Minimal compatibility header for AmigaOS 3.
#define ICONCTRLA_GetImageDataFormat
Definition: os3support.h:218
#define LIB_IS_AT_LEAST(B, V, R)
Definition: os3support.h:55
uint8_t uint8
Definition: os3support.h:180
#define IDFMT_BITMAPPED
Definition: os3support.h:220
int32_t int32
Definition: os3support.h:183
uint32_t uint32
Definition: os3support.h:184
#define IDFMT_DIRECTMAPPED
Definition: os3support.h:222
int width
Definition: gui.c:159
int height
Definition: gui.c:160
core web search facilities interface.
Interface to utility string handling.
RISC OS wimp toolkit bitmap.
Definition: bitmap.c:68
first entry in window list
Definition: gui.c:296
Definition: theme.h:64
Option reading and saving interface.
#define nsoption_charp(OPTION)
Get the value of a string option.
Definition: nsoption.h:297
#define nsoption_set_charp(OPTION, VALUE)
set string option in default table
Definition: nsoption.h:338
#define nsoption_bool(OPTION)
Get the value of a boolean option.
Definition: nsoption.h:270
Interface to a number of general purpose functionality.