1 /**
2  * vimb - a webkit based vim like browser.
3  *
4  * Copyright (C) 2012-2018 Daniel Carl
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see http://www.gnu.org/licenses/.
18  */
19 
20 #ifndef _MAIN_H
21 #define _MAIN_H
22 
23 #include <fcntl.h>
24 #include <gtk/gtkx.h>
25 #include <stdio.h>
26 #include <webkit2/webkit2.h>
27 #include "shortcut.h"
28 #include "handler.h"
29 #include "file-storage.h"
30 
31 #include "config.h"
32 
33 #define LENGTH(x) (sizeof x / sizeof x[0])
34 #define OVERWRITE_STRING(t, s) {if (t) g_free(t); t = g_strdup(s);}
35 #define OVERWRITE_NSTRING(t, s, l) {if (t) {g_free(t); t = NULL;} t = g_strndup(s, l);}
36 #define GET_CHAR(c, n)  (((Setting*)g_hash_table_lookup(c->config.settings, n))->value.s)
37 #define GET_INT(c, n)   (((Setting*)g_hash_table_lookup(c->config.settings, n))->value.i)
38 #define GET_BOOL(c, n)  (((Setting*)g_hash_table_lookup(c->config.settings, n))->value.b)
39 
40 
41 #ifdef DEBUG
42 #define PRINT_DEBUG(...) { \
43     fprintf(stderr, "\n\033[31;1mDEBUG: \033[32;1m%s +%d %s()\033[0m\t", __FILE__, __LINE__, __func__); \
44     fprintf(stderr, __VA_ARGS__);\
45 }
46 #define TIMER_START GTimer *__timer; {__timer = g_timer_new(); g_timer_start(__timer);}
47 #define TIMER_END {gdouble __debug_elapsed = g_timer_elapsed(__timer, NULL);\
48     PRINT_DEBUG("\033[33mtimer:\033[0m %fs", __debug_elapsed);\
49     g_timer_destroy(__timer); \
50 }
51 #else
52 #define PRINT_DEBUG(message, ...)
53 #define TIMER_START
54 #define TIMER_END
55 #endif
56 
57 /* the special mark ' must be the first in the list for easiest lookup */
58 #define MARK_CHARS   "'abcdefghijklmnopqrstuvwxyz"
59 #define MARK_TICK    0
60 #define MARK_SIZE    (sizeof(MARK_CHARS) - 1)
61 
62 #define USER_REG     "abcdefghijklmnopqrstuvwxyz"
63 /* registers in order displayed for :register command */
64 #define REG_CHARS    "\"" USER_REG ":%/;"
65 #define REG_SIZE     (sizeof(REG_CHARS) - 1)
66 
67 #define FILE_CLOSED  "closed"
68 #define FILE_COOKIES "cookies"
69 
70 enum { TARGET_CURRENT, TARGET_RELATED, TARGET_NEW };
71 
72 typedef enum {
73     RESULT_COMPLETE, RESULT_MORE, RESULT_ERROR
74 } VbResult;
75 
76 typedef enum {
77     CMD_ERROR,               /* command could not be parses or executed */
78     CMD_SUCCESS   = 0x01,    /* command runned successfully */
79     CMD_KEEPINPUT = 0x02,    /* don't clear inputbox after command run */
80 } VbCmdResult;
81 
82 typedef enum {
83     TYPE_BOOLEAN, TYPE_INTEGER, TYPE_CHAR, TYPE_COLOR, TYPE_FONT
84 } DataType;
85 
86 typedef enum {
87     MSG_NORMAL, MSG_ERROR
88 } MessageType;
89 
90 typedef enum {
91     STATUS_NORMAL, STATUS_SSL_VALID, STATUS_SSL_INVALID
92 } StatusType;
93 
94 typedef enum {
95     INPUT_UNKNOWN,
96     INPUT_SET              = 0x01,
97     INPUT_OPEN             = 0x02,
98     INPUT_TABOPEN          = 0x04,
99     INPUT_COMMAND          = 0x08,
100     INPUT_SEARCH_FORWARD   = 0x10,
101     INPUT_SEARCH_BACKWARD  = 0x20,
102     INPUT_BOOKMARK_ADD     = 0x40,
103     INPUT_ALL              = 0xff, /* map to match all input types */
104 } VbInputType;
105 
106 enum {
107     FILES_BOOKMARK,
108     FILES_CLOSED,
109     FILES_CONFIG,
110     FILES_COOKIE,
111     FILES_QUEUE,
112     FILES_SCRIPT,
113     FILES_USER_STYLE,
114     FILES_LAST
115 };
116 
117 enum {
118     STORAGE_CLOSED,
119     STORAGE_COMMAND,
120     STORAGE_CONFIG,
121     STORAGE_HISTORY,
122     STORAGE_SEARCH,
123     STORAGE_LAST
124 };
125 
126 typedef enum {
127     LINK_TYPE_NONE,
128     LINK_TYPE_LINK,
129     LINK_TYPE_IMAGE,
130 } VbLinkType;
131 
132 typedef struct Client Client;
133 typedef struct State State;
134 typedef struct Map Map;
135 typedef struct Mode Mode;
136 typedef struct Arg Arg;
137 typedef void (*ModeTransitionFunc)(Client*);
138 typedef VbResult (*ModeKeyFunc)(Client*, int);
139 typedef void (*ModeInputChangedFunc)(Client*, const char*);
140 
141 struct Arg {
142     int  i;
143     char *s;
144 };
145 
146 typedef int (*SettingFunction)(Client *c, const char *name, DataType type, void *value, void *data);
147 typedef union {
148     gboolean b;
149     int      i;
150     char     *s;
151 } SettingValue;
152 
153 typedef struct {
154     const char      *name;
155     int             type;
156     SettingValue    value;
157     SettingFunction setter;
158     int             flags;
159     void            *data;  /* data given to the setter */
160 } Setting;
161 
162 struct State {
163     char                *uri;
164     gboolean            typed;              /* indicates if the user typed the keys */
165     gboolean            processed_key;      /* indicates if a key press was handled and should not bubbled up */
166     gboolean            ctrlv;              /* indicates if the CTRL-V temorary submode is on */
167 
168 #define PROMPT_SIZE 4
169     char                prompt[PROMPT_SIZE];/* current prompt ':', 'g;t', '/' including nul */
170     glong               marks[MARK_SIZE];   /* holds marks set to page with 'm{markchar}' */
171     guint               input_timer;
172     MessageType         input_type;
173     StatusType          status_type;
174     glong               scroll_max;         /* Maxmimum scrollable height of the document. */
175     guint               scroll_percent;     /* Current position of the viewport in document (percent). */
176     glong               scroll_top;         /* Current position of the viewport in document (pixel). */
177     char                *title;             /* Window title of the client. */
178 
179     char                *reg[REG_SIZE];     /* holds the yank buffers */
180     /* TODO rename to reg_{enabled,current} */
181     gboolean            enable_register;    /* indicates if registers are filled */
182     char                current_register;   /* holds char for current register to be used */
183 
184     GList               *downloads;
185     guint               progress;
186     WebKitHitTestResult *hit_test_result;
187     gboolean            is_fullscreen;
188 
189     struct {
190         gboolean    active;         /* indicate if there is a active search */
191         short       direction;      /* last direction 1 forward, -1 backward */
192         int         matches;        /* number of matching search results */
193         char        *last_query;    /* last search query */
194     } search;
195 };
196 
197 struct Map {
198     char        *in;                /* input keys */
199     int         inlen;              /* length of the input keys */
200     char        *mapped;            /* mapped keys */
201     int         mappedlen;          /* length of the mapped keys string */
202     char        mode;               /* mode for which the map is available */
203     gboolean    remap;              /* if FALSE do not remap the {rhs} of this map */
204 };
205 
206 struct Mode {
207     char                 id;
208     ModeTransitionFunc   enter;         /* is called if the mode is entered */
209     ModeTransitionFunc   leave;         /* is called if the mode is left */
210     ModeKeyFunc          keypress;      /* receives key to process */
211     ModeInputChangedFunc input_changed; /* is triggered if input textbuffer is changed */
212 #define FLAG_NOMAP          0x0001  /* disables mapping for key strokes */
213 #define FLAG_HINTING        0x0002  /* marks active hinting submode */
214 #define FLAG_COMPLETION     0x0004  /* marks active completion submode */
215 #define FLAG_PASSTHROUGH    0x0008  /* don't handle any other keybind than <esc> */
216 #define FLAG_NEW_WIN        0x0010  /* enforce opening of pages into new window */
217 #define FLAG_IGNORE_FOCUS   0x0012  /* do not listen for focus change messages */
218     unsigned int         flags;
219 };
220 
221 struct Statusbar {
222     GtkBox    *box;
223     GtkWidget *mode, *left, *right, *cmd;
224 };
225 
226 struct AuGroup;
227 
228 struct Client {
229     struct Client       *next;
230     struct State        state;
231     struct Statusbar    statusbar;
232     void                *comp;                  /* pointer to data used in completion.c */
233     Mode                *mode;                  /* current active browser mode */
234     /* WebKitWebContext    *webctx; */          /* not used atm, use webkit_web_context_get_default() instead */
235     GtkWidget           *window, *input;
236     WebKitWebView       *webview;
237     WebKitFindController *finder;
238     WebKitWebInspector  *inspector;
239     guint64             page_id;                /* page id of the webview */
240     GtkTextBuffer       *buffer;
241     GDBusProxy          *dbusproxy;
242     GDBusServer         *dbusserver;
243     Handler             *handler;               /* the protocoll handlers */
244     struct {
245         /* TODO split in global setting definitions and set values on a per
246          * client base. */
247         GHashTable              *settings;
248         guint                   scrollstep;
249         gboolean                input_autohide;
250         gboolean                incsearch;
251         gboolean                prevent_newwindow;
252         guint                   default_zoom;   /* default zoom level in percent */
253         Shortcut                *shortcuts;
254     } config;
255     struct {
256         GSList      *list;
257         GString     *queue;                     /* queue holding typed keys */
258         int         qlen;                       /* pointer to last char in queue */
259         int         resolved;                   /* number of resolved keys (no mapping required) */
260         guint       timout_id;                  /* source id of the timeout function */
261         char        showcmd[SHOWCMD_LEN + 1];   /* buffer to show ambiguous key sequence */
262         guint       timeoutlen;                 /* timeout for ambiguous mappings */
263     } map;
264     struct {
265         struct AuGroup *curgroup;
266         GSList         *groups;
267         guint          usedbits;                /* holds all used event bits */
268     } autocmd;
269 };
270 
271 struct Vimb {
272     char        *argv0;
273     Client      *clients;
274     Window      embed;
275     GHashTable  *modes;             /* all available browser main modes */
276     char        *configfile;        /* config file given as option on startup */
277     char        *files[FILES_LAST];
278     FileStorage *storage[STORAGE_LAST];
279     char        *profile;           /* profile name */
280     GSList      *cmdargs;           /* ex commands given asl --command, -C option */
281     struct {
282         guint   history_max;
283         guint   closed_max;
284     } config;
285     GtkCssProvider *style_provider;
286     gboolean    no_maximize;
287     gboolean    incognito;
288 };
289 
290 gboolean vb_download_set_destination(Client *c, WebKitDownload *download,
291     char *suggested_filename, const char *path);
292 void vb_echo(Client *c, MessageType type, gboolean hide, const char *error, ...);
293 void vb_echo_force(Client *c, MessageType type, gboolean hide, const char *error, ...);
294 void vb_enter(Client *c, char id);
295 void vb_enter_prompt(Client *c, char id, const char *prompt, gboolean print_prompt);
296 Client *vb_get_client_for_page_id(guint64 pageid);
297 char *vb_input_get_text(Client *c);
298 void vb_input_set_text(Client *c, const char *text);
299 void vb_input_update_style(Client *c);
300 gboolean vb_load_uri(Client *c, const Arg *arg);
301 void vb_mode_add(char id, ModeTransitionFunc enter, ModeTransitionFunc leave,
302     ModeKeyFunc keypress, ModeInputChangedFunc input_changed);
303 VbResult vb_mode_handle_key(Client *c, int key);
304 void vb_modelabel_update(Client *c, const char *label);
305 gboolean vb_quit(Client *c, gboolean force);
306 void vb_register_add(Client *c, char buf, const char *value);
307 const char *vb_register_get(Client *c, char buf);
308 void vb_statusbar_update(Client *c);
309 void vb_statusbar_show_hover_url(Client *c, VbLinkType type, const char *uri);
310 void vb_gui_style_update(Client *c, const char *name, const char *value);
311 
312 #endif /* end of include guard: _MAIN_H */
313