📄 main.c
字号:
/**************************************************************************************************
* Author: Rio Tang ryotang@gmail.com
* File: main.c Main entry point of chuoren browser
* Lisence: GPL v3
window 状态改变后调用该函数
GDK_WINDOW_STATE_WITHDRAWN the window is not shown.
GDK_WINDOW_STATE_ICONIFIED the window is minimized.
GDK_WINDOW_STATE_MAXIMIZED the window is maximized.
GDK_WINDOW_STATE_STICKY the window is sticky.
GDK_WINDOW_STATE_FULLSCREEN the window is maximized without decorations.
GDK_WINDOW_STATE_ABOVE the window is kept above other windows.
GDK_WINDOW_STATE_BELOW the window is kept below other windows.
typedef struct {
GdkEventType type;
GdkWindow *window;
gint8 send_event;
GdkWindowState changed_mask;
GdkWindowState new_window_state;
} GdkEventWindowState;
CURL
struct CURLMsg {
CURLMSG msg; / what this message means/
CURL *easy_handle; /the handle it concerns /
union { void *whatever; / message-specific data /
CURLcode result; / return code for transfer /
} data;
};
When msg is CURLMSG_DONE, the message identifies a transfer that is done, and then result contains the return code for the easy handle that just completed.
typedef enum {
CURLE_OK = 0,
CURLE_UNSUPPORTED_PROTOCOL, / 1 /
CURLE_FAILED_INIT, / 2 /
CURLE_URL_MALFORMAT, / 3 /
CURLE_URL_MALFORMAT_USER, /4 - NOT USED /
CURLE_COULDNT_RESOLVE_PROXY, / 5 /
CURLE_COULDNT_RESOLVE_HOST, / 6 /
CURLE_COULDNT_CONNECT, / 7 /
CURLE_FTP_WEIRD_SERVER_REPLY, / 8 /
CURLE_FTP_ACCESS_DENIED, / 9 a service was denied by the FTP server
due to lack of access - when login fails
this is not returned. /
CURLE_FTP_USER_PASSWORD_INCORRECT, / 10 - NOT USED /
CURLE_FTP_WEIRD_PASS_REPLY, / 11 /
CURLE_FTP_WEIRD_USER_REPLY, / 12 /
CURLE_FTP_WEIRD_PASV_REPLY, / 13 /
CURLE_FTP_WEIRD_227_FORMAT, / 14 /
CURLE_FTP_CANT_GET_HOST, / 15 /
CURLE_FTP_CANT_RECONNECT, / 16 /
CURLE_FTP_COULDNT_SET_BINARY, / 17 /
CURLE_PARTIAL_FILE, / 18 /
CURLE_FTP_COULDNT_RETR_FILE, / 19 /
CURLE_FTP_WRITE_ERROR, / 20 /
CURLE_FTP_QUOTE_ERROR, / 21 /
CURLE_HTTP_RETURNED_ERROR, / 22 /
CURLE_WRITE_ERROR, / 23 /
CURLE_MALFORMAT_USER, / 24 - NOT USED /
CURLE_UPLOAD_FAILED, / 25 - failed upload "command" /
CURLE_READ_ERROR, / 26 - could open/read from file /
CURLE_OUT_OF_MEMORY, / 27 /
/ Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error
instead of a memory allocation error if CURL_DOES_CONVERSIONS
is defined /
CURLE_OPERATION_TIMEOUTED, / 28 - the timeout time was reached /
CURLE_FTP_COULDNT_SET_ASCII, / 29 - TYPE A failed /
CURLE_FTP_PORT_FAILED, / 30 - FTP PORT operation failed /
CURLE_FTP_COULDNT_USE_REST, / 31 - the REST command failed /
CURLE_FTP_COULDNT_GET_SIZE, / 32 - the SIZE command failed /
CURLE_HTTP_RANGE_ERROR, / 33 - RANGE "command" didn't work /
CURLE_HTTP_POST_ERROR, / 34 /
CURLE_SSL_CONNECT_ERROR, / 35 - wrong when connecting with SSL /
CURLE_BAD_DOWNLOAD_RESUME, / 36 - couldn't resume download /
CURLE_FILE_COULDNT_READ_FILE, / 37 /
CURLE_LDAP_CANNOT_BIND, / 38 /
CURLE_LDAP_SEARCH_FAILED, / 39 /
CURLE_LIBRARY_NOT_FOUND, / 40 /
CURLE_FUNCTION_NOT_FOUND, / 41 /
CURLE_ABORTED_BY_CALLBACK, / 42 /
CURLE_BAD_FUNCTION_ARGUMENT, / 43 /
CURLE_BAD_CALLING_ORDER, / 44 - NOT USED /
CURLE_INTERFACE_FAILED, / 45 - CURLOPT_INTERFACE failed /
CURLE_BAD_PASSWORD_ENTERED, / 46 - NOT USED /
CURLE_TOO_MANY_REDIRECTS , / 47 - catch endless re-direct loops /
CURLE_UNKNOWN_TELNET_OPTION, / 48 - User specified an unknown option /
CURLE_TELNET_OPTION_SYNTAX , / 49 - Malformed telnet option /
CURLE_OBSOLETE, / 50 - NOT USED /
CURLE_SSL_PEER_CERTIFICATE, / 51 - peer's certificate wasn't ok /
CURLE_GOT_NOTHING, / 52 - when this is a specific error /
CURLE_SSL_ENGINE_NOTFOUND, / 53 - SSL crypto engine not found /
CURLE_SSL_ENGINE_SETFAILED, / 54 - can not set SSL crypto engine as
default /
CURLE_SEND_ERROR, / 55 - failed sending network data /
CURLE_RECV_ERROR, / 56 - failure in receiving network data /
CURLE_SHARE_IN_USE, / 57 - share is in use /
CURLE_SSL_CERTPROBLEM, / 58 - problem with the local certificate /
CURLE_SSL_CIPHER, / 59 - couldn't use specified cipher /
CURLE_SSL_CACERT, / 60 - problem with the CA cert (path?) /
CURLE_BAD_CONTENT_ENCODING, / 61 - Unrecognized transfer encoding /
CURLE_LDAP_INVALID_URL, / 62 - Invalid LDAP URL /
CURLE_FILESIZE_EXCEEDED, / 63 - Maximum file size exceeded /
CURLE_FTP_SSL_FAILED, / 64 - Requested FTP SSL level failed /
CURLE_SEND_FAIL_REWIND, / 65 - Sending the data requires a rewind
that failed /
CURLE_SSL_ENGINE_INITFAILED, / 66 - failed to initialise ENGINE /
CURLE_LOGIN_DENIED, / 67 - user, password or similar was not
accepted and we failed to login /
CURLE_TFTP_NOTFOUND, / 68 - file not found on server /
CURLE_TFTP_PERM, / 69 - permission problem on server /
CURLE_TFTP_DISKFULL, / 70 - out of disk space on server /
CURLE_TFTP_ILLEGAL, / 71 - Illegal TFTP operation /
CURLE_TFTP_UNKNOWNID, / 72 - Unknown transfer ID /
CURLE_TFTP_EXISTS, / 73 - File already exists /
CURLE_TFTP_NOSUCHUSER, / 74 - No such user /
CURLE_CONV_FAILED, / 75 - conversion failed /
CURLE_CONV_REQD, / 76 - caller must register conversion
callbacks using curl_easy_setopt options
CURLOPT_CONV_FROM_NETWORK_FUNCTION,
CURLOPT_CONV_TO_NETWORK_FUNCTION, and
CURLOPT_CONV_FROM_UTF8_FUNCTION /
CURLE_SSL_CACERT_BADFILE, / 77 - could not load CACERT file, missing
or wrong format /
CURLE_REMOTE_FILE_NOT_FOUND, / 78 - remote file not found /
CURLE_SSH, / 79 - error from the SSH layer, somewhat
generic so the error message will be of
interest when this has happened /
CURLE_SSL_SHUTDOWN_FAILED, / 80 - Failed to shut down the SSL
connection /
CURL_LAST / never use! /
} CURLcode;
***************************************************************************************************/
#include <gtk/gtk.h>
#include <glade/glade.h>
#include <stdio.h>
#include <string.h>
#include <libgen.h>
#include <libgtkhtml/gtkhtml.h>
#include "glibcurl.h"
static gchar* g_file_name = NULL;
static GtkWidget* g_combox = NULL;
static GtkWidget* g_win = NULL;
static gboolean g_is_refr = TRUE;
static gboolean g_is_trans = FALSE;//是否正在传输
static HtmlDocument* g_document = NULL;
static GtkWidget* g_view = NULL;
static void curlCallback( void* data)
{
CURLMsg* msg;
int inQueue;
while (1) {
msg = curl_multi_info_read( glibcurl_handle(), &inQueue);
if (msg == 0) {
break;
}
if (msg->msg != CURLMSG_DONE)
continue;
else {
//在这里先free url,再删除curl handler
HtmlStream* stream = NULL;
curl_easy_getinfo( msg->easy_handle, CURLINFO_PRIVATE, (char**)&stream);
char * eurl = NULL;
curl_easy_getinfo( msg->easy_handle, CURLINFO_EFFECTIVE_URL, &eurl);
g_print("Connection %s closed, result code %d\n", eurl, msg->data.result);
if( g_file_name) {
//add text to popup menu
if( eurl)
g_free( eurl);
if( stream)
html_stream_close( stream);
}
g_is_trans = FALSE;
glibcurl_remove( msg->easy_handle);
}
}
}
static size_t curlWriter( void* ptr, size_t size, size_t nmemb, void *stream)
{
if (ptr == 0) return 0; /* NOP, just to avoid "unused param" warning */
g_print("Bytes length %d\n", size*nmemb);
//write the contents to htmlview widget
if( stream)
html_stream_write(stream, ptr, size*nmemb);
else
html_document_write_stream( g_document, ptr, size*nmemb);
return size * nmemb;
}
/**
param@ is_added 是否在combbox的下拉菜单中增加一个菜单项
param@ stream 对应的一个htmlstream
*/
static void read_url( const char* url, gboolean is_added, HtmlStream* stream)
{
CURL* hcurl;
if( url && strlen( url) > 0) {
if( is_added == TRUE)
gtk_combo_box_append_text( GTK_COMBO_BOX(g_combox), g_file_name);
char* dupurl = strdup(url);
hcurl = curl_easy_init();
curl_easy_setopt(hcurl, CURLOPT_URL, dupurl);
curl_easy_setopt(hcurl, CURLOPT_VERBOSE, 1);
curl_easy_setopt(hcurl, CURLOPT_BUFFERSIZE, 1024*32);
curl_easy_setopt(hcurl, CURLOPT_WRITEFUNCTION, curlWriter);
curl_easy_setopt(hcurl, CURLOPT_WRITEDATA, stream);
curl_easy_setopt(hcurl, CURLOPT_PRIVATE, stream);
g_is_trans = TRUE;
glibcurl_add( hcurl);
}
}
static void locale_file_name( const char* utf8_file, char* ret_file)
{
int wbytes = 0;
gchar* strtmp = g_locale_from_utf8( utf8_file, -1, NULL, &wbytes, NULL);
if( !strstr( utf8_file, "://")) {
snprintf( ret_file, PATH_MAX, "file://%s", strtmp?strtmp:utf8_file);
} else {
snprintf( ret_file, PATH_MAX, "%s", strtmp?strtmp:utf8_file);
}
if( strtmp) g_free( strtmp);
}
static void on_comb_editing_done( GtkWidget *widget, gpointer user_data)
{
g_print("Something added\n");
if( g_file_name) g_free(g_file_name),g_file_name=NULL;
if( g_is_trans == FALSE){
g_file_name = gtk_combo_box_get_active_text( GTK_COMBO_BOX(g_combox));
char furl[PATH_MAX] = {0};
if( strlen( g_file_name) > 0) {
html_view_set_document(HTML_VIEW(g_view), NULL);
html_document_clear( g_document);
html_view_set_document(HTML_VIEW(g_view), g_document);
html_document_open_stream( g_document, "text/html");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -