comparison gtk/dw.c @ 2011:2dfce1ced00f

GTK2: Added dw_html_javascript_run() and DW_SIGNAL_HTML_CHANGED support.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Thu, 07 Nov 2019 04:49:04 +0000
parents a17cc1958369
children 48b91f535f82
comparison
equal deleted inserted replaced
2010:617a78dc70aa 2011:2dfce1ced00f
160 static gint _tree_select_event(GtkTree *tree, GtkWidget *child, gpointer data); 160 static gint _tree_select_event(GtkTree *tree, GtkWidget *child, gpointer data);
161 static gint _tree_expand_event(GtkTreeItem *treeitem, gpointer data); 161 static gint _tree_expand_event(GtkTreeItem *treeitem, gpointer data);
162 #endif 162 #endif
163 static gint _switch_page_event(GtkNotebook *notebook, GtkNotebookPage *page, guint page_num, gpointer data); 163 static gint _switch_page_event(GtkNotebook *notebook, GtkNotebookPage *page, guint page_num, gpointer data);
164 static gint _column_click_event(GtkWidget *widget, gint column_num, gpointer data); 164 static gint _column_click_event(GtkWidget *widget, gint column_num, gpointer data);
165 #ifdef USE_WEBKIT
166 static void _html_changed_event(WebKitWebView *web_view, WebKitWebFrame *frame, gpointer user_data);
167 #endif
165 static void _dw_signal_disconnect(gpointer data, GClosure *closure); 168 static void _dw_signal_disconnect(gpointer data, GClosure *closure);
166
167 #ifdef USE_WEBKIT
168 /*
169 * we need to add these equivalents from webkitwebview.h so we can refer to
170 * our own pointers to functions (we don't link with the webkit libraries
171 */
172 # define DW_WEBKIT_TYPE_WEB_VIEW (_webkit_web_view_get_type())
173 # define DW_WEBKIT_WEB_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), DW_WEBKIT_TYPE_WEB_VIEW, WebKitWebView))
174 WEBKIT_API GType (*_webkit_web_view_get_type)(void) = NULL;
175 WEBKIT_API void (*_webkit_web_view_load_html_string)(WebKitWebView *, const gchar *, const gchar *) = NULL;
176 WEBKIT_API void (*_webkit_web_view_open)(WebKitWebView *, const gchar *) = NULL;
177 WEBKIT_API GtkWidget *(*_webkit_web_view_new)(void) = NULL;
178 WEBKIT_API void (*_webkit_web_view_go_back)(WebKitWebView *) = NULL;
179 WEBKIT_API void (*_webkit_web_view_go_forward)(WebKitWebView *) = NULL;
180 WEBKIT_API void (*_webkit_web_view_reload)(WebKitWebView *) = NULL;
181 WEBKIT_API void (*_webkit_web_view_stop_loading)(WebKitWebView *) = NULL;
182 # ifdef WEBKIT_CHECK_VERSION
183 # if WEBKIT_CHECK_VERSION(1,1,5)
184 WEBKIT_API void (*_webkit_web_frame_print)(WebKitWebFrame *) = NULL;
185 WEBKIT_API WebKitWebFrame *(*_webkit_web_view_get_focused_frame)(WebKitWebView *) = NULL;
186 # endif
187 # endif
188 #endif
189 169
190 typedef struct 170 typedef struct
191 { 171 {
192 GdkPixmap *pixmap; 172 GdkPixmap *pixmap;
193 GdkBitmap *mask; 173 GdkBitmap *mask;
216 gint cid; 196 gint cid;
217 void *intfunc; 197 void *intfunc;
218 198
219 } SignalHandler; 199 } SignalHandler;
220 200
221 #define SIGNALMAX 19 201 #define SIGNALMAX 20
222 202
223 /* A list of signal forwarders, to account for paramater differences. */ 203 /* A list of signal forwarders, to account for paramater differences. */
224 static SignalList SignalTranslate[SIGNALMAX] = { 204 static SignalList SignalTranslate[SIGNALMAX] = {
225 { _configure_event, DW_SIGNAL_CONFIGURE }, 205 { _configure_event, DW_SIGNAL_CONFIGURE },
226 { _key_press_event, DW_SIGNAL_KEY_PRESS }, 206 { _key_press_event, DW_SIGNAL_KEY_PRESS },
238 { _tree_select_event, DW_SIGNAL_ITEM_SELECT }, 218 { _tree_select_event, DW_SIGNAL_ITEM_SELECT },
239 { _set_focus_event, DW_SIGNAL_SET_FOCUS }, 219 { _set_focus_event, DW_SIGNAL_SET_FOCUS },
240 { _value_changed_event, DW_SIGNAL_VALUE_CHANGED }, 220 { _value_changed_event, DW_SIGNAL_VALUE_CHANGED },
241 { _switch_page_event, DW_SIGNAL_SWITCH_PAGE }, 221 { _switch_page_event, DW_SIGNAL_SWITCH_PAGE },
242 { _column_click_event, DW_SIGNAL_COLUMN_CLICK }, 222 { _column_click_event, DW_SIGNAL_COLUMN_CLICK },
243 { _tree_expand_event, DW_SIGNAL_TREE_EXPAND } 223 { _tree_expand_event, DW_SIGNAL_TREE_EXPAND },
224 #ifdef USE_WEBKIT
225 { _html_changed_event, DW_SIGNAL_HTML_CHANGED }
226 #else
227 { _generic_event, DW_SIGNAL_HTML_CHANGED }
228 #endif
244 }; 229 };
245 230
246 /* Alignment flags */ 231 /* Alignment flags */
247 #define DW_CENTER 0.5f 232 #define DW_CENTER 0.5f
248 #define DW_LEFT 0.0f 233 #define DW_LEFT 0.0f
1255 char text[101] = {0}; 1240 char text[101] = {0};
1256 1241
1257 snprintf(text, 100, "_dw_sigcid%d", counter); 1242 snprintf(text, 100, "_dw_sigcid%d", counter);
1258 gtk_object_set_data(GTK_OBJECT(widget), text, GINT_TO_POINTER(cid)); 1243 gtk_object_set_data(GTK_OBJECT(widget), text, GINT_TO_POINTER(cid));
1259 } 1244 }
1245
1246 #ifdef USE_WEBKIT
1247 static void _html_changed_event(WebKitWebView *web_view, WebKitWebFrame *frame, gpointer data)
1248 {
1249 SignalHandler work = _get_signal_handler(data);
1250 char *location = (char *)webkit_web_view_get_uri(web_view);
1251 int status = 0;
1252 void **params = data;
1253
1254 if(params)
1255 status = DW_POINTER_TO_INT(params[3]);
1256
1257 if(status && location && work.window && work.func)
1258 {
1259 int (*htmlchangedfunc)(HWND, int, char *, void *) = work.func;
1260
1261 htmlchangedfunc(work.window, status, location, work.data);
1262 }
1263 }
1264 #endif
1260 1265
1261 static gint _set_focus_event(GtkWindow *window, GtkWidget *widget, gpointer data) 1266 static gint _set_focus_event(GtkWindow *window, GtkWidget *widget, gpointer data)
1262 { 1267 {
1263 SignalHandler work = _get_signal_handler(data); 1268 SignalHandler work = _get_signal_handler(data);
1264 int retval = FALSE; 1269 int retval = FALSE;
12906 return DW_ERROR_NONE; 12911 return DW_ERROR_NONE;
12907 #endif 12912 #endif
12908 return DW_ERROR_UNKNOWN; 12913 return DW_ERROR_UNKNOWN;
12909 } 12914 }
12910 12915
12916 /*
12917 * Executes the javascript contained in "script" in the HTML window.
12918 * Parameters:
12919 * handle: Handle to the HTML window.
12920 * script: Javascript code to execute.
12921 * scriptdata: Data passed to the signal handler.
12922 * Notes: A DW_SIGNAL_HTML_RESULT event will be raised with scriptdata.
12923 * Returns:
12924 * DW_ERROR_NONE (0) on success.
12925 */
12926 int dw_html_javascript_run(HWND handle, char *script, void *scriptdata)
12927 {
12928 #ifdef USE_WEBKIT
12929 int _locked_by_me = FALSE;
12930 WebKitWebView *web_view;
12931
12932 DW_MUTEX_LOCK;
12933 if((web_view = (WebKitWebView *)gtk_object_get_data(GTK_OBJECT(handle), "_dw_web_view")))
12934 webkit_web_view_execute_script(web_view, script);
12935 DW_MUTEX_UNLOCK;
12936 return DW_ERROR_NONE;
12937 #else
12938 return DW_ERROR_UNKNOWN;
12939 #endif
12940 }
12941
12911 #ifdef USE_WEBKIT 12942 #ifdef USE_WEBKIT
12912 # ifdef WEBKIT_CHECK_VERSION 12943 # ifdef WEBKIT_CHECK_VERSION
12913 # if WEBKIT_CHECK_VERSION(1,1,5) 12944 # if WEBKIT_CHECK_VERSION(1,1,5)
12914 static void _dw_html_print_cb(GtkWidget *widget, gpointer *data) 12945 static void _dw_html_print_cb(GtkWidget *widget, gpointer *data)
12915 { 12946 {
12948 { 12979 {
12949 GtkWidget *widget = NULL; 12980 GtkWidget *widget = NULL;
12950 #ifdef USE_WEBKIT 12981 #ifdef USE_WEBKIT
12951 int _locked_by_me = FALSE; 12982 int _locked_by_me = FALSE;
12952 WebKitWebView *web_view; 12983 WebKitWebView *web_view;
12984 WebKitWebSettings *settings;
12953 12985
12954 DW_MUTEX_LOCK; 12986 DW_MUTEX_LOCK;
12955 widget = gtk_scrolled_window_new(NULL, NULL); 12987 widget = gtk_scrolled_window_new(NULL, NULL);
12956 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (widget), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); 12988 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (widget), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
12957 web_view = (WebKitWebView *)_webkit_web_view_new(); 12989 web_view = (WebKitWebView *)webkit_web_view_new();
12958 gtk_container_add(GTK_CONTAINER (widget), GTK_WIDGET(web_view)); 12990 gtk_container_add(GTK_CONTAINER (widget), GTK_WIDGET(web_view));
12959 gtk_widget_show( GTK_WIDGET(web_view) ); 12991 gtk_widget_show( GTK_WIDGET(web_view) );
12960 gtk_object_set_data(GTK_OBJECT(widget), "_dw_web_view", (gpointer)web_view); 12992 gtk_object_set_data(GTK_OBJECT(widget), "_dw_web_view", (gpointer)web_view);
12961 # ifdef WEBKIT_CHECK_VERSION 12993 # ifdef WEBKIT_CHECK_VERSION
12962 # if WEBKIT_CHECK_VERSION(1,1,5) 12994 # if WEBKIT_CHECK_VERSION(1,1,5)
12963 g_signal_connect(web_view, "populate-popup", G_CALLBACK(_dw_html_populate_popup_cb), NULL); 12995 g_signal_connect(web_view, "populate-popup", G_CALLBACK(_dw_html_populate_popup_cb), NULL);
12964 # endif 12996 # endif
12965 # endif 12997 # endif
12998 /* Create a new websettings and enable java script */
12999 settings = webkit_web_settings_new();
13000 g_object_set(G_OBJECT(settings), "enable-scripts", TRUE, NULL);
13001 webkit_web_view_set_settings(WEBKIT_WEB_VIEW(web_view), settings);
12966 gtk_widget_show(widget); 13002 gtk_widget_show(widget);
12967 DW_MUTEX_UNLOCK; 13003 DW_MUTEX_UNLOCK;
12968 #else 13004 #else
12969 dw_debug( "HTML widget not available; you do not have access to webkit.\n" ); 13005 dw_debug( "HTML widget not available; you do not have access to webkit.\n" );
12970 #endif 13006 #endif
13310 void dw_signal_connect(HWND window, char *signame, void *sigfunc, void *data) 13346 void dw_signal_connect(HWND window, char *signame, void *sigfunc, void *data)
13311 { 13347 {
13312 dw_signal_connect_data(window, signame, sigfunc, NULL, data); 13348 dw_signal_connect_data(window, signame, sigfunc, NULL, data);
13313 } 13349 }
13314 13350
13351 #define _DW_INTERNAL_CALLBACK_PARAMS 4
13352
13315 /* 13353 /*
13316 * Add a callback to a window event with a closure callback. 13354 * Add a callback to a window event with a closure callback.
13317 * Parameters: 13355 * Parameters:
13318 * window: Window handle of signal to be called back. 13356 * window: Window handle of signal to be called back.
13319 * signame: A string pointer identifying which signal to be hooked. 13357 * signame: A string pointer identifying which signal to be hooked.
13325 { 13363 {
13326 void *thisfunc = _findsigfunc(signame); 13364 void *thisfunc = _findsigfunc(signame);
13327 char *thisname = signame; 13365 char *thisname = signame;
13328 HWND thiswindow = window; 13366 HWND thiswindow = window;
13329 int sigid, _locked_by_me = FALSE; 13367 int sigid, _locked_by_me = FALSE;
13330 void **params = calloc(3, sizeof(void *)); 13368 void **params = calloc(_DW_INTERNAL_CALLBACK_PARAMS, sizeof(void *));
13331 gint cid; 13369 gint cid;
13332 13370
13333 /* Save the disconnect function pointer */ 13371 /* Save the disconnect function pointer */
13334 params[1] = discfunc; 13372 params[1] = discfunc;
13335 13373
13338 * If the window we are setting the signal on is a scrolled window we need to get 13376 * If the window we are setting the signal on is a scrolled window we need to get
13339 * the "real" widget type. thiswindow is the "real" widget type 13377 * the "real" widget type. thiswindow is the "real" widget type
13340 */ 13378 */
13341 if (GTK_IS_SCROLLED_WINDOW(thiswindow)) 13379 if (GTK_IS_SCROLLED_WINDOW(thiswindow))
13342 { 13380 {
13381 #ifdef USE_WEBKIT
13382 thiswindow = (HWND)gtk_object_get_data(GTK_OBJECT(window), "_dw_web_view");
13383 if(!thiswindow)
13384 #endif
13343 thiswindow = (HWND)gtk_object_get_user_data(GTK_OBJECT(window)); 13385 thiswindow = (HWND)gtk_object_get_user_data(GTK_OBJECT(window));
13344 } 13386 }
13345 13387
13346 if (GTK_IS_MENU_ITEM(thiswindow) && strcmp(signame, DW_SIGNAL_CLICKED) == 0) 13388 if (GTK_IS_MENU_ITEM(thiswindow) && strcmp(signame, DW_SIGNAL_CLICKED) == 0)
13347 { 13389 {
13402 gtk_object_set_data(GTK_OBJECT(thiswindow), "_dw_container_context_func", (gpointer)thisfunc); 13444 gtk_object_set_data(GTK_OBJECT(thiswindow), "_dw_container_context_func", (gpointer)thisfunc);
13403 gtk_object_set_data(GTK_OBJECT(thiswindow), "_dw_container_context_data", params); 13445 gtk_object_set_data(GTK_OBJECT(thiswindow), "_dw_container_context_data", params);
13404 cid = gtk_signal_connect(GTK_OBJECT(thiswindow), "button_press_event", GTK_SIGNAL_FUNC(thisfunc), params); 13446 cid = gtk_signal_connect(GTK_OBJECT(thiswindow), "button_press_event", GTK_SIGNAL_FUNC(thisfunc), params);
13405 _set_signal_handler_id(thiswindow, sigid, cid); 13447 _set_signal_handler_id(thiswindow, sigid, cid);
13406 13448
13407 params = calloc(sizeof(void *), 3); 13449 params = calloc(sizeof(void *), _DW_INTERNAL_CALLBACK_PARAMS);
13408 sigid = _set_signal_handler(window, window, sigfunc, data, thisfunc); 13450 sigid = _set_signal_handler(window, window, sigfunc, data, thisfunc);
13409 params[0] = GINT_TO_POINTER(sigid); 13451 params[0] = GINT_TO_POINTER(sigid);
13410 params[2] = (void *)thiswindow; 13452 params[2] = (void *)thiswindow;
13411 cid = gtk_signal_connect(GTK_OBJECT(window), "button_press_event", GTK_SIGNAL_FUNC(thisfunc), params); 13453 cid = gtk_signal_connect(GTK_OBJECT(window), "button_press_event", GTK_SIGNAL_FUNC(thisfunc), params);
13412 _set_signal_handler_id(window, sigid, cid); 13454 _set_signal_handler_id(window, sigid, cid);
13443 params[0] = GINT_TO_POINTER(sigid); 13485 params[0] = GINT_TO_POINTER(sigid);
13444 params[2] = (void *)thiswindow; 13486 params[2] = (void *)thiswindow;
13445 cid = g_signal_connect_data(G_OBJECT(thiswindow), "key_press_event", G_CALLBACK(_container_enter_event), params, _dw_signal_disconnect, 0); 13487 cid = g_signal_connect_data(G_OBJECT(thiswindow), "key_press_event", G_CALLBACK(_container_enter_event), params, _dw_signal_disconnect, 0);
13446 _set_signal_handler_id(thiswindow, sigid, cid); 13488 _set_signal_handler_id(thiswindow, sigid, cid);
13447 13489
13448 params = calloc(sizeof(void *), 3); 13490 params = calloc(sizeof(void *), _DW_INTERNAL_CALLBACK_PARAMS);
13449 thisname = "button_press_event"; 13491 thisname = "button_press_event";
13450 thisfunc = _findsigfunc(DW_SIGNAL_ITEM_ENTER); 13492 thisfunc = _findsigfunc(DW_SIGNAL_ITEM_ENTER);
13451 } 13493 }
13452 else if (GTK_IS_CLIST(thiswindow) && strcmp(signame, DW_SIGNAL_ITEM_SELECT) == 0) 13494 else if (GTK_IS_CLIST(thiswindow) && strcmp(signame, DW_SIGNAL_ITEM_SELECT) == 0)
13453 { 13495 {
13467 { 13509 {
13468 thisname = "focus-in-event"; 13510 thisname = "focus-in-event";
13469 if (GTK_IS_COMBO(thiswindow)) 13511 if (GTK_IS_COMBO(thiswindow))
13470 thiswindow = GTK_COMBO(thiswindow)->entry; 13512 thiswindow = GTK_COMBO(thiswindow)->entry;
13471 } 13513 }
13514 #ifdef USE_WEBKIT
13515 else if (WEBKIT_IS_WEB_VIEW(thiswindow) && strcmp(signame, DW_SIGNAL_HTML_CHANGED) == 0)
13516 {
13517 sigid = _set_signal_handler(thiswindow, window, sigfunc, data, thisfunc);
13518 params[0] = GINT_TO_POINTER(sigid);
13519 params[2] = (void *)thiswindow;
13520 params[3] = GINT_TO_POINTER(DW_HTML_CHANGE_STARTED);
13521 cid = g_signal_connect_data(G_OBJECT(thiswindow), "load-started", G_CALLBACK(thisfunc), params, _dw_signal_disconnect, 0);
13522 _set_signal_handler_id(thiswindow, sigid, cid);
13523
13524 params = calloc(sizeof(void *), _DW_INTERNAL_CALLBACK_PARAMS);
13525
13526 sigid = _set_signal_handler(thiswindow, window, sigfunc, data, thisfunc);
13527 params[0] = GINT_TO_POINTER(sigid);
13528 params[2] = (void *)thiswindow;
13529 params[3] = GINT_TO_POINTER(DW_HTML_CHANGE_LOADING);
13530 cid = g_signal_connect_data(G_OBJECT(thiswindow), "load-committed", G_CALLBACK(thisfunc), params, _dw_signal_disconnect, 0);
13531 _set_signal_handler_id(thiswindow, sigid, cid);
13532
13533 params = calloc(sizeof(void *), _DW_INTERNAL_CALLBACK_PARAMS);
13534 params[3] = GINT_TO_POINTER(DW_HTML_CHANGE_COMPLETE);
13535
13536 thisname = "load-finished";
13537 }
13538 #endif
13472 #if 0 13539 #if 0
13473 else if (strcmp(signame, DW_SIGNAL_LOSE_FOCUS) == 0) 13540 else if (strcmp(signame, DW_SIGNAL_LOSE_FOCUS) == 0)
13474 { 13541 {
13475 thisname = "focus-out-event"; 13542 thisname = "focus-out-event";
13476 if(GTK_IS_COMBO(thiswindow)) 13543 if(GTK_IS_COMBO(thiswindow))