1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /* This file is part of the GtkHTML library
3  *
4  * Copyright (C) 1997 Martin Jones (mjones@kde.org)
5  * Copyright (C) 1997 Torben Weis (weis@kde.org)
6  * Copyright (C) 1999, 2000 Helix Code, Inc.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public License
19  * along with this library; see the file COPYING.LIB.  If not, write to
20  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22 */
23 
24 #ifndef _HTMLENGINE_H_
25 #define _HTMLENGINE_H_
26 
27 #include <gtk/gtk.h>
28 #include "gtkhtml-types.h"
29 
30 #include "htmltypes.h"
31 #include "htmlenums.h"
32 #include "htmlcursor.h"
33 
34 
35 #define HTML_TYPE_ENGINE                 (html_engine_get_type ())
36 #define HTML_ENGINE(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), HTML_TYPE_ENGINE, HTMLEngine))
37 #define HTML_ENGINE_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), HTML_TYPE_ENGINE, HTMLEngineClass))
38 #define HTML_IS_ENGINE(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), HTML_TYPE_ENGINE))
39 #define HTML_IS_ENGINE_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), HTML_TYPE_ENGINE))
40 
41 
42 /* FIXME extreme hideous ugliness in the following lines.  */
43 
44 #define LEFT_BORDER 10
45 #define RIGHT_BORDER 10
46 #define TOP_BORDER 10
47 #define BOTTOM_BORDER 10
48 
49 /* FIXME this needs splitting.  */
50 
51 struct _HTMLEngine {
52 	GObject parent;
53 	HTMLDrawQueue *draw_queue;
54 
55 	HTMLPainter *painter;
56 
57 	HTMLSettings *settings;
58 	HTMLSettings *defaultSettings;
59 
60 	HTMLUndo *undo;
61 
62 	GdkWindow *window;
63 
64 	gboolean editable;
65 	gboolean caret_mode;
66 
67 	HTMLObject *clipboard;
68 	guint       clipboard_len;
69 	GList      *clipboard_stack;
70 
71 	HTMLObject *primary;
72 	guint       primary_len;
73 
74 	/* Freeze counter.  When greater than zero, we never trigger relayouts
75 	 * nor repaints.  When going from nonzero to zero, we relayout and
76 	 * repaint everything.  */
77 	guint freeze_count;
78 	guint thaw_idle_id;
79 	gint block_redraw;
80 	gboolean need_redraw;
81 	GSList *pending_expose;
82 
83 	gboolean parsing;
84 	HTMLTokenizer *ht;
85 	HTMLStringTokenizer *st;
86 	HTMLObject *clue;         /* the document root */
87 
88 	HTMLObject *flow;
89 
90 	gint leftBorder;
91 	gint rightBorder;
92 	gint topBorder;
93 	gint bottomBorder;
94 
95 	/* Current indentation level.  */
96 	guint indent_level;
97 
98 	/* For the widget */
99 	gint width;
100 	gint height;
101 
102 	/* Number of tokens parsed in the current time-slice */
103 	gint parseCount;
104 	gint granularity;
105 
106 	/* Offsets */
107 	gint x_offset, y_offset;
108 
109 	gboolean inTitle;
110 	gboolean inPre;
111 	gboolean inOption;
112 	gboolean inTextArea;
113 	gboolean eat_space;
114 	gboolean allow_frameset;
115 	gboolean newPage;
116 	gboolean begin;
117 
118 	HTMLStack *span_stack;
119 	HTMLStack *clueflow_style_stack; /* Clueflow style stack, elements are HTMLClueFlowStyles.  */
120 	HTMLStack *frame_stack;
121 	HTMLStack *body_stack;
122 	HTMLStack *table_stack;
123 
124 	gchar *url;
125 	gchar *target;
126 
127 	/* timer id to schedule paint events */
128 	guint updateTimer;
129 
130 	/* timer id for parsing routine */
131 	guint timerId;
132 
133 	guint redraw_idle_id;
134 
135 	/* FIXME: replace with a `gchar *'?  */
136 	GString *title;
137 
138 	gboolean writing;
139 
140 	/* The background pixmap, an HTMLImagePointer */
141         gpointer bgPixmapPtr;
142 
143 	/* Stack of lists currently active */
144 	HTMLStack *listStack;
145 
146 	/* Stack of embedded "object"'s */
147 	HTMLStack *embeddedStack;
148 
149 	/* The associated widget.  */
150 	GtkHTML *widget;
151 
152         gpointer image_factory;
153 
154 	/*
155 	 * This list holds strings which are displayed in the view,
156 	 * but are not actually contained in the HTML source.
157 	 * e.g. The numbers in an ordered list.
158 	 * FIXME?
159 	 */
160 	GList *tempStrings;
161 
162 	HTMLMap *map;
163 	HTMLForm *form;
164 	HTMLSelect *formSelect;
165 	HTMLTextArea *formTextArea;
166 	GList *formList;
167 	GString *formText;
168 
169 	/* This is TRUE if we cannot insert a paragraph break (which is just an
170 	 * extra empty line).  It's set to FALSE as soon as some element is
171 	 * added to a flow.  The purpose is to avoid having paragraph breaks to
172 	 * be inserted in sequence, or after elements that have some vspace of
173 	 * their own.  */
174 	gboolean avoid_para;
175 
176 	/* Whether we have the keyboard focus.  */
177 	guint have_focus : 1;
178 
179 	HTMLInterval *selection;
180 	gboolean selected_in;
181 
182 	/* --- */
183 
184 	/* Editing stuff.  -- FIXME it should be in a separate object.  */
185 
186 	/* The current position of the cursor.  */
187 	HTMLCursor *cursor;
188 
189 	/* If no region is active, this is NULL.  Otherwise, this is
190 	 * one extreme of the selected region.  The other extreme is
191 	 * always the cursor.  */
192 	HTMLCursor *mark;
193 
194 	/* Hide counter for the cursor.  When greater than zero, it
195 	 * means the cursor is invisible.  */
196 	gint cursor_hide_count;
197 
198 	/* Timer ID for cursor blink.  */
199 	gint blinking_timer_id;
200 
201 	/* Blinking status (visible/invisible).  */
202 	gboolean blinking_status;
203 
204 	/* Font style for insertion.  If HTML_FONT_STYLE_DEFAULT, use that of
205 	 * the text we are in.  */
206 	GtkHTMLFontStyle  insertion_font_style;
207 	HTMLColor        *insertion_color;
208 	gchar            *insertion_url;
209 	gchar            *insertion_target;
210 
211 	/* if we are doing shift selection - Shift + some event (arrows, mouse motion, ...) */
212 	gboolean shift_selection;
213 
214 	/* This object is used to update the keyboard selection in the
215 	 * idle loop.  */
216 	HTMLEngineEditSelectionUpdater *selection_updater;
217 
218 	/* keeps selection between operation, which are changing selection
219 	 * and need restore it after done */
220 	GList *selection_stack;
221 
222 	/* search & replace */
223 	HTMLSearch  *search_info;
224 	HTMLReplace *replace_info;
225 
226 	/* id-to-object mapping */
227 	GHashTable *id_table;
228 
229 	/* table contains data, which are set to objects by type during parse time */
230 	GHashTable *class_data;
231 
232 	/* table of maps */
233 	GHashTable *map_table;
234 
235 	gdouble min_split_index;
236 
237 	gboolean need_spell_check;
238 	gint block_events;
239 	gchar *language;
240 
241 	GSList *cursor_position_stack;
242 	gboolean selection_mode;
243 	gint block_selection;
244 
245 	HTMLCursorRectangle cursor_cell;
246 	HTMLCursorRectangle cursor_table;
247 	HTMLCursorRectangle cursor_image;
248 
249 	GList *cut_and_paste_stack;
250 
251 	gboolean block;
252 	gboolean block_images;
253 	gint opened_streams;
254 	gboolean stopped;
255 	gboolean keep_scroll;
256 
257 	HTMLObject *focus_object;
258 	gint focus_object_offset;
259 
260 	gboolean save_data;
261 	gint saved_step_count;
262 
263 	gboolean expose;
264 	gboolean need_update;
265 
266 	HTMLObject *parser_clue;  /* the root of the currently parsed block */
267 };
268 
269 /* must be forward referenced *sigh* */
270 struct _HTMLEmbedded;
271 
272 struct _HTMLEngineClass {
273 	GObjectClass parent_class;
274 
275 	void (* title_changed) (HTMLEngine *engine);
276 	void (* set_base) (HTMLEngine *engine, const gchar *base);
277 	void (* set_base_target) (HTMLEngine *engine, const gchar *base_target);
278 	void (* load_done) (HTMLEngine *engine);
279         void (* url_requested) (HTMLEngine *engine, const gchar *url, GtkHTMLStream *handle);
280 	void (* draw_pending) (HTMLEngine *engine);
281         void (* redirect) (HTMLEngine *engine, const gchar *url, gint delay);
282         void (* submit) (HTMLEngine *engine, const gchar *method, const gchar *action, const gchar *encoding);
283 	gboolean (* object_requested) (HTMLEngine *engine, GtkHTMLEmbedded *);
284 	void (* undo_changed) (HTMLEngine *engine);
285 };
286 
287 
288 /* Object construction.  */
289 GType       html_engine_get_type      (void);
290 HTMLEngine *html_engine_new           (GtkWidget *);
291 void        html_engine_realize       (HTMLEngine *engine,
292 				       GdkWindow  *window);
293 void        html_engine_unrealize     (HTMLEngine *engine);
294 
295 void      html_engine_saved     (HTMLEngine *e);
296 gboolean  html_engine_is_saved  (HTMLEngine *e);
297 
298 /* Editability control.  */
299 void      html_engine_set_editable  (HTMLEngine *e,
300 				     gboolean    editable);
301 gboolean  html_engine_get_editable  (HTMLEngine *e);
302 
303 /* Focus.  */
304 void  html_engine_set_focus  (HTMLEngine *engine,
305 			      gboolean    have_focus);
306 
307 /* Tokenizer. */
308 void html_engine_set_tokenizer (HTMLEngine *engine,
309 				HTMLTokenizer *tok);
310 
311 /* Parsing control.  */
312 GtkHTMLStream *html_engine_begin            (HTMLEngine  *p,
313 					     const gchar  *content_type);
314 void           html_engine_parse            (HTMLEngine  *p);
315 void           html_engine_stop_parser      (HTMLEngine  *e);
316 void           html_engine_stop             (HTMLEngine  *e);
317 void           html_engine_flush            (HTMLEngine  *e);
318 void           html_engine_set_engine_type   (HTMLEngine *e,
319 					 gboolean engine_type);
320 gboolean       html_engine_get_engine_type   (HTMLEngine *e);
321 void		   html_engine_set_content_type (HTMLEngine *e,
322 					const gchar * content_type);
323 const gchar *  html_engine_get_content_type (HTMLEngine *e);
324 
325 /* Rendering control.  */
326 gint  html_engine_calc_min_width       (HTMLEngine *e);
327 gboolean  html_engine_calc_size        (HTMLEngine *e,
328 					GList     **changed_objs);
329 gint  html_engine_get_doc_height       (HTMLEngine *p);
330 gint  html_engine_get_doc_width        (HTMLEngine *e);
331 gint  html_engine_get_max_width        (HTMLEngine *e);
332 gint  html_engine_get_max_height       (HTMLEngine *e);
333 void  html_engine_draw                 (HTMLEngine *e,
334 					gint        x,
335 					gint        y,
336 					gint        width,
337 					gint        height);
338 void  html_engine_draw_cb              (HTMLEngine *e,
339 					cairo_t    *cr);
340 void  html_engine_draw_background      (HTMLEngine *e,
341 					gint        x,
342 					gint        y,
343 					gint        width,
344 					gint        height);
345 
346 /* Scrolling.  */
347 void      html_engine_schedule_update      (HTMLEngine  *e);
348 void      html_engine_schedule_redraw      (HTMLEngine  *e);
349 void      html_engine_block_redraw         (HTMLEngine  *e);
350 void      html_engine_unblock_redraw       (HTMLEngine  *e);
351 gboolean  html_engine_make_cursor_visible  (HTMLEngine  *e);
352 gboolean  html_engine_goto_anchor          (HTMLEngine  *e,
353 					    const gchar *anchor);
354 
355 /* Draw/clear queue.  */
356 void  html_engine_flush_draw_queue  (HTMLEngine *e);
357 void  html_engine_queue_draw        (HTMLEngine *e,
358 				     HTMLObject *o);
359 void  html_engine_queue_clear       (HTMLEngine *e,
360 				     gint        x,
361 				     gint        y,
362 				     guint       width,
363 				     guint       height);
364 
365 void  html_engine_set_painter       (HTMLEngine  *e,
366 				     HTMLPainter *painter);
367 
368 /* Getting objects through pointer positions.  */
369 HTMLObject  *html_engine_get_object_at  (HTMLEngine *e,
370 					 gint        x,
371 					 gint        y,
372 					 guint      *offset_return,
373 					 gboolean    for_cursor);
374 HTMLPoint   *html_engine_get_point_at   (HTMLEngine *e,
375 					 gint        x,
376 					 gint        y,
377 					 gboolean    for_cursor);
378 const gchar *html_engine_get_link_at    (HTMLEngine *e,
379 					 gint        x,
380 					 gint        y);
381 
382 /* Form support.  */
383 void  html_engine_form_submitted  (HTMLEngine  *engine,
384 				   const gchar *method,
385 				   const gchar *action,
386 				   const gchar *encoding);
387 
388 /* Misc.  (FIXME: Should die?) */
389 gchar *html_engine_canonicalize_url  (HTMLEngine *e,
390 				      const gchar *in_url);
391 
392 /* Cursor */
393 HTMLCursor *html_engine_get_cursor        (HTMLEngine *e);
394 void        html_engine_normalize_cursor  (HTMLEngine *e);
395 
396 /* Freezing/thawing.  */
397 gboolean  html_engine_frozen  (HTMLEngine *engine);
398 void      html_engine_freeze  (HTMLEngine *engine);
399 void      html_engine_thaw    (HTMLEngine *engine);
400 
401 /* Creating an empty document.  */
402 void      html_engine_load_empty                (HTMLEngine *engine);
403 
404 /* Search & Replace */
405 
406 void      html_engine_replace                   (HTMLEngine *e,
407 						 const gchar *text,
408 						 const gchar *rep_text,
409 						 gboolean case_sensitive,
410 						 gboolean forward,
411 						 gboolean regular,
412 						 void (*ask)(HTMLEngine *, gpointer), gpointer ask_data);
413 gboolean  html_engine_replace_do                (HTMLEngine *e, HTMLReplaceQueryAnswer answer);
414 gint      html_engine_replaced                  (void);
415 
416 /* Magic links */
417 void      html_engine_init_magic_links          (void);
418 
419 /* spell checking */
420 void      html_engine_spell_check              (HTMLEngine  *e);
421 void      html_engine_clear_spell_check        (HTMLEngine  *e);
422 gchar    *html_engine_get_spell_word           (HTMLEngine  *e);
423 gboolean  html_engine_spell_word_is_valid      (HTMLEngine  *e);
424 void      html_engine_replace_spell_word_with  (HTMLEngine  *e,
425 						const gchar *word);
426 void      html_engine_set_language             (HTMLEngine  *e,
427 						const gchar *language);
428 const gchar *html_engine_get_language          (HTMLEngine *e);
429 
430 /* view size - for image size specified in percent */
431 gint  html_engine_get_view_width   (HTMLEngine *e);
432 gint  html_engine_get_view_height  (HTMLEngine *e);
433 
434 /* id support */
435 void        html_engine_add_object_with_id  (HTMLEngine  *e,
436 					     const gchar *id,
437 					     HTMLObject  *obj);
438 HTMLObject *html_engine_get_object_by_id    (HTMLEngine  *e,
439 					     const gchar *id);
440 
441 HTMLEngine *html_engine_get_top_html_engine (HTMLEngine *e);
442 void        html_engine_thaw_idle_flush     (HTMLEngine *e);
443 
444 /* class data */
445 const gchar *html_engine_get_class_data        (HTMLEngine  *e,
446 						const gchar *class_name,
447 						const gchar *key);
448 GHashTable  *html_engine_get_class_table       (HTMLEngine  *e,
449 						const gchar *class_name);
450 void         html_engine_set_class_data        (HTMLEngine  *e,
451 						const gchar *class_name,
452 						const gchar *key,
453 						const gchar *value);
454 void         html_engine_clear_class_data      (HTMLEngine  *e,
455 						const gchar *class_name,
456 						const gchar *key);
457 void         html_engine_clear_all_class_data  (HTMLEngine  *e);
458 gboolean  html_engine_intersection  (HTMLEngine *e,
459 				     gint       *x1,
460 				     gint       *y1,
461 				     gint       *x2,
462 				     gint       *y2);
463 void  html_engine_add_expose  (HTMLEngine *e,
464 			       gint        x,
465 			       gint        y,
466 			       gint        width,
467 			       gint        height,
468 			       gboolean    expose);
469 void html_engine_redraw_selection (HTMLEngine *e);
470 
471 gboolean    html_engine_focus              (HTMLEngine       *e,
472 					    GtkDirectionType  dir);
473 HTMLObject *html_engine_get_focus_object   (HTMLEngine       *e,
474 					    gint             *offset);
475 void        html_engine_set_focus_object   (HTMLEngine       *e,
476 					    HTMLObject       *o,
477 					    gint              offset);
478 void        html_engine_update_focus_if_necessary (HTMLEngine	*e,
479 						   HTMLObject	*o,
480 						   gint		offset);
481 
482 HTMLMap *html_engine_get_map  (HTMLEngine  *e,
483 			       const gchar *name);
484 
485 gboolean html_engine_selection_contains_object_type (HTMLEngine *e,
486 						     HTMLType obj_type);
487 gboolean html_engine_selection_contains_link        (HTMLEngine *e);
488 
489 gint  html_engine_get_left_border    (HTMLEngine *e);
490 gint  html_engine_get_right_border   (HTMLEngine *e);
491 gint  html_engine_get_top_border     (HTMLEngine *e);
492 gint  html_engine_get_bottom_border  (HTMLEngine *e);
493 
494 HTMLImageFactory *html_engine_get_image_factory (HTMLEngine *e);
495 void html_engine_opened_streams_increment (HTMLEngine *e);
496 void html_engine_opened_streams_decrement (HTMLEngine *e);
497 void html_engine_opened_streams_set (HTMLEngine *e, gint value);
498 
499 void html_engine_refresh_fonts (HTMLEngine *e);
500 
501 void html_engine_emit_undo_changed (HTMLEngine *e);
502 
503 #endif /* _HTMLENGINE_H_ */
504