summaryrefslogtreecommitdiff
path: root/amiga
diff options
context:
space:
mode:
authorChris Young <chris@unsatisfactorysoftware.co.uk>2015-09-03 19:57:04 +0100
committerChris Young <chris@unsatisfactorysoftware.co.uk>2015-09-03 19:57:04 +0100
commitcdaae7b30e22373b99117438a15e062e8749688d (patch)
treea45eeaf68ce050d47be199508acb07663f81a42f /amiga
parent944248ce3205881df9268d2c3f9f0cb52fc2f075 (diff)
downloadnetsurf-cdaae7b30e22373b99117438a15e062e8749688d.tar.gz
netsurf-cdaae7b30e22373b99117438a15e062e8749688d.tar.bz2
Add a couple of context menu items for links for testing.
Diffstat (limited to 'amiga')
-rw-r--r--amiga/ctxmenu.c165
-rw-r--r--amiga/ctxmenu.h19
-rw-r--r--amiga/gui.c11
-rw-r--r--[-rwxr-xr-x]amiga/gui.h3
4 files changed, 159 insertions, 39 deletions
diff --git a/amiga/ctxmenu.c b/amiga/ctxmenu.c
index 2b7575321..bf16e21b0 100644
--- a/amiga/ctxmenu.c
+++ b/amiga/ctxmenu.c
@@ -23,29 +23,43 @@
#ifdef __amigaos4__
#include <string.h>
+#include <proto/exec.h>
#include <proto/intuition.h>
-#include <classes/window.h>
+
+#include <proto/bitmap.h>
#include <images/bitmap.h>
+#include <proto/window.h>
+#include <classes/window.h>
+
#include <intuition/menuclass.h>
#include <reaction/reaction_macros.h>
#include "amiga/ctxmenu.h"
#include "amiga/gui.h"
#include "amiga/libs.h"
+#include "amiga/theme.h"
+#include "amiga/utf8.h"
+
+#include "desktop/browser.h"
+#include "desktop/mouse.h"
#include "utils/log.h"
+#include "utils/messages.h"
+#include "utils/nsoption.h"
enum {
AMI_CTX_ID_TEST = 1,
+ AMI_CTX_ID_URLOPEN,
+ AMI_CTX_ID_URLOPENWIN,
+ AMI_CTX_ID_URLOPENTAB,
AMI_CTX_ID_MAX
};
static Object *ctxmenu_obj = NULL;
-static struct Hook ctxmenu_hook;
static struct Hook ctxmenu_item_hook[AMI_CTX_ID_MAX];
static char *ctxmenu_item_label[AMI_CTX_ID_MAX];
-static char *ctxmenu_item_image[AMI_CTX_ID_MAX];
+static Object *ctxmenu_item_image[AMI_CTX_ID_MAX];
/** Menu functions - called automatically by RA_HandleInput **/
HOOKF(void, ami_ctxmenu_item_test, APTR, window, struct IntuiMessage *)
@@ -53,57 +67,143 @@ HOOKF(void, ami_ctxmenu_item_test, APTR, window, struct IntuiMessage *)
printf("testing\n");
}
+HOOKF(void, ami_ctxmenu_item_urlopentab, APTR, window, struct IntuiMessage *)
+{
+ struct browser_window *bw;
+ nsurl *url = (nsurl *)hook->h_Data;
+ struct gui_window_2 *gwin;
+
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
+ nserror error = browser_window_create(BW_CREATE_CLONE | BW_CREATE_HISTORY | BW_CREATE_TAB,
+ url,
+ browser_window_get_url(gwin->gw->bw),
+ gwin->gw->bw,
+ &bw);
+
+ if (error != NSERROR_OK)
+ warn_user(messages_get_errorcode(error), 0);
+}
+
+HOOKF(void, ami_ctxmenu_item_urlopenwin, APTR, window, struct IntuiMessage *)
+{
+ struct browser_window *bw;
+ nsurl *url = (nsurl *)hook->h_Data;
+ struct gui_window_2 *gwin;
+
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
+ nserror error = browser_window_create(BW_CREATE_CLONE | BW_CREATE_HISTORY,
+ url,
+ browser_window_get_url(gwin->gw->bw),
+ gwin->gw->bw,
+ &bw);
+
+ if (error != NSERROR_OK)
+ warn_user(messages_get_errorcode(error), 0);
+}
+
+
+/** Add an initialised item to a context menu **/
+static void ami_ctxmenu_add_item(Object *root_menu, int id, APTR data)
+{
+ ctxmenu_item_hook[id].h_Data = data;
+
+ IDoMethod(root_menu, OM_ADDMEMBER, MStrip,
+ MA_Type, T_ITEM,
+ MA_Label, ctxmenu_item_label[id],
+ MA_ID, id,
+ MA_Image, ctxmenu_item_image[id],
+ MA_UserData, &ctxmenu_item_hook[id],
+ MEnd);
+}
+
/** Hook function called by Intuition, creates context menu structure **/
-static uint32 ctxmenu_hook_func(struct Hook *hook, struct Window *window, struct ContextMenuMsg *msg)
+static uint32 ami_ctxmenu_hook_func(struct Hook *hook, struct Window *window, struct ContextMenuMsg *msg)
{
- if(msg->State != CM_QUERY) return 0;
+ Object *root_menu;
+ bool ctxmenu_has_content = false;
+ struct gui_window_2 *gwin = hook->h_Data;
+ struct hlcache_handle *cc = browser_window_get_content(gwin->gw->bw);
+ struct browser_window_features ccdata;
+ int mx = window->MouseX;
+ int my = window->MouseY;
+ int x, y;
- ctxmenu_item_hook[AMI_CTX_ID_TEST].h_Entry = (void *)ami_ctxmenu_item_test;
- ctxmenu_item_hook[AMI_CTX_ID_TEST].h_Data = 0;
+ if(msg->State != CM_QUERY) return 0;
+ if(nsoption_bool(kiosk_mode) == true) return 0;
+// check window is active
if(ctxmenu_obj != NULL) DisposeObject(ctxmenu_obj);
ctxmenu_obj = MStrip,
MA_Type, T_ROOT,
- MA_AddChild, MStrip,
+ MA_AddChild, root_menu = MStrip,
MA_Type, T_MENU,
MA_Label, NULL, //"NetSurf",
- MA_AddChild, MStrip,
- MA_Type, T_ITEM,
- MA_Label, ctxmenu_item_label[AMI_CTX_ID_TEST],
- MA_ID, AMI_CTX_ID_TEST,
- MA_Image, BitMapObj,
- IA_Scalable, TRUE,
- BITMAP_SourceFile, ctxmenu_item_image[AMI_CTX_ID_TEST],
- BITMAP_Screen, scrn,
- BITMAP_Masking, TRUE,
- BITMAP_Width, 16,
- BITMAP_Height, 16,
- BitMapEnd,
- MA_UserData, &ctxmenu_item_hook[AMI_CTX_ID_TEST],
- MEnd,
+ MA_EmbeddedKey, FALSE,
+ MA_FreeImage, FALSE,
MEnd,
MEnd;
- msg->Menu = ctxmenu_obj;
+ if(ami_mouse_to_ns_coords(gwin, &x, &y, mx, my) == false) {
+ /* Outside browser render area */
+ return 0;
+ }
+
+ browser_window_get_features(gwin->gw->bw, x, y, &ccdata);
+
+ if(ccdata.link) {
+ ami_ctxmenu_add_item(root_menu, AMI_CTX_ID_URLOPENTAB, ccdata.link);
+ ami_ctxmenu_add_item(root_menu, AMI_CTX_ID_URLOPENWIN, ccdata.link);
+ ctxmenu_has_content = true;
+ }
+
+ if(ctxmenu_has_content == true) {
+ msg->Menu = ctxmenu_obj;
+ ami_set_pointer(gwin, GUI_POINTER_DEFAULT, false);
+ }
return 0;
}
+/** Initial menu item creation **/
+static void ami_ctxmenu_alloc_item(int id, const char *label, const char *image, void *func)
+{
+ ctxmenu_item_label[id] = ami_utf8_easy(messages_get(label));
+ ctxmenu_item_image[id] = BitMapObj,
+ BITMAP_Screen, scrn,
+ BITMAP_SourceFile, image,
+ BITMAP_Masking, TRUE,
+ BitMapEnd;
+
+ SetAttrs(ctxmenu_item_image[id],
+ BITMAP_Width, 16,
+ BITMAP_Height, 16,
+ TAG_DONE);
+
+ ctxmenu_item_hook[id].h_Entry = func;
+ ctxmenu_item_hook[id].h_Data = 0;
+}
+
+/** Exported interface documented in ctxmenu.h **/
+struct Hook *ami_ctxmenu_get_hook(APTR data)
+{
+ return AllocSysObjectTags(ASOT_HOOK,
+ ASOHOOK_Entry, (HOOKFUNC)ami_ctxmenu_hook_func,
+ ASOHOOK_Data, data,
+ TAG_DONE);
+}
+
/** Exported interface documented in ctxmenu.h **/
-struct Hook *ami_ctxmenu_get_hook(void)
+void ami_ctxmenu_release_hook(struct Hook *hook)
{
- return &ctxmenu_hook;
+ FreeSysObject(ASOT_HOOK, hook);
}
/** Exported interface documented in ctxmenu.h **/
void ami_ctxmenu_init(void)
{
- ctxmenu_hook.h_Entry = (HOOKFUNC)ctxmenu_hook_func;
- ctxmenu_hook.h_Data = 0;
-
- ctxmenu_item_label[AMI_CTX_ID_TEST] = strdup("test item");
- ctxmenu_item_image[AMI_CTX_ID_TEST] = strdup("TBimages:list_info");
+ ami_ctxmenu_alloc_item(AMI_CTX_ID_URLOPENWIN, "LinkNewWin", "TBImages:list_app", ami_ctxmenu_item_urlopenwin);
+ ami_ctxmenu_alloc_item(AMI_CTX_ID_URLOPENTAB, "LinkNewTab", "TBImages:list_add", ami_ctxmenu_item_urlopentab);
}
/** Exported interface documented in ctxmenu.h **/
@@ -111,11 +211,12 @@ void ami_ctxmenu_free(void)
{
for(int i = 1; i < AMI_CTX_ID_MAX; i++) {
if(ctxmenu_item_label[i] != NULL) {
- free(ctxmenu_item_label[i]);
+ ami_utf8_free(ctxmenu_item_label[i]);
ctxmenu_item_label[i] = NULL;
}
+
if(ctxmenu_item_image[i] != NULL) {
- free(ctxmenu_item_image[i]);
+ DisposeObject(ctxmenu_item_image[i]);
ctxmenu_item_image[i] = NULL;
}
}
diff --git a/amiga/ctxmenu.h b/amiga/ctxmenu.h
index e23c723f1..678208647 100644
--- a/amiga/ctxmenu.h
+++ b/amiga/ctxmenu.h
@@ -26,7 +26,8 @@
struct Hook;
/**
- * Initialise context menus code
+ * Initialise context menus code (allocate label text, etc)
+ * Must be called *after* NetSurf's screen pointer is obtained.
*/
void ami_ctxmenu_init(void);
@@ -38,8 +39,20 @@ void ami_ctxmenu_free(void);
/**
* Get a Hook for WA_ContextMenuHook
*
+ * \param data ptr for the hook to use (struct gui_window_2 *)
* \returns pointer to a struct Hook
*/
-struct Hook *ami_ctxmenu_get_hook(void);
-#endif
+struct Hook *ami_ctxmenu_get_hook(APTR data);
+/**
+ * Release a Hook for WA_ContextMenuHook
+ *
+ * \param hook ptr to hook
+ */
+void ami_ctxmenu_release_hook(struct Hook *hook);
+#else
+inline void ami_ctxmenu_init(void) {}
+inline void ami_ctxmenu_free(void) {}
+inline struct Hook *ami_ctxmenu_get_hook(APTR data) {return NULL;}
+inline void ami_ctxmenu_release_hook(struct Hook *hook) {}
+#endif
diff --git a/amiga/gui.c b/amiga/gui.c
index 46973f282..9b312e52f 100644
--- a/amiga/gui.c
+++ b/amiga/gui.c
@@ -1318,7 +1318,7 @@ static bool ami_spacebox_to_ns_coords(struct gui_window_2 *gwin, int *x, int *y,
return true;
}
-static bool ami_mouse_to_ns_coords(struct gui_window_2 *gwin, int *x, int *y,
+bool ami_mouse_to_ns_coords(struct gui_window_2 *gwin, int *x, int *y,
int mouse_x, int mouse_y)
{
int ns_x, ns_y;
@@ -3769,6 +3769,8 @@ gui_window_create(struct browser_window *bw,
newprefs_hook.h_Entry = (void *)ami_gui_newprefs_hook;
newprefs_hook.h_Data = 0;
+
+ g->shared->ctxmenu_hook = ami_ctxmenu_get_hook(g->shared);
if(nsoption_bool(window_simple_refresh) == true) {
refresh_mode = WA_SimpleRefresh;
@@ -3932,7 +3934,7 @@ gui_window_create(struct browser_window *bw,
WA_ReportMouse,TRUE,
refresh_mode, TRUE,
WA_SizeBBottom, TRUE,
- WA_ContextMenuHook, ami_ctxmenu_get_hook(),
+ WA_ContextMenuHook, g->shared->ctxmenu_hook,
WA_IDCMP, IDCMP_MENUPICK | IDCMP_MOUSEMOVE |
IDCMP_MOUSEBUTTONS | IDCMP_NEWSIZE |
IDCMP_RAWKEY | idcmp_sizeverify |
@@ -4376,7 +4378,6 @@ static void gui_window_destroy(struct gui_window *g)
DisposeObject(g->shared->objects[OID_MAIN]);
ami_gui_appicon_remove(g->shared);
if(g->shared->appwin) RemoveAppWindow(g->shared->appwin);
-
ami_gui_hotlist_toolbar_free(g->shared, &g->shared->hotlist_toolbar_list);
/* These aren't freed by the above.
@@ -4390,6 +4391,7 @@ static void gui_window_destroy(struct gui_window *g)
ami_gui_opts_websearch_free(g->shared->web_search_list);
if(g->shared->search_bm) DisposeObject(g->shared->search_bm);
+ ami_ctxmenu_release_hook(g->shared->ctxmenu_hook);
ami_free_menulabs(g->shared);
#ifndef __amigaos4__
ami_menu_free_os3(g->shared);
@@ -5433,7 +5435,6 @@ int main(int argc, char** argv)
ami_amiupdate(); /* set env-vars for AmiUpdate */
ami_init_fonts();
ami_context_menu_init();
- ami_ctxmenu_init();
save_complete_init();
ami_theme_init();
ami_init_mouse_pointers();
@@ -5449,6 +5450,8 @@ int main(int argc, char** argv)
gui_init2(argc, argv);
+ ami_ctxmenu_init(); /* Requires screen pointer */
+
ami_gui_splash_close(splash_window);
strlcpy(script, nsoption_charp(arexx_dir), 1024);
diff --git a/amiga/gui.h b/amiga/gui.h
index 7ac140b19..9f8284b56 100755..100644
--- a/amiga/gui.h
+++ b/amiga/gui.h
@@ -132,6 +132,7 @@ struct gui_window_2 {
struct DiskObject *dobj; /* iconify appicon */
struct Hook favicon_hook;
struct Hook throbber_hook;
+ struct Hook *ctxmenu_hook;
gui_drag_type drag_op;
struct IBox *ptr_lock;
struct AppWindow *appwin;
@@ -174,6 +175,8 @@ void ami_schedule_redraw(struct gui_window_2 *gwin, bool full_redraw);
STRPTR ami_locale_langs(void);
int ami_key_to_nskey(ULONG keycode, struct InputEvent *ie);
bool ami_text_box_at_point(struct gui_window_2 *gwin, ULONG *x, ULONG *y);
+bool ami_mouse_to_ns_coords(struct gui_window_2 *gwin, int *x, int *y,
+ int mouse_x, int mouse_y);
BOOL ami_gadget_hit(Object *obj, int x, int y);
void ami_gui_history(struct gui_window_2 *gwin, bool back);
void ami_gui_hotlist_update_all(void);