WebGadget Extensions (PB v6.xx GTK3)

Linux specific forum
User avatar
mk-soft
Always Here
Always Here
Posts: 5335
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

WebGadget Extensions (PB v6.xx GTK3)

Post by mk-soft »

WebGadget extensions for PB version v6.xx (GTK3) from Linux version Ubuntu 20.04 LTS and Raspberry PI.

- New: WebGadget EventTypes
- New: WebGadget HitTest Callback
- WebKit_LoadHTML
- WebKit_LoadFile
- WebKit_GetHtmlCode ; Get resource data asynchronous. With synchron not longer work!

Update v1.01.2
- Fix: Now send event with right window id

Update v1.2.1
- Added: #PB_Eventtype_WebLoadFailed ; Detail over EventData()
- Added: #PB_Eventtype_WebLoadFailedTLS ; Detail over EventData()

Update v1.03.2
- Added: WebKit_RunJavaScript(...)
- Added: #PB_EventType_WebRunJavaScriptFinished
- Added: #PB_EventType_WebRunJavaScriptFailed

Update v1.03.3
- WebKit_RunJavaScript added optional parameter ScriptID. Use EventData() to get ScriptID

Update v1.04.1
- Remove WebKit_GetDataAsynchron
- Remove Webkit_GetDataHTML
- Remove #PB_EventType_WebGetDataFinished
- Added WebKit_GetHtmlCode(Gadget, *Callback.WebKit_GetHtmlCodeCallback)
- ----
- Remove #PB_EventType_WebRunJavaScriptFinished
- Remove #PB_EventType_WebRunJavaScriptFailed
- Change WebKit_RunJavaScript(Gadget, ScriptID, JavaScript.s, *Callback.WebKit_RunJavaScriptCallback)
- ----
- Added WebKit_DisableJavaScript(Gadget, State)
- Added WebKit_IsEnableJavaScript(Gadget)

Update v1.05.1
- Added WebKit_SetNavigationCallback(Gadget, *Callback.Webkit_NavigationCallback)
* This fixed too the "web-process-crashed" on Raspberry Arm64 the click on a link

Update v1.06.2
- Added #PB_EventType_WebProcessCrashed

Update v1.06.3
- Bugfix: Forgot some 'ProcedureC' for callback

Update v1.06.4
- Added WebKit_SetAcceleration(Gadget, Policy)

Update v1.06.6
- Added WebViewGadget
- Optimize Java Result

Update v1.06.7
- Added Settings Get/SetProperty
- Added SetPermissionCallback
- Update Example

Update v1.06.8
- Change: Query the permission request name for better gobject checking

WebGadgetEx.pb

Code: Select all

;-TOP

; Comment : WebGadgetEx (GTK3)
; Compiler: Purebasic v6.xx (Ubuntu 20.04 LTS, Raspberry PI)
; Author  : mk-soft
; File    : WebGadgetEx.pb
; Version : v1.06.8
; Create  : 26.11.2021
; Update  : 03.03.2024

; Link    : https://www.purebasic.fr/english/viewtopic.php?t=78274

; ---------------------

; Linux Libraries (deb)

; sudo apt-get install libwebkit2gtk-4.0
; sudo apt-get install libwebkit2gtk-4.0-dev

; Syntax Callback:
; - HitTestCallback(Gadget, Type, Text.s)
; - NavigationCallback(Gadget, URI.s)
;   * Return true to enable load uri 
; - GetHtmlCodeCallback(Gadget, State, HtmlCode.s)
; - RunJavaScriptCallback(Gadget, State, ScriptID, JavaResult.s)

; ********************* 

DeclareModule WebKit2
  
  ImportC ""
    webkit_user_media_permission_is_for_audio_device(*request)
    webkit_user_media_permission_is_for_video_device(*request)
  EndImport
  
  Enumeration #PB_EventType_FirstCustomValue
    #PB_EventType_WebLoadStarted
    #PB_EventType_WebLoadRedirected
    #PB_EventType_WebLoadCommitted
    #PB_EventType_WebLoadFinished
    #PB_EventType_WebLoadFailed
    #PB_EventType_WebLoadFailedTLS
    #PB_EventType_WebProcessCrashed
  EndEnumeration
    
  #WEBKIT_HIT_TEST_RESULT_CONTEXT_DOCUMENT  = 1 << 1
  #WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK      = 1 << 2
  #WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE     = 1 << 3
  #WEBKIT_HIT_TEST_RESULT_CONTEXT_MEDIA     = 1 << 4
  #WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE  = 1 << 5
  #WEBKIT_HIT_TEST_RESULT_CONTEXT_SCROLLBAR = 1 << 6
  #WEBKIT_HIT_TEST_RESULT_CONTEXT_SELECTION = 1 << 7
  
  #WEBKIT_HARDWARE_ACCELERATION_POLICY_ON_DEMAND = 0
  #WEBKIT_HARDWARE_ACCELERATION_POLICY_ALWAYS = 1
  #WEBKIT_HARDWARE_ACCELERATION_POLICY_NEVER = 2
  
  Structure WebKitLoadError
    Link.s
    Code.i
    Message.s
  EndStructure
  
  Structure WebKitLoadErrorTLS
    Link.s
    Errors.i
    *Certificate
  EndStructure
  
  Prototype WebKit_HitTestCallback(Gadget, Type, Text.s)
  Prototype WebKit_GetHtmlCodeCallback(Gadget, State, HtmlCode.s)
  Prototype WebKit_RunJavaScriptCallback(Gadget, State, ScriptID, JavaResult.s)
  Prototype Webkit_NavigationCallback(Gadget, URI.s)
  Prototype Webkit_PermissionCallback(Gadget, RequestName.s, *Request)
  
  Declare WebKit_Init(Gadget)
  Declare WebKit_Free(Gadget)
  
  Declare WebKit_LoadURI(Gadget, URI.s)
  Declare WebKit_LoadHTML(Gadget, content.s, base_uri.s = "localhost")
  Declare WebKit_LoadFile(Gadget, FileName.s)
  
  Declare.s WebKit_GetURI(Gadget)
  Declare.s WebKit_GetTitle(Gadget)
  Declare.i WebKit_GetHtmlCode(Gadget, *Callback.WebKit_GetHtmlCodeCallback)
  
  Declare WebKit_SetHitTestCallback(Gadget, *Callback.WebKit_HitTestCallback)
  Declare WebKit_SetNavigationCallback(Gadget, *Callback.WebKit_NavigationCallback)
  Declare WebKit_SetPermissionCallback(Gadget, *Callback.Webkit_PermissionCallback)
  
  Declare WebKit_RunJavaScript(Gadget, ScriptID, JavaScript.s, *Callback.WebKit_RunJavaScriptCallback)
  Declare WebKit_DisableJavaScript(Gadget, State)
  Declare WebKit_IsEnableJavaScript(Gadget)
  
  Declare WebKit_SetAcceleration(Gadget, Policy)
  
  Declare WebKit_GetProperty(Gadget, Property.s, *Value.gvalue)
  Declare WebKit_SetProperty(Gadget, Property.s, *Value.gvalue)
  
EndDeclareModule

Module WebKit2
  
  EnableExplicit
  
  ; ---- Force compiler to link webkit
  
  If 0 : WebGadget(0, 0, 0, 0, 0, "") : EndIf
  
  ; ----
  
  Enumeration
    #WEBKIT_LOAD_STARTED
    #WEBKIT_LOAD_REDIRECTED
    #WEBKIT_LOAD_COMMITTED
    #WEBKIT_LOAD_FINISHED
  EndEnumeration
  
  ; ----
  
  Macro G_TYPE_MAKE_FUNDAMENTAL(x)
    x << 2
  EndMacro
  
  #G_TYPE_INVALID = G_TYPE_MAKE_FUNDAMENTAL(0)
  #G_TYPE_NONE = G_TYPE_MAKE_FUNDAMENTAL(1)
  #G_TYPE_INTERFACE = G_TYPE_MAKE_FUNDAMENTAL(2)
  #G_TYPE_CHAR = G_TYPE_MAKE_FUNDAMENTAL(3)
  #G_TYPE_UCHAR = G_TYPE_MAKE_FUNDAMENTAL(4)
  #G_TYPE_BOOLEAN = G_TYPE_MAKE_FUNDAMENTAL(5)
  #G_TYPE_INT = G_TYPE_MAKE_FUNDAMENTAL(6)
  #G_TYPE_UINT = G_TYPE_MAKE_FUNDAMENTAL(7)
  #G_TYPE_LONG = G_TYPE_MAKE_FUNDAMENTAL(8)
  #G_TYPE_ULONG = G_TYPE_MAKE_FUNDAMENTAL(9)
  #G_TYPE_INT64 = G_TYPE_MAKE_FUNDAMENTAL(10)
  #G_TYPE_UINT64 = G_TYPE_MAKE_FUNDAMENTAL(11)
  #G_TYPE_ENUM = G_TYPE_MAKE_FUNDAMENTAL(12)
  #G_TYPE_FLAGS = G_TYPE_MAKE_FUNDAMENTAL(13)
  #G_TYPE_FLOAT = G_TYPE_MAKE_FUNDAMENTAL(14)
  #G_TYPE_DOUBLE = G_TYPE_MAKE_FUNDAMENTAL(15)
  #G_TYPE_STRING = G_TYPE_MAKE_FUNDAMENTAL(16)
  #G_TYPE_POINTER = G_TYPE_MAKE_FUNDAMENTAL(17)
  #G_TYPE_BOXED = G_TYPE_MAKE_FUNDAMENTAL(18)
  #G_TYPE_PARAM = G_TYPE_MAKE_FUNDAMENTAL(19)
  #G_TYPE_OBJECT = G_TYPE_MAKE_FUNDAMENTAL(20)
  
  ; ----
  
  ImportC ""
    webkit_web_view_new()
    webkit_web_view_load_uri(*web_view, url.p-utf8)
    webkit_web_view_load_html(*web_view, content.p-utf8, base_uri.p-utf8);
    webkit_web_view_get_uri(*web_view)
    webkit_web_view_get_title(*web_view)
    
    webkit_hit_test_result_get_context(*hit_test_result)
    
    webkit_hit_test_result_context_is_link(*hit_test_result)
    webkit_hit_test_result_context_is_image(*hit_test_result)
    webkit_hit_test_result_context_is_media(*hit_test_result)
    webkit_hit_test_result_context_is_editable(*hit_test_result)
    webkit_hit_test_result_context_is_selection(*hit_test_result)
    webkit_hit_test_result_context_is_scrollbar(*hit_test_result)
    
    webkit_hit_test_result_get_link_uri(*hit_test_result)
    webkit_hit_test_result_get_link_title(*hit_test_result)
    webkit_hit_test_result_get_link_label(*hit_test_result)
    webkit_hit_test_result_get_image_uri(*hit_test_result)
    webkit_hit_test_result_get_media_uri(*hit_test_result)
    
    webkit_permission_request_allow(*request)
    webkit_permission_request_deny(*request)
    
    webkit_web_view_get_main_resource(*web_view) ; Result WebKitWebResource
    webkit_web_resource_get_data(*resource, *cancellable, *callback, user_data)
    webkit_web_resource_get_data_finish(*resource, *result, *length, *p_error)
    
    webkit_web_view_get_settings(*web_view)
    webkit_web_view_set_settings(*web_view, *settings)
    webkit_settings_get_enable_javascript(*settings)
    webkit_settings_set_enable_javascript(*settings, enabled)
    webkit_settings_set_hardware_acceleration_policy(*settings, policy)
    
    webkit_web_view_run_javascript(*web_view, script.p-utf8, *cancellable, *callback, user_data)
    webkit_web_view_run_javascript_finish(*web_view, *result, *p_error) ; *js_result
    webkit_javascript_result_unref (*js_result)
    webkit_javascript_result_get_global_context(*js_result)
    webkit_javascript_result_get_value(*js_result)
    
    JSValueIsString(*context, value)
    JSValueIsNumber(*context, value)
    JSValueIsInt32(*context, value)
    JSValueToStringCopy(*context, value, outException)
    JSValueToNumber.d(*context, value, outException)
    JSStringGetMaximumUTF8CStringSize(*js_str_value)
    JSStringGetUTF8CString(*js_str_value, *str_value, str_length)
    JSStringRelease(*js_str_value)
    
    ; gobject
    g_type_check_instance(*instance)
    g_type_name(Type)
    g_type_name_from_instance(*Instance)
    g_type_name_from_class(*Class)
  EndImport
  
  ; ----
  
  Structure udtWebKitGadget
    ; Widgets
    Window.i
    Gadget.i
    WebView.i
    ; Signal handle
    signal_load_changed.i
    signal_mouse_target_changed.i
    signal_load_failed.i
    signal_load_failed_with_tls_errors.i
    signal_web_process_crashed.i
    signal_button_press_event.i
    signal_permission_request.i
    ; Data
    *Resource
    HitTestURI.s
    ; User callback hit test
    *HitTestCallback.WebKit_HitTestCallback
    ; User callback navigation
    *NavigationCallback.WebKit_NavigationCallback
    ; Permission Request
    *PermissionCallback.Webkit_PermissionCallback
    ; User callback get data
    *GetDataCallback.WebKit_GetHtmlCodeCallback
    ; Last load failed
    LoadError.WebKitLoadError
    ; Last load failed tls
    LoadErrorTLS.WebKitLoadErrorTLS
  EndStructure
  
  Structure udtJavaScriptData
    Gadget.i
    ScriptID.i
    *RunJavaScriptCallback.WebKit_RunJavaScriptCallback
  EndStructure
  
  ; ----
  
  Global NewMap mapWebKitGadget.udtWebKitGadget()
  
  ; ----
  
  ProcedureC _signal_load_changed_cb(*web_view, load_event, *GadgetData.udtWebKitGadget)
    With *GadgetData
      Select load_event
        Case #WEBKIT_LOAD_STARTED
          PostEvent(#PB_Event_Gadget, \Window, \Gadget, #PB_Eventtype_WebLoadStarted)
        Case #WEBKIT_LOAD_COMMITTED
          PostEvent(#PB_Event_Gadget, \Window, \Gadget, #PB_Eventtype_WebLoadCommitted)
        Case #WEBKIT_LOAD_REDIRECTED
          PostEvent(#PB_Event_Gadget, \Window, \Gadget, #PB_Eventtype_WebLoadRedirected)
        Case #WEBKIT_LOAD_FINISHED
          PostEvent(#PB_Event_Gadget, \Window, \Gadget, #PB_Eventtype_WebLoadFinished)
      EndSelect
    EndWith
  EndProcedure
  
  ; ----
  
  ProcedureC _signal_mouse_target_changed_cb(*web_view, *hit_test_result, modifiers, *GadgetData.udtWebKitGadget)
    Protected gint, *gchar, text.s
    gint = webkit_hit_test_result_get_context(*hit_test_result)
    With *GadgetData
      If *GadgetData
        If gint & #WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK
          *gchar = webkit_hit_test_result_get_link_uri(*hit_test_result)
          \HitTestURI = PeekS(*gchar, -1, #PB_UTF8)
          If \HitTestCallback
            \HitTestCallback(\Gadget, #WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK, \HitTestURI)
          EndIf
        Else
          \HitTestURI = ""
        EndIf
          
        If \HitTestCallback
          If gint & #WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE
            *gchar = webkit_hit_test_result_get_image_uri(*hit_test_result)
            text = PeekS(*gchar, -1, #PB_UTF8)
            \HitTestCallback(\Gadget, #WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE, text)
          EndIf
          If gint & #WEBKIT_HIT_TEST_RESULT_CONTEXT_MEDIA
            *gchar = webkit_hit_test_result_get_media_uri(*hit_test_result)
            text = PeekS(*gchar, -1, #PB_UTF8)
            \HitTestCallback(\Gadget, #WEBKIT_HIT_TEST_RESULT_CONTEXT_MEDIA, text)
          EndIf
          If gint & #WEBKIT_HIT_TEST_RESULT_CONTEXT_SCROLLBAR
            \HitTestCallback(\Gadget, #WEBKIT_HIT_TEST_RESULT_CONTEXT_SCROLLBAR, "")
          EndIf
          If gint & #WEBKIT_HIT_TEST_RESULT_CONTEXT_SELECTION
            \HitTestCallback(\Gadget, #WEBKIT_HIT_TEST_RESULT_CONTEXT_SELECTION, "")
          EndIf
          If gint = #WEBKIT_HIT_TEST_RESULT_CONTEXT_DOCUMENT
            \HitTestCallback(\Gadget, #WEBKIT_HIT_TEST_RESULT_CONTEXT_DOCUMENT, "")
          EndIf
          
        EndIf
      EndIf
    EndWith
  EndProcedure
  
  ; ----
  
  ProcedureC _signal_load_failed_cb(*web_view, load_event, *failing_uri, *error.gerror, *GadgetData.udtWebKitGadget)
    With *GadgetData
      \LoadError\Link = PeekS(*failing_uri, -1, #PB_UTF8)
      \LoadError\Code = *error\code
      \LoadError\Message + PeekS(*error\message, -1, #PB_UTF8)
      PostEvent(#PB_Event_Gadget, \Window, \Gadget, #PB_Eventtype_WebLoadFailed, @\LoadError)
    EndWith
    ProcedureReturn #True
  EndProcedure
  
  ; ----
  
  ProcedureC _signal_load_failed_with_tls_errors_cb(*web_view, *failing_uri, *certificate, errors, *GadgetData.udtWebKitGadget)
    With *GadgetData
      \LoadErrorTLS\Link = PeekS(*failing_uri, -1, #PB_UTF8)
      \LoadErrorTLS\Errors = errors
      \LoadErrorTLS\Certificate = *certificate
      PostEvent(#PB_Event_Gadget, \Window, \Gadget, #PB_Eventtype_WebLoadFailedTLS, @\LoadErrorTLS)
    EndWith
    ProcedureReturn #False
  EndProcedure
  
  ; ----
  
  ProcedureC _signal_web_process_crashed_cb(*web_view, *GadgetData.udtWebKitGadget)
    With *GadgetData
      PostEvent(#PB_Event_Gadget, \Window, \Gadget, #PB_EventType_WebProcessCrashed)
      webkit_web_view_load_html(*web_view, "Web Process Crashed!", "")
    EndWith
    ProcedureReturn #True
  EndProcedure
  
  ; ----
  
  ProcedureC _signal_button_press_event_cb(*web_view, *Event.GdkEventButton, *WidgetData.udtWebKitGadget)
    With *WidgetData
      If *Event\button = 1 And \HitTestURI <> ""
        If \NavigationCallback
          If \NavigationCallback(\Gadget, \HitTestURI)
            webkit_web_view_load_uri(*web_view, *WidgetData\HitTestURI)
          EndIf
        Else
          webkit_web_view_load_uri(*web_view, *WidgetData\HitTestURI)
        EndIf
        ProcedureReturn 1 ; Button process finished
      Else
        ProcedureReturn 0 ; Botton process continue
      EndIf
    EndWith
  EndProcedure
  
  ; ----
  
  ProcedureC _signal_permission_request_cb(*web_view, *request.gobject, *GadgetData.udtWebKitGadget)
    Protected r1, *instance_name, request_name.s
    With *GadgetData
      If \PermissionCallback
        If Not g_type_check_instance(*request\g_type_instance)
          ProcedureReturn #True
        EndIf
        *instance_name = g_type_name_from_instance(*request\g_type_instance)
        If Not *instance_name
          ProcedureReturn #True
        EndIf
        request_name = PeekS(*instance_name, -1, #PB_UTF8)
        If \PermissionCallback(\Gadget, request_name, *request)
          webkit_permission_request_allow(*request)
          ProcedureReturn #True
        EndIf
      EndIf
      webkit_permission_request_deny(*request)
    EndWith
    ProcedureReturn #True
  EndProcedure
  
  ; ----
  
  ProcedureC _get_response_data_finish_cb(*resource, *result, *GadgetData.udtWebKitGadget)
    Protected HtmlResult.s, *guchar, length.i, *error.gerror
    With *GadgetData
      *guchar = webkit_web_resource_get_data_finish(*resource, *result, @length, @*error)
      If *guchar
        If \GetDataCallback
          HtmlResult = PeekS(*guchar, length, #PB_UTF8)
          \GetDataCallback(\Gadget, #True, HtmlResult)
        EndIf
        g_free_(*guchar)
      Else
        HtmlResult = PeekS(*error\message, -1, #PB_UTF8)
        g_error_free_(*error)
        If \GetDataCallback
          HtmlResult = PeekS(*guchar, length, #PB_UTF8)
          \GetDataCallback(\Gadget, #False, HtmlResult)
        EndIf
      EndIf
    EndWith
  EndProcedure
  
  ; ----
  
  ProcedureC _web_view_javascript_finished_cb(*object, *result, *ScriptData.udtJavaScriptData)
    Protected JavaResult.s, *js_result, *error.gerror
    Protected *context, value, *js_str_value, *str_value, str_length, dbl_value.d, int_value.i
    
    With *ScriptData
      *js_result = webkit_web_view_run_javascript_finish(*object, *result, @*error)
      If *js_result
        *context = webkit_javascript_result_get_global_context(*js_result);
        value = webkit_javascript_result_get_value(*js_result);
        If value
          *js_str_value = JSValueToStringCopy(*context, value, #Null);
          If *js_str_value
            str_length = JSStringGetMaximumUTF8CStringSize(*js_str_value);
            *str_value = g_malloc_(str_length);
            JSStringGetUTF8CString(*js_str_value, *str_value, str_length);
            JSStringRelease(*js_str_value)                               ;
            JavaResult = PeekS(*str_value, -1, #PB_UTF8)
            g_free_(*str_value)
          EndIf
        Else
          JavaResult = "Java Value is Nil"
        EndIf
        webkit_javascript_result_unref(*js_result)
        If \RunJavaScriptCallback
          \RunJavaScriptCallback(\Gadget, #True, \ScriptID, JavaResult)
        EndIf
      Else
        JavaResult = PeekS(*error\message, -1, #PB_UTF8)
        g_error_free_(*error)
        If \RunJavaScriptCallback
          \RunJavaScriptCallback(\Gadget, #False, \ScriptID, JavaResult)
        EndIf
      EndIf
    EndWith
    FreeStructure(*ScriptData)
  EndProcedure
  
  ; ----
  
  Procedure WebKit_Init(Gadget)
    Protected r1, *GadgetData.udtWebKitGadget, cancel
    
    If Not (GadgetType(Gadget) = #PB_GadgetType_Web Or GadgetType(Gadget) = 35); #PB_GadgetType_WebView)
      ProcedureReturn 0
    EndIf
    
    *GadgetData = AddMapElement(mapWebKitGadget(), Str(Gadget))
    If Not *GadgetData
      ProcedureReturn 0
    EndIf
    
    With *GadgetData
      \Gadget = Gadget
      Select GadgetType(Gadget)
        Case #PB_GadgetType_Web
          \WebView = GadgetID(Gadget)
        Case 35;#PB_GadgetType_WebView
          \WebView = gtk_bin_get_child_(GadgetID(Gadget))
      EndSelect
      \Window = g_object_get_data_(gtk_widget_get_toplevel_(\WebView), "pb_id")
      ; Bind Signals
      \signal_load_changed = g_signal_connect_(\WebView, "load-changed", @_signal_load_changed_cb(), *GadgetData)
      \signal_mouse_target_changed = g_signal_connect_(\WebView, "mouse-target-changed", @_signal_mouse_target_changed_cb(), *GadgetData)
      \signal_load_failed = g_signal_connect_(\WebView, "load-failed", @_signal_load_failed_cb(), *GadgetData)
      \signal_load_failed_with_tls_errors = g_signal_connect_(\WebView, "load-failed-with-tls-errors", @_signal_load_failed_with_tls_errors_cb(), *GadgetData)
      \signal_web_process_crashed = g_signal_connect_(\WebView, "web-process-crashed", @_signal_web_process_crashed_cb(), *GadgetData)
      \signal_button_press_event = g_signal_connect_(\WebView, "button-press-event", @_signal_button_press_event_cb(), *GadgetData)
      \signal_permission_request = g_signal_connect_(\WebView, "permission-request", @_signal_permission_request_cb(), *GadgetData)
    EndWith
    ProcedureReturn *GadgetData
  EndProcedure
  
  ; ----
  
  Procedure WebKit_Free(Gadget)
    Protected *GadgetData.udtWebKitGadget
    
    *GadgetData = FindMapElement(mapWebKitGadget(), Str(Gadget))
    If Not *GadgetData
      ProcedureReturn 0
    EndIf
    
    With *GadgetData
      ; Unbind Signals
      If g_signal_handler_is_connected_(\WebView, \signal_load_changed)
        g_signal_handler_disconnect_(\WebView, \signal_load_changed)
      EndIf
      If g_signal_handler_is_connected_(\WebView, \signal_mouse_target_changed)
        g_signal_handler_disconnect_(\WebView, \signal_mouse_target_changed)
      EndIf
      If g_signal_handler_is_connected_(\WebView, \signal_load_failed)
        g_signal_handler_disconnect_(\WebView, \signal_load_failed)
      EndIf
      If g_signal_handler_is_connected_(\WebView, \signal_load_failed_with_tls_errors)
        g_signal_handler_disconnect_(\WebView, \signal_load_failed_with_tls_errors)
      EndIf
      If g_signal_handler_is_connected_(\WebView, \signal_web_process_crashed)
        g_signal_handler_disconnect_(\WebView, \signal_web_process_crashed)
      EndIf
      If g_signal_handler_is_connected_(\WebView, \signal_button_press_event)
        g_signal_handler_disconnect_(\WebView, \signal_button_press_event)
      EndIf
      DeleteMapElement(mapWebKitGadget())
    EndWith
  EndProcedure
  
  ; ----
  
  Procedure WebKit_LoadURI(Gadget, URI.s)
    Protected r1, *GadgetData.udtWebKitGadget
    
    *GadgetData = FindMapElement(mapWebKitGadget(), Str(Gadget))
    If *GadgetData
      r1 = webkit_web_view_load_uri(*GadgetData\WebView, URI)
    EndIf
    ProcedureReturn r1
  EndProcedure
  
  ; ----
  
  Procedure WebKit_LoadHTML(Gadget, Content.s, Base_URI.s = "localhost")
    Protected r1, *GadgetData.udtWebKitGadget
    
    *GadgetData = FindMapElement(mapWebKitGadget(), Str(Gadget))
    If *GadgetData
      r1 = webkit_web_view_load_html(*GadgetData\WebView, Content, Base_URI)
    EndIf
    ProcedureReturn r1
  EndProcedure
  
  ; ----
  
  Procedure WebKit_LoadFile(Gadget, FileName.s)
    Protected r1, file.s, *GadgetData.udtWebKitGadget
    
    If FileSize(FileName) > 0
      *GadgetData = FindMapElement(mapWebKitGadget(), Str(Gadget))
      If *GadgetData
        file = "file://" + FileName
        r1 = webkit_web_view_load_uri(*GadgetData\WebView, file)
      EndIf
    EndIf
    ProcedureReturn r1
  EndProcedure
  
  ; ----
  
  Procedure.s WebKit_GetURI(Gadget)
    Protected s1.s, *gchar, *GadgetData.udtWebKitGadget
    
    *GadgetData = FindMapElement(mapWebKitGadget(), Str(Gadget))
    If *GadgetData
      *gchar = webkit_web_view_get_uri(*GadgetData\WebView)
      If *gchar
        s1 = PeekS(*gchar, -1, #PB_Ascii)
      EndIf
    EndIf
    ProcedureReturn s1
  EndProcedure
  
  ; ----
  
  Procedure.s WebKit_GetTitle(Gadget)
    Protected s1.s, *gchar, *GadgetData.udtWebKitGadget
    
    *GadgetData = FindMapElement(mapWebKitGadget(), Str(Gadget))
    If *GadgetData
      *gchar = webkit_web_view_get_title(*GadgetData\WebView)
      If *gchar
        s1 = PeekS(*gchar, -1, #PB_Ascii)
      EndIf
    EndIf
    ProcedureReturn s1
  EndProcedure
  
  ; ----
  
  Procedure WebKit_SetHitTestCallback(Gadget, *Callback.WebKit_HitTestCallback)
    Protected *GadgetData.udtWebKitGadget
    
    *GadgetData = FindMapElement(mapWebKitGadget(), Str(Gadget))
    If *GadgetData
      *GadgetData\HitTestCallback = *Callback
    EndIf
  EndProcedure
  
  ; ----
  
  Procedure WebKit_SetNavigationCallback(Gadget, *Callback.WebKit_NavigationCallback)
    Protected *GadgetData.udtWebKitGadget
    
    *GadgetData = FindMapElement(mapWebKitGadget(), Str(Gadget))
    If *GadgetData
      *GadgetData\NavigationCallback = *Callback
    EndIf
  EndProcedure
  
  ; ----
  
  Procedure WebKit_SetPermissionCallback(Gadget, *Callback.Webkit_PermissionCallback)
    Protected *GadgetData.udtWebKitGadget
    
    *GadgetData = FindMapElement(mapWebKitGadget(), Str(Gadget))
    If *GadgetData
      *GadgetData\PermissionCallback = *Callback
    EndIf
  EndProcedure
  
  ; ----
  
  Procedure WebKit_GetHtmlCode(Gadget, *Callback.WebKit_GetHtmlCodeCallback)
    Protected r1, *GadgetData.udtWebKitGadget
    
    With *GadgetData
      *GadgetData = FindMapElement(mapWebKitGadget(), Str(Gadget))
      If *GadgetData
        \Resource = webkit_web_view_get_main_resource(\WebView)
        If \Resource
          \GetDataCallback = *Callback
          webkit_web_resource_get_data(\Resource, 0, @_get_response_data_finish_cb(), *GadgetData)
          r1 = #True
        EndIf
      EndIf
    EndWith
    ProcedureReturn r1
  EndProcedure
  
  ; ----
  
  Procedure WebKit_RunJavaScript(Gadget, ScriptID, JavaScript.s, *Callback.WebKit_RunJavaScriptCallback)
    Protected *GadgetData.udtWebKitGadget, *ScriptData.udtJavaScriptData
    Protected r1
    
    With *GadgetData
      *GadgetData = FindMapElement(mapWebKitGadget(), Str(Gadget))
      If *GadgetData
        *ScriptData = AllocateStructure(udtJavaScriptData)
        If *ScriptData
          *ScriptData\Gadget = \Gadget
          *ScriptData\ScriptID = ScriptID
          *ScriptData\RunJavaScriptCallback = *Callback
          webkit_web_view_run_javascript(\WebView, JavaScript, #Null, @_web_view_javascript_finished_cb(), *ScriptData)
          r1 = #True
        EndIf
      EndIf
    EndWith
    ProcedureReturn r1  
  EndProcedure
  
  ; ----
  
  Procedure WebKit_DisableJavaScript(Gadget, State)
    Protected *GadgetData.udtWebKitGadget, *settings
    Protected r1
    
    With *GadgetData
      *GadgetData = FindMapElement(mapWebKitGadget(), Str(Gadget))
      If *GadgetData
        *settings = webkit_web_view_get_settings(*GadgetData\WebView)
        If State
          webkit_settings_set_enable_javascript(*settings, #False)
        Else
          webkit_settings_set_enable_javascript(*settings, #True)
        EndIf
      EndIf
    EndWith
  EndProcedure
  
  ; ----
  
  Procedure WebKit_IsEnableJavaScript(Gadget)
    Protected *GadgetData.udtWebKitGadget, *settings
    Protected r1
    
    With *GadgetData
      *GadgetData = FindMapElement(mapWebKitGadget(), Str(Gadget))
      If *GadgetData
        *settings = webkit_web_view_get_settings(*GadgetData\WebView)
        r1 = webkit_settings_get_enable_javascript(*settings)
      EndIf
    EndWith
    ProcedureReturn r1
  EndProcedure
  
  ; ----
  
  Procedure WebKit_GetProperty(Gadget, Property.s, *Value.gvalue)
    Protected *GadgetData.udtWebKitGadget, *settings
    Protected r1, value.gvalue
    
    With *GadgetData
      If *value
        *GadgetData = FindMapElement(mapWebKitGadget(), Str(Gadget))
        If *GadgetData
          *settings = webkit_web_view_get_settings(*GadgetData\WebView)
          g_object_get_property_(*settings, Property, *value)
          r1 = *Value\g_type
        EndIf
      EndIf
    EndWith
    ProcedureReturn r1
  EndProcedure
  
  ; ----
  
  Procedure WebKit_SetProperty(Gadget, Property.s, *Value.gvalue)
    Protected *GadgetData.udtWebKitGadget, *settings
    Protected r1, value.gvalue
    
    With *GadgetData
      If *value
        *GadgetData = FindMapElement(mapWebKitGadget(), Str(Gadget))
        If *GadgetData
          *settings = webkit_web_view_get_settings(*GadgetData\WebView)
          r1 =g_object_set_property_(*settings, Property, *value)
        EndIf
      EndIf
    EndWith
    ProcedureReturn r1
  EndProcedure
  
  ; ----
  
  Procedure WebKit_SetAcceleration(Gadget, Policy)
    Protected webview, *settings
    Select GadgetType(gadget)
      Case #PB_GadgetType_Web
        webview = GadgetID(Gadget)
      Case 35; #PB_GadgetType_WebView
        webview = gtk_bin_get_child_(GadgetID(Gadget))
      Default
        ProcedureReturn 0
    EndSelect
    *settings = webkit_web_view_get_settings(webview)
    webkit_settings_set_hardware_acceleration_policy(*settings, Policy)
  EndProcedure
  
EndModule

; ****
Last edited by mk-soft on Sun Mar 03, 2024 12:39 pm, edited 31 times in total.
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
mk-soft
Always Here
Always Here
Posts: 5335
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: WebGadget Extension (PB v6.00 GTK3)

Post by mk-soft »

Mini Browser Example
- Update v1.06.7

Code: Select all

;-TOP

; Comment : WebGadgetEx Example (GTK3)
; Compiler: Purebasic v6.10 (Ubuntu 20.04 LTS, Raspberry PI)
; Author  : mk-soft
; Version : v1.06.7
; Create  : 26.11.2021
; Update  : 02.03.2024

; ---------------------

IncludeFile "WebGadgetEx.pb"

UseModule WebKit2

Enumeration Windows 1
  #Main
EndEnumeration

Enumeration Menu
  #MainMenu
EndEnumeration

Enumeration MenuItem
  #MainMenuExit
  #MainMenuGetHtmlData
  #MainMenuLoadHTML
  #MainMenuLoadFile
  #MainMenuDisableJavaScript
  #MainMenuRunJavaScript
EndEnumeration

Enumeration Gadgets
  #MainButtonLoad
  #MainButtonStop
  #MainButtonBack
  #MainButtonForward
  #MainButtonReload
  #MainStringURI
  #MainWebGadget
EndEnumeration

Enumeration Status
  #MainStatusBar
EndEnumeration

Global ExitApplication

; ****

Procedure UpdateWindow()
  Protected dx, dy
  dx = WindowWidth(#Main)
  dy = WindowHeight(#Main) - StatusBarHeight(#MainStatusBar) - MenuHeight() - 45
  ResizeGadget(#MainWebGadget, 0, 45, dx, dy)
EndProcedure

; ----

Procedure MyHitTestCB(Gadget, Type, Text.s)
  
  Select Type
    Case #WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK
      StatusBarText(#MainStatusBar, 1, "HitTest: " + Text)
      ;Debug "HitTestCB Link: " + Text
      
    Case #WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE
      ;Debug "HitTestCB Image: " + Text
      
    Case #WEBKIT_HIT_TEST_RESULT_CONTEXT_MEDIA
      ;Debug "HitTestCB Media: " + Text
      
    Case #WEBKIT_HIT_TEST_RESULT_CONTEXT_DOCUMENT
      StatusBarText(#MainStatusBar, 1, "HitTest: Dokument")
      ;Debug "HitTestCB Dokument"
      
  EndSelect
                      
EndProcedure  

; ----

Procedure MyGetHtmlDataCB(Gadget, State, Text.s)
  
  If State
    Debug "*** Get Data Callback ***"
    Debug Text
    Debug "*************************"
  Else
    Debug "*** Get Data Callback ***"
    Debug "Error: " + Text
    Debug "*************************"
  EndIf
  
EndProcedure

Procedure MyJavaScripCB(Gadget, State, ScriptID, Result.s)
  
  If State
    Debug "*** JavaScript Callback ***"
    Debug "ScriptID: " + ScriptID
    Debug "Result: " + Result
    Debug "*************************"
  Else
    Debug "*** JavaScript Callback ***"
    Debug "ScriptID " + ScriptID
    Debug "Error: " + Result
    Debug "*************************"
  EndIf
  
EndProcedure

; ----

Procedure MyNavigationCB(Gadget, Uri.s)
  
  If FindString(uri, "#top")
    ProcedureReturn #True
  EndIf
    
  If MessageRequester("Questions", "Open: " + URI, #PB_MessageRequester_YesNo | #PB_MessageRequester_Warning) = #PB_MessageRequester_Yes
    ProcedureReturn #True
  Else
    ProcedureReturn #False
  EndIf
  
EndProcedure

Procedure MyPermissionCB(Gadget, RequestName.s, *Request)
  Protected r1, permission_str.s
  Select RequestName
    Case "WebKitGeolocationPermissionRequest"
      permission_str = "Allow this site to see your location?";
    Case "WebKitNotificationPermissionRequest"
      permission_str = "Allow notifications from this website?";
    Case "WebKitDeviceInfoPermissionRequest"
      permission_str = "Allow this site to see your device info?";
    Case "WebKitUserMediaPermissionRequest"
      If webkit_user_media_permission_is_for_audio_device(*request)
        permission_str = "Allow this site to access your microphone?";
      ElseIf webkit_user_media_permission_is_for_video_device(*request)
        permission_str = "Allow this site to access your webcam?";
      Else
        ProcedureReturn #False
      EndIf
    Default
      ProcedureReturn #False
  EndSelect
  
  r1 = MessageRequester("Permission Request", permission_str, #PB_MessageRequester_YesNo)
  If r1 = #PB_MessageRequester_Yes
    ProcedureReturn #True
  Else
    ProcedureReturn #False
  EndIf
EndProcedure

Procedure Main()
  Protected x, dx, dy, text.s, file.s, *Error.WebKitLoadError, *ErrorTLS.WebKitLoadErrorTLS
  Protected Script.s
  
  #MainStyle = #PB_Window_SystemMenu | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget
  
  If OpenWindow(#Main, 100, 100, 800, 600, "WebKit" , #MainStyle)
    CreateMenu(#MainMenu, WindowID(#Main))
    MenuTitle("File")
    MenuItem(#MainMenuGetHtmlData, "&Get HTML Code")
    MenuItem(#MainMenuLoadHTML, "Load &HTLM")
    MenuItem(#MainMenuLoadFile, "Load &File")
    MenuBar()
    MenuItem(#MainMenuDisableJavaScript, "Disable JavaScript")
    MenuItem(#MainMenuRunJavaScript, "Run JavaScript")
    MenuBar()
    MenuItem(#MainMenuExit, "E&xit")
    
    CreateStatusBar(#MainStatusBar, WindowID(#Main))
    AddStatusBarField(160)
    AddStatusBarField(#PB_Ignore)
    
    x = 5
    ButtonGadget(#MainButtonReload, x, 5, 90, 30, "Reload")
    x + 95
    ButtonGadget(#MainButtonStop, x, 5, 90, 30, "Stop")
    x + 95
    ButtonGadget(#MainButtonBack, x, 5, 90, 30, "Back")
    x + 95
    ButtonGadget(#MainButtonForward, x, 5, 90, 30, "Forward")
    x + 95
    ButtonGadget(#MainButtonLoad, x, 5, 90, 30, "Load")
    x + 95
    StringGadget(#MainStringURI, x, 5, WindowWidth(#Main) - x - 5, 30, "about:blank")
    
    dx = WindowWidth(#Main)
    dy = WindowHeight(#Main) - StatusBarHeight(#MainStatusBar) - MenuHeight() - 45
    WebGadget(#MainWebGadget, 0, 45, dx, dy, "about:blank")
    WebKit_Init(#MainWebGadget)
    WebKit_SetAcceleration(#MainWebGadget, #WEBKIT_HARDWARE_ACCELERATION_POLICY_NEVER)
    WebKit_LoadURI(#MainWebGadget, "https://www.purebasic.com")
    
    WebKit_SetHitTestCallback(#MainWebGadget, @MyHitTestCB())
    WebKit_SetNavigationCallback(#MainWebGadget, @MyNavigationCB())
    WebKit_SetPermissionCallback(#MainWebGadget, @MyPermissionCB())
    
    BindEvent(#PB_Event_SizeWindow, @UpdateWindow())
    
    Repeat
      Select WaitWindowEvent()
        Case #PB_Event_CloseWindow
          ExitApplication = #True
          
        Case #PB_Event_Menu
          Select EventMenu()
            Case #MainMenuGetHtmlData
              WebKit_GetHtmlCode(#MainWebGadget, @MyGetHtmlDataCB())
              
            Case #MainMenuLoadHTML
              file = OpenFileRequester("File", "", "", 0)
              If ReadFile(0, file)
                text = ReadString(0, #PB_File_IgnoreEOL | #PB_UTF8)
                WebKit_LoadHTML(#MainWebGadget, text)
              EndIf
              
            Case #MainMenuLoadFile
              file = OpenFileRequester("HTML File", "", "", 0)
              If file
                WebKit_LoadFile(#MainWebGadget, file)
              EndIf
              
            Case #MainMenuDisableJavaScript
              If GetMenuItemState(#MainMenu, #MainMenuDisableJavaScript)
                WebKit_DisableJavaScript(#MainWebGadget, #False)
                SetMenuItemState(#MainMenu, #MainMenuDisableJavaScript, #False)
              Else
                WebKit_DisableJavaScript(#MainWebGadget, #True)
                SetMenuItemState(#MainMenu, #MainMenuDisableJavaScript, #True)
              EndIf
              
            Case #MainMenuRunJavaScript
              Script = InputRequester("JavaScript", "Code:", "window.scrollTo(0,500);")
              If Script
                Debug WebKit_RunJavaScript(#MainWebGadget, 1, Script, @MyJavaScripCB())
              EndIf
              
            Case #MainMenuExit
              ExitApplication = #True
              
          EndSelect
                      
        Case #PB_Event_Gadget
          Select EventGadget()
            Case #MainButtonLoad
              ;SetGadgetText(#MainWebGadget, GetGadgetText(#MainStringURI))
              WebKit_LoadURI(#MainWebGadget, GetGadgetText(#MainStringURI))
              
            Case #MainButtonReload
              SetGadgetState(#MainWebGadget, #PB_Web_Refresh)
              
            Case #MainButtonStop
              SetGadgetState(#MainWebGadget, #PB_Web_Stop)
              
            Case #MainButtonBack
              SetGadgetState(#MainWebGadget, #PB_Web_Back)
              
            Case #MainButtonForward
              SetGadgetState(#MainWebGadget, #PB_Web_Forward)
              
            Case #MainWebGadget
              Select EventType()
                Case #PB_Eventtype_WebLoadStarted
                  StatusBarText(#MainStatusBar, 0, "Load started")
                  
                Case #PB_Eventtype_WebLoadCommitted
                  StatusBarText(#MainStatusBar, 0, "Load committed")
                  
                Case #PB_Eventtype_WebLoadFinished
                  StatusBarText(#MainStatusBar, 0, "Load finished")
                  SetWindowTitle(#Main, "WebKit - " + WebKit_GetURI(#MainWebGadget))
                  SetGadgetText(#MainStringURI, WebKit_GetURI(#MainWebGadget))
                  
                Case #PB_Eventtype_WebLoadRedirected
                  StatusBarText(#MainStatusBar, 0, "Load redirected")
                  SetWindowTitle(#Main, "WebKit - " + WebKit_GetURI(#MainWebGadget))
                  
                Case #PB_Eventtype_WebLoadFailed
                  *Error = EventData()
                  text = "Link: " + *Error\Link + #LF$ + #LF$
                  text + *Error\Message
                  MessageRequester("Error", text, #PB_MessageRequester_Error)
                  
                Case #PB_Eventtype_WebLoadFailedTLS
                  *ErrorTLS = EventData()
                  text = "Link: " + *ErrorTLS\Link + #LF$ + #LF$
                  text + "Code: " + Hex(*ErrorTLS\Errors)
                  MessageRequester("TLS Error", text, #PB_MessageRequester_Error)
                  
                Case #PB_EventType_WebProcessCrashed
                  StatusBarText(#MainStatusBar, 0, "Web process crashed")
                
              EndSelect
          EndSelect
          
      EndSelect
    Until ExitApplication
    
    WebKit_Free(#MainWebGadget)
    
  EndIf
  
EndProcedure : Main()
Last edited by mk-soft on Sat Mar 02, 2024 7:38 pm, edited 10 times in total.
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
useful
Enthusiast
Enthusiast
Posts: 367
Joined: Fri Jul 19, 2013 7:36 am

Re: WebGadget Extension (PB v6.00 GTK3)

Post by useful »

I usually use mint xfce or xubuntu, but for pure experimentation I put classic ubuntu 20.04.3
Everything compiles and works fine, including your example, but I expected that with 6.0 we would be spared:

[22:37:01] Waiting for executable to start...
[22:37:01] Executable type: Linux - x64 (64bit, Unicode)
[22:37:01] Executable started.
[22:37:02] [WARNING] wg.pb (Line: 1)
[22:37:02] [WARNING] GLib-GIO (DEBUG): _g_io_module_get_default: Found default implementation gvfs (GDaemonVfs) for ‘gio-vfs’
[22:37:02] [WARNING] wg.pb (Line: 112)
[22:37:02] [WARNING] GLib (DEBUG): posix_spawn avoided (child_setup specified)
[22:37:02] [WARNING] wg.pb (Line: 112)
[22:37:02] [WARNING] GLib (DEBUG): posix_spawn avoided (child_setup specified)
[22:37:04] [WARNING] wg.pb (Line: 120)
[22:37:04] [WARNING] GLib-GIO (DEBUG): _g_io_module_get_default: Found default implementation gnutls (GTlsBackendGnutls) for ‘gio-tls-backend’
[22:37:08] The Program execution has finished.


Do you have these warnings too?
Dawn will come inevitably.
User avatar
mk-soft
Always Here
Always Here
Posts: 5335
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: WebGadget Extension (PB v6.00 GTK3)

Post by mk-soft »

Update v1.01.2
- Fix: Now send event with right window id

; ----

I also have some warnings. But not only with my code.
It depends on the GCC compiler and developers libraries which warnings come up.

But you can ignore them.

OS: Ubuntu 2104 LTS

[17:29:02] Executable-Typ: Linux - x64 (64bit, Unicode)
[17:29:02] Executable gestartet.
[17:29:02] [WARNING] WebGadgetEx_Example.pb (Zeile: 1)
[17:29:02] [WARNING] GLib-GIO (DEBUG): _g_io_module_get_default: Found default implementation gvfs (GDaemonVfs) for ‘gio-vfs’
[17:29:02] [WARNING] WebGadgetEx_Example.pb (Zeile: 120)
[17:29:02] [WARNING] GLib-GIO (DEBUG): _g_io_module_get_default: Found default implementation gnutls (GTlsBackendGnutls) for ‘gio-tls-backend’
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
mk-soft
Always Here
Always Here
Posts: 5335
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: WebGadget Extension (PB v6.00 GTK3)

Post by mk-soft »

Update v1.2.1
- Added: #PB_Eventtype_WebLoadFailed ; Detail over EventData()
- Added: #PB_Eventtype_WebLoadFailedTLS ; Detail over EventData()
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
Borstensohn
User
User
Posts: 11
Joined: Sun Jun 05, 2005 9:45 pm

Re: WebGadget Extension (PB v6.00 GTK3)

Post by Borstensohn »

I use Xubuntu 21.10 and PureBasic 5.73 LTS, your test program refuses to run, and this is the error message I get:

/usr/bin/ld: purebasic.o: in function `PB_DEBUGGER_ModuleBank':
(.data+0x15d8): undefined reference to `webkit_web_view_get_main_resource'
/usr/bin/ld: (.data+0x15e0): undefined reference to `webkit_web_resource_get_data'
/usr/bin/ld: (.data+0x15e8): undefined reference to `webkit_web_view_load_html'
/usr/bin/ld: (.data+0x15f0): undefined reference to `webkit_hit_test_result_get_context'
/usr/bin/ld: (.data+0x15f8): undefined reference to `webkit_web_view_load_uri'
/usr/bin/ld: (.data+0x1600): undefined reference to `webkit_hit_test_result_get_link_uri'
...
collect2: error: ld returned 1 exit status
ON ERROR GOTO BED
User avatar
mk-soft
Always Here
Always Here
Posts: 5335
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: WebGadget Extension (PB v6.00 GTK3)

Post by mk-soft »

PB v5.73 does not support Webkit2gtk-4.0, only Webkitgtk and Webkitgtk-3.0.

The Webkitgtk and Webkitgtk-3.0 is no longer supported since Ubuntu 19.04.

Use PB v6.00 Beta (20.04)
Webkit2gtk-4.0 supports gtk3 (gtk2 is no longer supported)
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
mk-soft
Always Here
Always Here
Posts: 5335
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: WebGadget Extension (PB v6.00 GTK3)

Post by mk-soft »

Update v1.03.2
- Added: WebKit_RunJavaScript(...)
- Added: #PB_EventType_WebRunJavaScriptFinished
- Added: #PB_EventType_WebRunJavaScriptFailed

Update v1.03.3
- WebKit_RunJavaScript added optional parameter ScriptID. Use EventData() to get ScriptID

For example java script :wink:

scroll window to
window.scrollTo(0,500);
get scroll y
window.scrollY;
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
mk-soft
Always Here
Always Here
Posts: 5335
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: WebGadget Extension (PB v6.00 GTK3)

Post by mk-soft »

Update v1.04.1
- Remove WebKit_GetDataAsynchron
- Remove Webkit_GetDataHTML
- Remove #PB_EventType_WebGetDataFinished
- Added WebKit_GetHtmlCode(Gadget, *Callback.WebKit_GetHtmlCodeCallback)
- ----
- Remove #PB_EventType_WebRunJavaScriptFinished
- Remove #PB_EventType_WebRunJavaScriptFailed
- Change WebKit_RunJavaScript(Gadget, ScriptID, JavaScript.s, *Callback.WebKit_RunJavaScriptCallback)
- ----
- Added WebKit_DisableJavaScript(Gadget, State)
- Added WebKit_IsEnableJavaScript(Gadget)

The callbacks are hooked into the MainScope by webkit2gtk.
Thus, no 'ThreadSafe' is required as the callback is called internally in the event loop.

Syntax Callback:
- HitTestCallback(Gadget, Type, Text.s)
- GetHtmlCodeCallback(Gadget, State, HtmlCode.s)
- RunJavaScriptCallback(Gadget, State, ScriptID, JavaResult.s)
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
StarBootics
Addict
Addict
Posts: 984
Joined: Sun Jul 07, 2013 11:35 am
Location: Canada

Re: WebGadget Extension (PB v6.00 GTK3)

Post by StarBootics »

Hello everyone,

Something completely weird if I load the source "WebGadgetEx.pb" and I run the compiler with the debugger active I get
/usr/bin/ld : purebasic.o : dans la fonction « PB_DEBUGGER_ModuleBank » :
(.data+0xfc8) : référence indéfinie vers « webkit_web_view_get_main_resource »
/usr/bin/ld : (.data+0xfd0) : référence indéfinie vers « webkit_javascript_result_get_value »
/usr/bin/ld : (.data+0xfd8) : référence indéfinie vers « webkit_web_resource_get_data »
/usr/bin/ld : (.data+0xfe0) : référence indéfinie vers « JSValueIsNumber »
/usr/bin/ld : (.data+0xfe8) : référence indéfinie vers « webkit_web_view_get_settings »
/usr/bin/ld : (.data+0xff0) : référence indéfinie vers « webkit_settings_get_enable_javascript »
...
collect2: error: ld returned 1 exit status
And without the debugger I get :
/usr/bin/ld : purebasic.o : dans la fonction « _SYS_StaticStringEnd » :
(.data+0x1c8) : référence indéfinie vers « webkit_web_view_get_main_resource »
/usr/bin/ld : (.data+0x1d0) : référence indéfinie vers « webkit_javascript_result_get_value »
/usr/bin/ld : (.data+0x1d8) : référence indéfinie vers « webkit_web_resource_get_data »
/usr/bin/ld : (.data+0x1e0) : référence indéfinie vers « JSValueIsNumber »
/usr/bin/ld : (.data+0x1e8) : référence indéfinie vers « webkit_web_view_get_settings »
/usr/bin/ld : (.data+0x1f0) : référence indéfinie vers « webkit_settings_get_enable_javascript »
...
collect2: error: ld returned 1 exit status
If I try the example "WebGadgetEx Example.pb" that include "WebGadgetEx.pb" everything work fine.

I'm using Ubuntu 21.10 and PB V6.00 Beta 6.

Best regards
StarBootics
The Stone Age did not end due to a shortage of stones !
User avatar
mk-soft
Always Here
Always Here
Posts: 5335
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: WebGadget Extension (PB v6.00 GTK3)

Post by mk-soft »

Without using the WegGadget the compiler not linked the webkit library!

You can add this line inside the Module to force the webkit library.

Code: Select all

If 0 : WebGadget(0, 0, 0, 0, 0, "") : EndIf
But normality not needed
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
StarBootics
Addict
Addict
Posts: 984
Joined: Sun Jul 07, 2013 11:35 am
Location: Canada

Re: WebGadget Extension (PB v6.00 GTK3)

Post by StarBootics »

Hello again,

I'm trying to make the following code to work :

Code: Select all

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Project name : Gtk WebView Widget
; File Name : Gtk WebView Widget - OOP.pb
; File version: 0.0.0
; Programming : Linker Errors problem
; Programmed by : StarBootics
; Date : April 3rd, 2022
; Last Update : April 3rd, 2022
; PureBasic code : V6.00 Beta 6
; Platform : Windows, Linux, MacOS X
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

DeclareModule GtkWindow
  
  Interface Window
    
    GetID.i()
    GetPosition(*PosX, *PosY)
    SetPosition(Position.i = #GTK_WIN_POS_NONE)
    SetSize(Width.l, Height.l)
    SetTitle(Title.s)
    SetResizable(Resizable.i)
    SetBorderWidth(BorderWidth.l)
    SetTransientFor(*Parent)
    SetKeepAbove(Setting.i)
    Move(X.l, Y.l)
    Show()
    SignalConnect(SignalName.s, *CallBack, UserData.i)
    AddWidget(*Widget)
    Free()
    
  EndInterface
  
  Declare.i New()
  
EndDeclareModule

Module GtkWindow
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Déclaration de la Structure <<<<<

  Structure Private_Members
    
    VirtualTable.i
    *WindowID
    
  EndStructure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Les observateurs <<<<<

  Procedure.i GetID(*This.Private_Members)
    
    ProcedureReturn *This\WindowID
  EndProcedure
  
  Procedure GetPosition(*This.Private_Members, *PosX, *PosY)
    
    gtk_window_get_position_(*This\WindowID, *PosX, *PosY)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Les mutateurs <<<<<
  
  Procedure SetPosition(*This.Private_Members, Position.i = #GTK_WIN_POS_NONE)
    
    gtk_window_set_position_(*This\WindowID, Position)
    
  EndProcedure
  
  Procedure SetSize(*This.Private_Members, Width.l, Height.l)
    
    gtk_window_set_default_size_(*This\WindowID, Width, Height)
    
  EndProcedure
  
  Procedure SetTitle(*This.Private_Members, Title.s)
    
    gtk_window_set_title_(*This\WindowID, Title)
    
  EndProcedure
  
  Procedure SetResizable(*This.Private_Members, Resizable.i)
    
    gtk_window_set_resizable_(*This\WindowID, Resizable)
    
  EndProcedure
  
  Procedure SetBorderWidth(*This.Private_Members, BorderWidth.l)
    
    gtk_container_set_border_width_(*This\WindowID, BorderWidth)
    
  EndProcedure
  
  Procedure SetTransientFor(*This.Private_Members, *Parent)
    
    gtk_window_set_transient_for_(*This\WindowID, *Parent)
    
  EndProcedure

  Procedure SetKeepAbove(*This.Private_Members, Setting.i)
    
    gtk_window_set_keep_above_(*This\WindowID, Setting)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< L'opérateur Move <<<<<
  
  Procedure Move(*This.Private_Members, X.l, Y.l)
    
    gtk_window_move_(*This\WindowID, X, Y)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< L'opérateur Show <<<<<
  
  Procedure Show(*This.Private_Members)
    
     gtk_widget_show_all_(*This\WindowID)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Nom de la procédure <<<<<
  
  Procedure SignalConnect(*This.Private_Members, SignalName.s, *CallBack, UserData.i)
    
    g_signal_connect_(*This\WindowID, SignalName, *CallBack, UserData)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Nom de la procédure <<<<<
  
  Procedure AddWidget(*This.Private_Members, *Widget)
    
    gtk_container_add_(*This\WindowID, *Widget)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Le Destructeur <<<<<

  Procedure Free(*This.Private_Members)
    
    FreeStructure(*This)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Le Constructeur <<<<<

  Procedure.i New()
    
    *This.Private_Members = AllocateStructure(Private_Members)
    *This\VirtualTable = ?START_METHODS
    
    *This\WindowID = gtk_window_new_(#GTK_WINDOW_TOPLEVEL)
    
    ProcedureReturn *This
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Les entrées de la table virtuelle <<<<<

  DataSection
    START_METHODS:
    Data.i @GetID()
    Data.i @GetPosition()
    Data.i @SetPosition()
    Data.i @SetSize()
    Data.i @SetTitle()
    Data.i @SetResizable()
    Data.i @SetBorderWidth()
    Data.i @SetTransientFor()
    Data.i @SetKeepAbove()
    Data.i @Move()
    Data.i @Show()
    Data.i @SignalConnect()
    Data.i @AddWidget()
    Data.i @Free()
    END_METHODS:
  EndDataSection
  
EndModule

DeclareModule GtkWebView
  
  Interface WebView
    
    GetID.i()
    GetUri.s()
    GetTitle.s()
    LoadUri.i(Uri.s)
    LoadHtml.i(Content.s, Base_URI.s = "localhost")
    Free()
    
  EndInterface
  
  Declare.i New()
  
EndDeclareModule

Module GtkWebView
  
  ImportC ""
    
    webkit_web_view_new()
    webkit_web_view_load_uri(*web_view, url.p-utf8)
    webkit_web_view_load_html(*web_view, content.p-utf8, base_uri.p-utf8)
    webkit_web_view_get_uri(*web_view)
    webkit_web_view_get_title(*web_view)
    
;     webkit_hit_test_result_get_context(*hit_test_result)
;     
;     webkit_hit_test_result_context_is_link(*hit_test_result)
;     webkit_hit_test_result_context_is_image(*hit_test_result)
;     webkit_hit_test_result_context_is_media(*hit_test_result)
;     webkit_hit_test_result_context_is_editable(*hit_test_result)
;     webkit_hit_test_result_context_is_selection(*hit_test_result)
;     webkit_hit_test_result_context_is_scrollbar(*hit_test_result)
;     
;     webkit_hit_test_result_get_link_uri(*hit_test_result)
;     webkit_hit_test_result_get_link_title(*hit_test_result)
;     webkit_hit_test_result_get_link_label(*hit_test_result)
;     webkit_hit_test_result_get_image_uri(*hit_test_result)
;     webkit_hit_test_result_get_media_uri(*hit_test_result)
;     
;     webkit_web_view_get_main_resource(*web_view) ; Result WebKitWebResource
;     webkit_web_resource_get_data(*resource, *cancellable, *callback, user_data)
;     webkit_web_resource_get_data_finish(*resource, *result, *length, *p_error)
;     
;     webkit_web_view_get_settings(*web_view)
;     webkit_web_view_set_settings(*web_view, *settings)
;     webkit_settings_get_enable_javascript(*settings)
;     webkit_settings_set_enable_javascript(*settings, enabled)
;     
;     webkit_web_view_run_javascript(*web_view, script.p-utf8, *cancellable, *callback, user_data)
;     webkit_web_view_run_javascript_finish(*web_view, *result, *p_error) ; *js_result
;     webkit_javascript_result_unref (*js_result)
;     webkit_javascript_result_get_global_context(*js_result)
;     webkit_javascript_result_get_value(*js_result)
;     
;     JSValueIsString(*context, value)
;     JSValueIsNumber(*context, value)
;     JSValueToStringCopy(*context, value, outException)
;     JSValueToNumber.d(*context, value, outException)
;     JSStringGetMaximumUTF8CStringSize(*js_str_value)
;     JSStringGetUTF8CString(*js_str_value, *str_value, str_length)
;     JSStringRelease(*js_str_value)
    
  EndImport
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Déclaration de la Structure <<<<<

  Structure Private_Members
    
    VirtualTable.i
    *WebViewID
    
  EndStructure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Les observateurs <<<<<

  Procedure.i GetID(*This.Private_Members)
    
    ProcedureReturn *This\WebViewID
  EndProcedure
  
  Procedure.s GetUri(*This.Private_Members)
    
    *gchar = webkit_web_view_get_uri(*This\WebViewID)
    
    If *gchar
      s1.s = PeekS(*gchar, -1, #PB_UTF8)
    EndIf
    
    ProcedureReturn s1
  EndProcedure
  
  Procedure.s GetTitle(*This.Private_Members)
    
    *gchar = webkit_web_view_get_title(*This\WebViewID)
    
    If *gchar
      s1.s = PeekS(*gchar, -1, #PB_UTF8)
    EndIf
    
    ProcedureReturn s1
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Nom de la procédure <<<<<
  
  Procedure.i LoadUri(*This.Private_Members, Uri.s)
    
    ProcedureReturn webkit_web_view_load_uri(*This\WebViewID, Uri)
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Nom de la procédure <<<<<
  
  Procedure.i LoadHtml(*This.Private_Members, Content.s, Base_URI.s = "localhost")
    
    ProcedureReturn webkit_web_view_load_html(*This\WebViewID, Content, Base_URI)
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Le Destructeur <<<<<

  Procedure Free(*This.Private_Members)
    
    FreeStructure(*This)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Le Constructeur <<<<<

  Procedure.i New()
    
    *This.Private_Members = AllocateStructure(Private_Members)
    *This\VirtualTable = ?START_METHODS
    
    *This\WebViewID = webkit_web_view_new()

    ProcedureReturn *This
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Les entrées de la table virtuelle <<<<<

  DataSection
    START_METHODS:
    Data.i @GetID()
    Data.i @GetUri()
    Data.i @GetTitle()
    Data.i @LoadUri()
    Data.i @LoadHtml()
    Data.i @Free()
    END_METHODS:
  EndDataSection
  
  If 0
    *This.Private_Members = New()
    GetUri(*This)
    GetTitle(*This)
    LoadUri(*This, "")
    LoadHtml(*This, "")
  EndIf
  
EndModule

CompilerIf #PB_Compiler_IsMainFile
  
  ProcedureC WindowDeleteEventHandler(*Widget.GtkWidget, *Event.GdkEventAny, UserData.I)
    
    Debug "WindowDeleteEventHandler"
    gtk_window_get_position_(*Widget, @X.l, @Y.l)
    
    Debug "Position (x,y) = (" + Str(X) + "," + Str(Y) + ")"
    
  EndProcedure
  
  ProcedureC WindowCloseHandler(*Widget.GtkWidget, *Event.GdkEventAny, UserData.I)
    
    gtk_main_quit_()
    
  EndProcedure

  gtk_init_(0, 0)
  
  MainWin.GtkWindow::Window = GtkWindow::New()
  MainWin\SetSize(800, 600)
  MainWin\SetTitle("Gtk WebView")
  MainWin\SetPosition(#GTK_WIN_POS_CENTER)
  MainWin\SetResizable(#False)
  MainWin\Move(100, 100)
  MainWin\SignalConnect("delete-event", @WindowDeleteEventHandler(), 25)
  MainWin\SignalConnect("destroy", @WindowCloseHandler(), 0)
  
  WebView.GtkWebView::WebView = GtkWebView::New()
  
  WebView\LoadUri("https://www.purebasic.com")
  
  MainWin\AddWidget(WebView\GetID())
  
  MainWin\Show()
  
  gtk_main_()
  
  MainWin\Free()
  
CompilerEndIf

; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< END OF FILE <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<
Unfortunately I get linker errors and I can't figure out why. Any ideas !?!

Best regards
StarBootics
The Stone Age did not end due to a shortage of stones !
User avatar
mk-soft
Always Here
Always Here
Posts: 5335
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: WebGadget Extension (PB v6.00 GTK3)

Post by mk-soft »

For the webkit you need something more.

Pack the WebkitView into a ScrolledWindow. Even if you can't control the ScrolledWindow from the outside, because internally only the Webkit does that.
I once had the Webkit (without Java) running with PB. The structure for the WebKit2gtk I had somewhere from a C++ example

Link: https://www.purebasic.fr/english/viewtopic.php?t=78246

I have not yet found the path to the library for ImportC. I use OpenLibrary ...
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
mk-soft
Always Here
Always Here
Posts: 5335
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: WebGadget Extension (PB v6.00 GTK3)

Post by mk-soft »

Update v1.05.1
- Added WebKit_SetNavigationCallback(Gadget, Callback)
* This fixed too the "web-process-crashed" on Raspberry Arm64 the click on a link
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
mk-soft
Always Here
Always Here
Posts: 5335
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: WebGadget Extension (PB v6.00 GTK3)

Post by mk-soft »

Update v1.06.2
- Added #PB_EventType_WebProcessCrashed
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Post Reply