Codebase list dillo / upstream/3.0.3
Imported Upstream version 3.0.3 Axel Beckert 11 years ago
207 changed file(s) with 10492 addition(s) and 4937 deletion(s). Raw diff Collapse all Expand all
8585 public domain.
8686 * src/md5.[ch] contain code by L. Peter Deutsch whose copyright is held by
8787 Aladdin Enterprises.
88 * src/tipwin.cc contains code by Greg Ercolano.
55 user. For a history of changes in full detail, see our Mercurial repository
66 at http://hg.dillo.org/dillo
77
8
9 dillo-3.0.3 [April 17, 2013]
10
11 +- Support for CSS display property
12 - Replace polling in DNS with a pipe.
13 - Packed trie to optimize hyphenator memory consumption.
14 - Fix crash in datauri dpi.
15 - Speed up DNS requests when ipv6 isn't enabled.
16 Patches: Johannes Hofmann
17 +- Fix image input coordinates (BUG#1070)
18 - When location bar is given focus, temporarily show panels if hidden
19 (BUG#1093).
20 - Fix bug where data URI has charset but no media type.
21 - Bug meter line number fix for bare carriage returns.
22 - Add some more info to various bug meter messages.
23 - For text selection, fix releasing mouse button outside of boundary.
24 - While selecting text, moving cursor outside viewport will scroll it.
25 - Make form resetting work for <select>.
26 - Never leave location bar empty when requesting page (BUG#1113).
27 - Some improvements to tab navigation of form widgets (includes BUG#1111).
28 - Don't let form input widget insert literal control chars (BUG#1110).
29 - Assorted improvements to browser usability from the keyboard.
30 - Added user interface color preferences (ui_*).
31 - Removed show_url preference.
32 Patches: corvid
33 +- Automatic hyphenation (includes penalty_* preferences that control
34 line-breaking).
35 Patch: Sebastian Geerken
36 +- Added the "view-source" keybinding (default: Ctrl-U).
37 Patch: Alexander Voigt
38 +- Introduced the domainrc mechanism for finer-grained control than
39 filter_auto_requests had provided.
40 Patch: p37sitdu, corvid
41 +- After focusing option menu, keypress will seek to next one beginning with
42 that character.
43 - When active tab is closed, focus the last one visited or opened.
44 - Fixed a bug in dpip when dillo aborts a running dpi connection.
45 Patches: Jorge Arellano Cid
46 +- Better window titles.
47 - Show dialog if saved file would overwrite an existing one.
48 Patches: Jeremy Henty
49 +- Remove hardcoded UI colors.
50 Patch: Benjamin Johnson, corvid
51 +- Fix fd leak in dpi write failure case.
52 Patch: p37sitdu, Jorge Arellano Cid
53
54 -----------------------------------------------------------------------------
855
956 dillo-3.0.2 [December 05, 2011]
1057
0 Installation Instructions
1 *************************
2
3 Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
4 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
5
6 Copying and distribution of this file, with or without modification,
7 are permitted in any medium without royalty provided the copyright
8 notice and this notice are preserved. This file is offered as-is,
9 without warranty of any kind.
10
011 Basic Installation
112 ==================
213
3 These are generic installation instructions.
14 Briefly, the shell commands `./configure; make; make install' should
15 configure, build, and install this package. The following
16 more-detailed instructions are generic; see the `README' file for
17 instructions specific to this package. Some packages provide this
18 `INSTALL' file but do not implement all of the features documented
19 below. The lack of an optional feature in a given package is not
20 necessarily a bug. More recommendations for GNU packages can be found
21 in *note Makefile Conventions: (standards)Makefile Conventions.
422
523 The `configure' shell script attempts to guess correct values for
624 various system-dependent variables used during compilation. It uses
725 those values to create a `Makefile' in each directory of the package.
826 It may also create one or more `.h' files containing system-dependent
927 definitions. Finally, it creates a shell script `config.status' that
10 you can run in the future to recreate the current configuration, a file
11 `config.cache' that saves the results of its tests to speed up
12 reconfiguring, and a file `config.log' containing compiler output
13 (useful mainly for debugging `configure').
28 you can run in the future to recreate the current configuration, and a
29 file `config.log' containing compiler output (useful mainly for
30 debugging `configure').
31
32 It can also use an optional file (typically called `config.cache'
33 and enabled with `--cache-file=config.cache' or simply `-C') that saves
34 the results of its tests to speed up reconfiguring. Caching is
35 disabled by default to prevent problems with accidental use of stale
36 cache files.
1437
1538 If you need to do unusual things to compile the package, please try
1639 to figure out how `configure' could check whether to do them, and mail
1740 diffs or instructions to the address given in the `README' so they can
18 be considered for the next release. If at some point `config.cache'
19 contains results you don't want to keep, you may remove or edit it.
20
21 The file `configure.in' is used to create `configure' by a program
22 called `autoconf'. You only need `configure.in' if you want to change
23 it or regenerate `configure' using a newer version of `autoconf'.
24
25 The simplest way to compile this package is:
41 be considered for the next release. If you are using the cache, and at
42 some point `config.cache' contains results you don't want to keep, you
43 may remove or edit it.
44
45 The file `configure.ac' (or `configure.in') is used to create
46 `configure' by a program called `autoconf'. You need `configure.ac' if
47 you want to change it or regenerate `configure' using a newer version
48 of `autoconf'.
49
50 The simplest way to compile this package is:
2651
2752 1. `cd' to the directory containing the package's source code and type
28 `./configure' to configure the package for your system. If you're
29 using `csh' on an old version of System V, you might need to type
30 `sh ./configure' instead to prevent `csh' from trying to execute
31 `configure' itself.
32
33 Running `configure' takes a while. While running, it prints some
34 messages telling which features it is checking for.
53 `./configure' to configure the package for your system.
54
55 Running `configure' might take a while. While running, it prints
56 some messages telling which features it is checking for.
3557
3658 2. Type `make' to compile the package.
3759
3860 3. Optionally, type `make check' to run any self-tests that come with
39 the package.
61 the package, generally using the just-built uninstalled binaries.
4062
4163 4. Type `make install' to install the programs and any data files and
42 documentation.
43
44 5. You can remove the program binaries and object files from the
64 documentation. When installing into a prefix owned by root, it is
65 recommended that the package be configured and built as a regular
66 user, and only the `make install' phase executed with root
67 privileges.
68
69 5. Optionally, type `make installcheck' to repeat any self-tests, but
70 this time using the binaries in their final installed location.
71 This target does not install anything. Running this target as a
72 regular user, particularly if the prior `make install' required
73 root privileges, verifies that the installation completed
74 correctly.
75
76 6. You can remove the program binaries and object files from the
4577 source code directory by typing `make clean'. To also remove the
4678 files that `configure' created (so you can compile the package for
4779 a different kind of computer), type `make distclean'. There is
5082 all sorts of other programs in order to regenerate files that came
5183 with the distribution.
5284
85 7. Often, you can also type `make uninstall' to remove the installed
86 files again. In practice, not all packages have tested that
87 uninstallation works correctly, even though it is required by the
88 GNU Coding Standards.
89
90 8. Some packages, particularly those that use Automake, provide `make
91 distcheck', which can by used by developers to test that all other
92 targets like `make install' and `make uninstall' work correctly.
93 This target is generally not run by end users.
94
5395 Compilers and Options
5496 =====================
5597
5698 Some systems require unusual options for compilation or linking that
57 the `configure' script does not know about. You can give `configure'
58 initial values for variables by setting them in the environment. Using
59 a Bourne-compatible shell, you can do that on the command line like
60 this:
61 CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
62
63 Or on systems that have the `env' program, you can do it like this:
64 env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
99 the `configure' script does not know about. Run `./configure --help'
100 for details on some of the pertinent environment variables.
101
102 You can give `configure' initial values for configuration parameters
103 by setting variables in the command line or in the environment. Here
104 is an example:
105
106 ./configure CC=c99 CFLAGS=-g LIBS=-lposix
107
108 *Note Defining Variables::, for more details.
65109
66110 Compiling For Multiple Architectures
67111 ====================================
68112
69113 You can compile the package for more than one kind of computer at the
70114 same time, by placing the object files for each architecture in their
71 own directory. To do this, you must use a version of `make' that
72 supports the `VPATH' variable, such as GNU `make'. `cd' to the
115 own directory. To do this, you can use GNU `make'. `cd' to the
73116 directory where you want the object files and executables to go and run
74117 the `configure' script. `configure' automatically checks for the
75 source code in the directory that `configure' is in and in `..'.
76
77 If you have to use a `make' that does not supports the `VPATH'
78 variable, you have to compile the package for one architecture at a time
79 in the source code directory. After you have installed the package for
80 one architecture, use `make distclean' before reconfiguring for another
81 architecture.
118 source code in the directory that `configure' is in and in `..'. This
119 is known as a "VPATH" build.
120
121 With a non-GNU `make', it is safer to compile the package for one
122 architecture at a time in the source code directory. After you have
123 installed the package for one architecture, use `make distclean' before
124 reconfiguring for another architecture.
125
126 On MacOS X 10.5 and later systems, you can create libraries and
127 executables that work on multiple system types--known as "fat" or
128 "universal" binaries--by specifying multiple `-arch' options to the
129 compiler but only a single `-arch' option to the preprocessor. Like
130 this:
131
132 ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
133 CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
134 CPP="gcc -E" CXXCPP="g++ -E"
135
136 This is not guaranteed to produce working output in all cases, you
137 may have to build one architecture at a time and combine the results
138 using the `lipo' tool if you have problems.
82139
83140 Installation Names
84141 ==================
85142
86 By default, `make install' will install the package's files in
87 `/usr/local/bin', `/usr/local/man', etc. You can specify an
88 installation prefix other than `/usr/local' by giving `configure' the
89 option `--prefix=PATH'.
143 By default, `make install' installs the package's commands under
144 `/usr/local/bin', include files under `/usr/local/include', etc. You
145 can specify an installation prefix other than `/usr/local' by giving
146 `configure' the option `--prefix=PREFIX', where PREFIX must be an
147 absolute file name.
90148
91149 You can specify separate installation prefixes for
92150 architecture-specific files and architecture-independent files. If you
93 give `configure' the option `--exec-prefix=PATH', the package will use
94 PATH as the prefix for installing programs and libraries.
95 Documentation and other data files will still use the regular prefix.
151 pass the option `--exec-prefix=PREFIX' to `configure', the package uses
152 PREFIX as the prefix for installing programs and libraries.
153 Documentation and other data files still use the regular prefix.
154
155 In addition, if you use an unusual directory layout you can give
156 options like `--bindir=DIR' to specify different values for particular
157 kinds of files. Run `configure --help' for a list of the directories
158 you can set and what kinds of files go in them. In general, the
159 default for these options is expressed in terms of `${prefix}', so that
160 specifying just `--prefix' will affect all of the other directory
161 specifications that were not explicitly provided.
162
163 The most portable way to affect installation locations is to pass the
164 correct locations to `configure'; however, many packages provide one or
165 both of the following shortcuts of passing variable assignments to the
166 `make install' command line to change installation locations without
167 having to reconfigure or recompile.
168
169 The first method involves providing an override variable for each
170 affected directory. For example, `make install
171 prefix=/alternate/directory' will choose an alternate location for all
172 directory configuration variables that were expressed in terms of
173 `${prefix}'. Any directories that were specified during `configure',
174 but not in terms of `${prefix}', must each be overridden at install
175 time for the entire installation to be relocated. The approach of
176 makefile variable overrides for each directory variable is required by
177 the GNU Coding Standards, and ideally causes no recompilation.
178 However, some platforms have known limitations with the semantics of
179 shared libraries that end up requiring recompilation when using this
180 method, particularly noticeable in packages that use GNU Libtool.
181
182 The second method involves providing the `DESTDIR' variable. For
183 example, `make install DESTDIR=/alternate/directory' will prepend
184 `/alternate/directory' before all installation names. The approach of
185 `DESTDIR' overrides is not required by the GNU Coding Standards, and
186 does not work on platforms that have drive letters. On the other hand,
187 it does better at avoiding recompilation issues, and works well even
188 when some directory options were not specified in terms of `${prefix}'
189 at `configure' time.
190
191 Optional Features
192 =================
96193
97194 If the package supports it, you can cause programs to be installed
98195 with an extra prefix or suffix on their names by giving `configure' the
99196 option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
100
101 Optional Features
102 =================
103197
104198 Some packages pay attention to `--enable-FEATURE' options to
105199 `configure', where FEATURE indicates an optional part of the package.
113207 you can use the `configure' options `--x-includes=DIR' and
114208 `--x-libraries=DIR' to specify their locations.
115209
210 Some packages offer the ability to configure how verbose the
211 execution of `make' will be. For these packages, running `./configure
212 --enable-silent-rules' sets the default to minimal output, which can be
213 overridden with `make V=1'; while running `./configure
214 --disable-silent-rules' sets the default to verbose, which can be
215 overridden with `make V=0'.
216
217 Particular systems
218 ==================
219
220 On HP-UX, the default C compiler is not ANSI C compatible. If GNU
221 CC is not installed, it is recommended to use the following options in
222 order to use an ANSI C compiler:
223
224 ./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
225
226 and if that doesn't work, install pre-built binaries of GCC for HP-UX.
227
228 On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
229 parse its `<wchar.h>' header file. The option `-nodtk' can be used as
230 a workaround. If GNU CC is not installed, it is therefore recommended
231 to try
232
233 ./configure CC="cc"
234
235 and if that doesn't work, try
236
237 ./configure CC="cc -nodtk"
238
239 On Solaris, don't put `/usr/ucb' early in your `PATH'. This
240 directory contains several dysfunctional programs; working variants of
241 these programs are available in `/usr/bin'. So, if you need `/usr/ucb'
242 in your `PATH', put it _after_ `/usr/bin'.
243
244 On Haiku, software installed for all users goes in `/boot/common',
245 not `/usr/local'. It is recommended to use the following options:
246
247 ./configure --prefix=/boot/common
248
116249 Specifying the System Type
117250 ==========================
118251
119 There may be some features `configure' can not figure out
120 automatically, but needs to determine by the type of host the package
121 will run on. Usually `configure' can figure that out, but if it prints
122 a message saying it can not guess the host type, give it the
123 `--host=TYPE' option. TYPE can either be a short name for the system
124 type, such as `sun4', or a canonical name with three fields:
252 There may be some features `configure' cannot figure out
253 automatically, but needs to determine by the type of machine the package
254 will run on. Usually, assuming the package is built to be run on the
255 _same_ architectures, `configure' can figure that out, but if it prints
256 a message saying it cannot guess the machine type, give it the
257 `--build=TYPE' option. TYPE can either be a short name for the system
258 type, such as `sun4', or a canonical name which has the form:
259
125260 CPU-COMPANY-SYSTEM
126261
127 See the file `config.sub' for the possible values of each field. If
262 where SYSTEM can have one of these forms:
263
264 OS
265 KERNEL-OS
266
267 See the file `config.sub' for the possible values of each field. If
128268 `config.sub' isn't included in this package, then this package doesn't
129 need to know the host type.
130
131 If you are building compiler tools for cross-compiling, you can also
132 use the `--target=TYPE' option to select the type of system they will
133 produce code for and the `--build=TYPE' option to select the type of
134 system on which you are compiling the package.
269 need to know the machine type.
270
271 If you are _building_ compiler tools for cross-compiling, you should
272 use the option `--target=TYPE' to select the type of system they will
273 produce code for.
274
275 If you want to _use_ a cross compiler, that generates code for a
276 platform different from the build platform, you should specify the
277 "host" platform (i.e., that on which the generated programs will
278 eventually be run) with `--host=TYPE'.
135279
136280 Sharing Defaults
137281 ================
144288 `CONFIG_SITE' environment variable to the location of the site script.
145289 A warning: not all `configure' scripts look for a site script.
146290
147 Operation Controls
291 Defining Variables
148292 ==================
293
294 Variables not defined in a site shell script can be set in the
295 environment passed to `configure'. However, some packages may run
296 configure again during the build, and the customized values of these
297 variables may be lost. In order to avoid this problem, you should set
298 them in the `configure' command line, using `VAR=value'. For example:
299
300 ./configure CC=/usr/local2/bin/gcc
301
302 causes the specified `gcc' to be used as the C compiler (unless it is
303 overridden in the site shell script).
304
305 Unfortunately, this technique does not work for `CONFIG_SHELL' due to
306 an Autoconf bug. Until the bug is fixed you can use this workaround:
307
308 CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
309
310 `configure' Invocation
311 ======================
149312
150313 `configure' recognizes the following options to control how it
151314 operates.
152315
316 `--help'
317 `-h'
318 Print a summary of all of the options to `configure', and exit.
319
320 `--help=short'
321 `--help=recursive'
322 Print a summary of the options unique to this package's
323 `configure', and exit. The `short' variant lists options used
324 only in the top level, while the `recursive' variant lists options
325 also present in any nested packages.
326
327 `--version'
328 `-V'
329 Print the version of Autoconf used to generate the `configure'
330 script, and exit.
331
153332 `--cache-file=FILE'
154 Use and save the results of the tests in FILE instead of
155 `./config.cache'. Set FILE to `/dev/null' to disable caching, for
156 debugging `configure'.
157
158 `--help'
159 Print a summary of the options to `configure', and exit.
333 Enable the cache: use and save the results of the tests in FILE,
334 traditionally `config.cache'. FILE defaults to `/dev/null' to
335 disable caching.
336
337 `--config-cache'
338 `-C'
339 Alias for `--cache-file=config.cache'.
160340
161341 `--quiet'
162342 `--silent'
163343 `-q'
164 Do not print messages saying which checks are being made.
344 Do not print messages saying which checks are being made. To
345 suppress all normal output, redirect it to `/dev/null' (any error
346 messages will still be shown).
165347
166348 `--srcdir=DIR'
167349 Look for the package's source code in directory DIR. Usually
168350 `configure' can determine that directory automatically.
169351
170 `--version'
171 Print the version of Autoconf used to generate the `configure'
172 script, and exit.
173
174 `configure' also accepts some other, not widely useful, options.
175
352 `--prefix=DIR'
353 Use DIR as the installation prefix. *note Installation Names::
354 for more details, including other options available for fine-tuning
355 the installation locations.
356
357 `--no-create'
358 `-n'
359 Run the configure checks, but stop before creating any output
360 files.
361
362 `configure' also accepts some other, not widely useful, options. Run
363 `configure --help' for more details.
364
00 SUBDIRS = lout dw dlib dpip src doc dpid dpi test
1
2 dist_bin_SCRIPTS = dillo-install-hyphenation
13
24 EXTRA_DIST = Doxyfile dillorc install-dpi-local d_size.h
35
0 # Makefile.in generated by automake 1.11.1 from Makefile.am.
0 # Makefile.in generated by automake 1.11.6 from Makefile.am.
11 # @configure_input@
22
33 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
4 # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
5 # Inc.
4 # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
5 # Foundation, Inc.
66 # This Makefile.in is free software; the Free Software Foundation
77 # gives unlimited permission to copy and/or distribute it,
88 # with or without modifications, as long as this notice is preserved.
1414
1515 @SET_MAKE@
1616
17
1718 VPATH = @srcdir@
19 am__make_dryrun = \
20 { \
21 am__dry=no; \
22 case $$MAKEFLAGS in \
23 *\\[\ \ ]*) \
24 echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
25 | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
26 *) \
27 for am__flg in $$MAKEFLAGS; do \
28 case $$am__flg in \
29 *=*|--*) ;; \
30 *n*) am__dry=yes; break;; \
31 esac; \
32 done;; \
33 esac; \
34 test $$am__dry = yes; \
35 }
1836 pkgdatadir = $(datadir)/@PACKAGE@
1937 pkgincludedir = $(includedir)/@PACKAGE@
2038 pkglibdir = $(libdir)/@PACKAGE@
3553 host_triplet = @host@
3654 target_triplet = @target@
3755 subdir = .
38 DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
39 $(srcdir)/Makefile.in $(srcdir)/config.h.in \
40 $(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \
41 config.guess config.sub depcomp install-sh missing
56 DIST_COMMON = README $(am__configure_deps) $(dist_bin_SCRIPTS) \
57 $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
58 $(srcdir)/config.h.in $(top_srcdir)/configure AUTHORS COPYING \
59 ChangeLog INSTALL NEWS config.guess config.sub depcomp \
60 install-sh missing
4261 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
43 am__aclocal_m4_deps = $(top_srcdir)/configure.in
62 am__aclocal_m4_deps = $(top_srcdir)/configure.ac
4463 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
4564 $(ACLOCAL_M4)
4665 am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
4968 CONFIG_HEADER = config.h
5069 CONFIG_CLEAN_FILES =
5170 CONFIG_CLEAN_VPATH_FILES =
52 SOURCES =
53 DIST_SOURCES =
54 RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
55 html-recursive info-recursive install-data-recursive \
56 install-dvi-recursive install-exec-recursive \
57 install-html-recursive install-info-recursive \
58 install-pdf-recursive install-ps-recursive install-recursive \
59 installcheck-recursive installdirs-recursive pdf-recursive \
60 ps-recursive uninstall-recursive
6171 am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
6272 am__vpath_adj = case $$p in \
6373 $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
7989 am__base_list = \
8090 sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
8191 sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
82 am__installdirs = "$(DESTDIR)$(sysconfdir)"
92 am__uninstall_files_from_dir = { \
93 test -z "$$files" \
94 || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
95 || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
96 $(am__cd) "$$dir" && rm -f $$files; }; \
97 }
98 am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sysconfdir)"
99 SCRIPTS = $(dist_bin_SCRIPTS)
100 SOURCES =
101 DIST_SOURCES =
102 RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
103 html-recursive info-recursive install-data-recursive \
104 install-dvi-recursive install-exec-recursive \
105 install-html-recursive install-info-recursive \
106 install-pdf-recursive install-ps-recursive install-recursive \
107 installcheck-recursive installdirs-recursive pdf-recursive \
108 ps-recursive uninstall-recursive
109 am__can_run_installinfo = \
110 case $$AM_UPDATE_INFO_DIR in \
111 n|no|NO) false;; \
112 *) (install-info --version) >/dev/null 2>&1;; \
113 esac
83114 DATA = $(sysconf_DATA)
84115 RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
85116 distclean-recursive maintainer-clean-recursive
93124 distdir = $(PACKAGE)-$(VERSION)
94125 top_distdir = $(distdir)
95126 am__remove_distdir = \
96 { test ! -d "$(distdir)" \
97 || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
98 && rm -fr "$(distdir)"; }; }
127 if test -d "$(distdir)"; then \
128 find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
129 && rm -rf "$(distdir)" \
130 || { sleep 5 && rm -rf "$(distdir)"; }; \
131 else :; fi
99132 am__relativize = \
100133 dir0=`pwd`; \
101134 sed_first='s,^\([^/]*\)/.*$$,\1,'; \
124157 DIST_ARCHIVES = $(distdir).tar.gz
125158 GZIP_ENV = --best
126159 distuninstallcheck_listfiles = find . -type f -print
160 am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
161 | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
127162 distcleancheck_listfiles = find . -type f -print
128163 ACLOCAL = @ACLOCAL@
129164 AMTAR = @AMTAR@
242277 top_builddir = @top_builddir@
243278 top_srcdir = @top_srcdir@
244279 SUBDIRS = lout dw dlib dpip src doc dpid dpi test
280 dist_bin_SCRIPTS = dillo-install-hyphenation
245281 EXTRA_DIST = Doxyfile dillorc install-dpi-local d_size.h
246282 sysconf_DATA = dillorc
247283 all: config.h
248284 $(MAKE) $(AM_MAKEFLAGS) all-recursive
249285
250286 .SUFFIXES:
251 am--refresh:
287 am--refresh: Makefile
252288 @:
253289 $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
254290 @for dep in $?; do \
284320 $(am__aclocal_m4_deps):
285321
286322 config.h: stamp-h1
287 @if test ! -f $@; then \
288 rm -f stamp-h1; \
289 $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \
290 else :; fi
323 @if test ! -f $@; then rm -f stamp-h1; else :; fi
324 @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi
291325
292326 stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
293327 @rm -f stamp-h1
299333
300334 distclean-hdr:
301335 -rm -f config.h stamp-h1
336 install-dist_binSCRIPTS: $(dist_bin_SCRIPTS)
337 @$(NORMAL_INSTALL)
338 @list='$(dist_bin_SCRIPTS)'; test -n "$(bindir)" || list=; \
339 if test -n "$$list"; then \
340 echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
341 $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
342 fi; \
343 for p in $$list; do \
344 if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
345 if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
346 done | \
347 sed -e 'p;s,.*/,,;n' \
348 -e 'h;s|.*|.|' \
349 -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
350 $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
351 { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
352 if ($$2 == $$4) { files[d] = files[d] " " $$1; \
353 if (++n[d] == $(am__install_max)) { \
354 print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
355 else { print "f", d "/" $$4, $$1 } } \
356 END { for (d in files) print "f", d, files[d] }' | \
357 while read type dir files; do \
358 if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
359 test -z "$$files" || { \
360 echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \
361 $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
362 } \
363 ; done
364
365 uninstall-dist_binSCRIPTS:
366 @$(NORMAL_UNINSTALL)
367 @list='$(dist_bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \
368 files=`for p in $$list; do echo "$$p"; done | \
369 sed -e 's,.*/,,;$(transform)'`; \
370 dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir)
302371 install-sysconfDATA: $(sysconf_DATA)
303372 @$(NORMAL_INSTALL)
304 test -z "$(sysconfdir)" || $(MKDIR_P) "$(DESTDIR)$(sysconfdir)"
305373 @list='$(sysconf_DATA)'; test -n "$(sysconfdir)" || list=; \
374 if test -n "$$list"; then \
375 echo " $(MKDIR_P) '$(DESTDIR)$(sysconfdir)'"; \
376 $(MKDIR_P) "$(DESTDIR)$(sysconfdir)" || exit 1; \
377 fi; \
306378 for p in $$list; do \
307379 if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
308380 echo "$$d$$p"; \
316388 @$(NORMAL_UNINSTALL)
317389 @list='$(sysconf_DATA)'; test -n "$(sysconfdir)" || list=; \
318390 files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
319 test -n "$$files" || exit 0; \
320 echo " ( cd '$(DESTDIR)$(sysconfdir)' && rm -f" $$files ")"; \
321 cd "$(DESTDIR)$(sysconfdir)" && rm -f $$files
391 dir='$(DESTDIR)$(sysconfdir)'; $(am__uninstall_files_from_dir)
322392
323393 # This directory's subdirectories are mostly independent; you can cd
324394 # into them and run `make' without going through this Makefile.
489559 done
490560 @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
491561 if test "$$subdir" = .; then :; else \
492 test -d "$(distdir)/$$subdir" \
493 || $(MKDIR_P) "$(distdir)/$$subdir" \
494 || exit 1; \
495 fi; \
496 done
497 @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
498 if test "$$subdir" = .; then :; else \
562 $(am__make_dryrun) \
563 || test -d "$(distdir)/$$subdir" \
564 || $(MKDIR_P) "$(distdir)/$$subdir" \
565 || exit 1; \
499566 dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
500567 $(am__relativize); \
501568 new_distdir=$$reldir; \
527594 $(am__remove_distdir)
528595
529596 dist-bzip2: distdir
530 tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
597 tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
598 $(am__remove_distdir)
599
600 dist-lzip: distdir
601 tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
531602 $(am__remove_distdir)
532603
533604 dist-lzma: distdir
535606 $(am__remove_distdir)
536607
537608 dist-xz: distdir
538 tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz
609 tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
539610 $(am__remove_distdir)
540611
541612 dist-tarZ: distdir
566637 bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
567638 *.tar.lzma*) \
568639 lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\
640 *.tar.lz*) \
641 lzip -dc $(distdir).tar.lz | $(am__untar) ;;\
569642 *.tar.xz*) \
570643 xz -dc $(distdir).tar.xz | $(am__untar) ;;\
571644 *.tar.Z*) \
575648 *.zip*) \
576649 unzip $(distdir).zip ;;\
577650 esac
578 chmod -R a-w $(distdir); chmod a+w $(distdir)
651 chmod -R a-w $(distdir); chmod u+w $(distdir)
579652 mkdir $(distdir)/_build
580653 mkdir $(distdir)/_inst
581654 chmod a-w $(distdir)
585658 && am__cwd=`pwd` \
586659 && $(am__cd) $(distdir)/_build \
587660 && ../configure --srcdir=.. --prefix="$$dc_install_base" \
661 $(AM_DISTCHECK_CONFIGURE_FLAGS) \
588662 $(DISTCHECK_CONFIGURE_FLAGS) \
589663 && $(MAKE) $(AM_MAKEFLAGS) \
590664 && $(MAKE) $(AM_MAKEFLAGS) dvi \
613687 list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
614688 sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
615689 distuninstallcheck:
616 @$(am__cd) '$(distuninstallcheck_dir)' \
617 && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
690 @test -n '$(distuninstallcheck_dir)' || { \
691 echo 'ERROR: trying to run $@ with an empty' \
692 '$$(distuninstallcheck_dir)' >&2; \
693 exit 1; \
694 }; \
695 $(am__cd) '$(distuninstallcheck_dir)' || { \
696 echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \
697 exit 1; \
698 }; \
699 test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \
618700 || { echo "ERROR: files left after uninstall:" ; \
619701 if test -n "$(DESTDIR)"; then \
620702 echo " (check DESTDIR support)"; \
632714 exit 1; } >&2
633715 check-am: all-am
634716 check: check-recursive
635 all-am: Makefile $(DATA) config.h
717 all-am: Makefile $(SCRIPTS) $(DATA) config.h
636718 installdirs: installdirs-recursive
637719 installdirs-am:
638 for dir in "$(DESTDIR)$(sysconfdir)"; do \
720 for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sysconfdir)"; do \
639721 test -z "$$dir" || $(MKDIR_P) "$$dir"; \
640722 done
641723 install: install-recursive
648730
649731 installcheck: installcheck-recursive
650732 install-strip:
651 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
652 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
653 `test -z '$(STRIP)' || \
654 echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
733 if test -z '$(STRIP)'; then \
734 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
735 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
736 install; \
737 else \
738 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
739 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
740 "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
741 fi
655742 mostlyclean-generic:
656743
657744 clean-generic:
690777
691778 install-dvi-am:
692779
693 install-exec-am: install-sysconfDATA
780 install-exec-am: install-dist_binSCRIPTS install-sysconfDATA
694781
695782 install-html: install-html-recursive
696783
730817
731818 ps-am:
732819
733 uninstall-am: uninstall-sysconfDATA
820 uninstall-am: uninstall-dist_binSCRIPTS uninstall-sysconfDATA
734821
735822 .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \
736823 ctags-recursive install-am install-strip tags-recursive
738825 .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
739826 all all-am am--refresh check check-am clean clean-generic \
740827 ctags ctags-recursive dist dist-all dist-bzip2 dist-gzip \
741 dist-lzma dist-shar dist-tarZ dist-xz dist-zip distcheck \
742 distclean distclean-generic distclean-hdr distclean-tags \
743 distcleancheck distdir distuninstallcheck dvi dvi-am html \
744 html-am info info-am install install-am install-data \
745 install-data-am install-dvi install-dvi-am install-exec \
746 install-exec-am install-html install-html-am install-info \
747 install-info-am install-man install-pdf install-pdf-am \
748 install-ps install-ps-am install-strip install-sysconfDATA \
749 installcheck installcheck-am installdirs installdirs-am \
750 maintainer-clean maintainer-clean-generic mostlyclean \
751 mostlyclean-generic pdf pdf-am ps ps-am tags tags-recursive \
752 uninstall uninstall-am uninstall-sysconfDATA
828 dist-lzip dist-lzma dist-shar dist-tarZ dist-xz dist-zip \
829 distcheck distclean distclean-generic distclean-hdr \
830 distclean-tags distcleancheck distdir distuninstallcheck dvi \
831 dvi-am html html-am info info-am install install-am \
832 install-data install-data-am install-dist_binSCRIPTS \
833 install-dvi install-dvi-am install-exec install-exec-am \
834 install-html install-html-am install-info install-info-am \
835 install-man install-pdf install-pdf-am install-ps \
836 install-ps-am install-strip install-sysconfDATA installcheck \
837 installcheck-am installdirs installdirs-am maintainer-clean \
838 maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
839 pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \
840 uninstall-dist_binSCRIPTS uninstall-sysconfDATA
753841
754842
755843 # Tell versions [3.59,3.63) of GNU make to not export all variables.
3737
3838 dillo-3.0.1, a bugfix release for the new 3.x series is out.
3939
40 Mar 2013
41
42 dillo-3.0.3, a new release for the new 3.x series is out.
4043
4144 Jorge.-
4245 jcid@dillo.org
2929 * no https (there's a barebones prototype).
3030
3131
32 -------
32 --------
3333 FLTK-1.3
34 -------
34 --------
3535
36 You can get FLTK-1.3 here:
36 If you don't have FLTK-1.3 (try 'fltk-config --version' to check),
37 you can get it from:
3738
38 http://fltk.org/software.php?VERSION=1.3.0
39 http://fltk.org/software.php
3940
41 and build it like:
4042
41 ---------------------------
42 Building dillo from sources
43 ---------------------------
44
45 1.- Install fltk:
46
47 tar zxvf fltk-1.3.0-source.tar.gz
48 cd fltk-1.3.0
43 tar zxvf fltk-1.3.2-source.tar.gz [or latest 1.3.x version]
44 cd fltk-1.3.2
4945 less README.Unix.txt
5046 make
5147 sudo make install
5248 cd ..
53
54 (don't configure fltk with --enable-cairo)
5549
56 2.- Then dillo3:
50 ------
51 Dillo3
52 ------
5753
58 tar jxvf dillo-3.0.2.tar.bz2
59 cd dillo-3.0.2
54 tar jxvf dillo-3.0.3.tar.bz2
55 cd dillo-3.0.3
6056 ./configure; make
6157 sudo make install-strip
58
59 In order to use the hyphenation feature, pattern files from CTAN need
60 to be installed.
61 This can be done with the script dillo-install-hyphenation.
62 Call it with ISO-639-1 language codes as arguments, or without arguments
63 to get more help.
6264
6365
6466 ------------
102104
103105 Jorge.-
104106 (jcid@dillo.org)
105 August, 2011
107 April, 2013
0 # generated automatically by aclocal 1.11.1 -*- Autoconf -*-
0 # generated automatically by aclocal 1.11.6 -*- Autoconf -*-
11
22 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3 # 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
3 # 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation,
4 # Inc.
45 # This file is free software; the Free Software Foundation
56 # gives unlimited permission to copy and/or distribute it,
67 # with or without modifications, as long as this notice is preserved.
1213
1314 m4_ifndef([AC_AUTOCONF_VERSION],
1415 [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
15 m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.68],,
16 [m4_warning([this file was generated for autoconf 2.68.
16 m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],,
17 [m4_warning([this file was generated for autoconf 2.69.
1718 You have another version of autoconf. It may work, but is not guaranteed to.
1819 If you have problems, you may need to regenerate the build system entirely.
1920 To do so, use the procedure documented by the package, typically `autoreconf'.])])
2021
21 # Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
22 #
23 # This file is free software; the Free Software Foundation
24 # gives unlimited permission to copy and/or distribute it,
25 # with or without modifications, as long as this notice is preserved.
22 # Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2011 Free Software
23 # Foundation, Inc.
24 #
25 # This file is free software; the Free Software Foundation
26 # gives unlimited permission to copy and/or distribute it,
27 # with or without modifications, as long as this notice is preserved.
28
29 # serial 1
2630
2731 # AM_AUTOMAKE_VERSION(VERSION)
2832 # ----------------------------
3337 [am__api_version='1.11'
3438 dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
3539 dnl require some minimum version. Point them to the right macro.
36 m4_if([$1], [1.11.1], [],
40 m4_if([$1], [1.11.6], [],
3741 [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
3842 ])
3943
4953 # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
5054 # This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
5155 AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
52 [AM_AUTOMAKE_VERSION([1.11.1])dnl
56 [AM_AUTOMAKE_VERSION([1.11.6])dnl
5357 m4_ifndef([AC_AUTOCONF_VERSION],
5458 [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
5559 _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
5660
5761 # AM_AUX_DIR_EXPAND -*- Autoconf -*-
5862
59 # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
60 #
61 # This file is free software; the Free Software Foundation
62 # gives unlimited permission to copy and/or distribute it,
63 # with or without modifications, as long as this notice is preserved.
63 # Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc.
64 #
65 # This file is free software; the Free Software Foundation
66 # gives unlimited permission to copy and/or distribute it,
67 # with or without modifications, as long as this notice is preserved.
68
69 # serial 1
6470
6571 # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
6672 # $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
143149 Usually this means the macro was only invoked conditionally.]])
144150 fi])])
145151
146 # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009
147 # Free Software Foundation, Inc.
148 #
149 # This file is free software; the Free Software Foundation
150 # gives unlimited permission to copy and/or distribute it,
151 # with or without modifications, as long as this notice is preserved.
152
153 # serial 10
152 # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009,
153 # 2010, 2011 Free Software Foundation, Inc.
154 #
155 # This file is free software; the Free Software Foundation
156 # gives unlimited permission to copy and/or distribute it,
157 # with or without modifications, as long as this notice is preserved.
158
159 # serial 12
154160
155161 # There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
156162 # written in clear, in which case automake, when reading aclocal.m4,
190196 # instance it was reported that on HP-UX the gcc test will end up
191197 # making a dummy file named `D' -- because `-MD' means `put the output
192198 # in D'.
199 rm -rf conftest.dir
193200 mkdir conftest.dir
194201 # Copy depcomp to subdir because otherwise we won't find it if we're
195202 # using a relative directory.
254261 break
255262 fi
256263 ;;
257 msvisualcpp | msvcmsys)
264 msvc7 | msvc7msys | msvisualcpp | msvcmsys)
258265 # This compiler won't grok `-c -o', but also, the minuso test has
259266 # not run yet. These depmodes are late enough in the game, and
260267 # so weak that their functioning should not be impacted.
319326 if test "x$enable_dependency_tracking" != xno; then
320327 am_depcomp="$ac_aux_dir/depcomp"
321328 AMDEPBACKSLASH='\'
329 am__nodep='_no'
322330 fi
323331 AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
324332 AC_SUBST([AMDEPBACKSLASH])dnl
325333 _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
334 AC_SUBST([am__nodep])dnl
335 _AM_SUBST_NOTMAKE([am__nodep])dnl
326336 ])
327337
328338 # Generate code to set up dependency tracking. -*- Autoconf -*-
544554 done
545555 echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
546556
547 # Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc.
548 #
549 # This file is free software; the Free Software Foundation
550 # gives unlimited permission to copy and/or distribute it,
551 # with or without modifications, as long as this notice is preserved.
557 # Copyright (C) 2001, 2003, 2005, 2008, 2011 Free Software Foundation,
558 # Inc.
559 #
560 # This file is free software; the Free Software Foundation
561 # gives unlimited permission to copy and/or distribute it,
562 # with or without modifications, as long as this notice is preserved.
563
564 # serial 1
552565
553566 # AM_PROG_INSTALL_SH
554567 # ------------------
681694 fi
682695 ])
683696
684 # Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
685 #
686 # This file is free software; the Free Software Foundation
687 # gives unlimited permission to copy and/or distribute it,
688 # with or without modifications, as long as this notice is preserved.
697 # Copyright (C) 2003, 2004, 2005, 2006, 2011 Free Software Foundation,
698 # Inc.
699 #
700 # This file is free software; the Free Software Foundation
701 # gives unlimited permission to copy and/or distribute it,
702 # with or without modifications, as long as this notice is preserved.
703
704 # serial 1
689705
690706 # AM_PROG_MKDIR_P
691707 # ---------------
709725
710726 # Helper functions for option handling. -*- Autoconf -*-
711727
712 # Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc.
713 #
714 # This file is free software; the Free Software Foundation
715 # gives unlimited permission to copy and/or distribute it,
716 # with or without modifications, as long as this notice is preserved.
717
718 # serial 4
728 # Copyright (C) 2001, 2002, 2003, 2005, 2008, 2010 Free Software
729 # Foundation, Inc.
730 #
731 # This file is free software; the Free Software Foundation
732 # gives unlimited permission to copy and/or distribute it,
733 # with or without modifications, as long as this notice is preserved.
734
735 # serial 5
719736
720737 # _AM_MANGLE_OPTION(NAME)
721738 # -----------------------
723740 [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
724741
725742 # _AM_SET_OPTION(NAME)
726 # ------------------------------
743 # --------------------
727744 # Set option NAME. Presently that only means defining a flag for this option.
728745 AC_DEFUN([_AM_SET_OPTION],
729746 [m4_define(_AM_MANGLE_OPTION([$1]), 1)])
730747
731748 # _AM_SET_OPTIONS(OPTIONS)
732 # ----------------------------------
749 # ------------------------
733750 # OPTIONS is a space-separated list of Automake options.
734751 AC_DEFUN([_AM_SET_OPTIONS],
735752 [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
805822 fi
806823 AC_MSG_RESULT(yes)])
807824
808 # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
809 #
810 # This file is free software; the Free Software Foundation
811 # gives unlimited permission to copy and/or distribute it,
812 # with or without modifications, as long as this notice is preserved.
825 # Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc.
826 #
827 # This file is free software; the Free Software Foundation
828 # gives unlimited permission to copy and/or distribute it,
829 # with or without modifications, as long as this notice is preserved.
830
831 # serial 1
813832
814833 # AM_PROG_INSTALL_STRIP
815834 # ---------------------
833852 INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
834853 AC_SUBST([INSTALL_STRIP_PROGRAM])])
835854
836 # Copyright (C) 2006, 2008 Free Software Foundation, Inc.
837 #
838 # This file is free software; the Free Software Foundation
839 # gives unlimited permission to copy and/or distribute it,
840 # with or without modifications, as long as this notice is preserved.
841
842 # serial 2
855 # Copyright (C) 2006, 2008, 2010 Free Software Foundation, Inc.
856 #
857 # This file is free software; the Free Software Foundation
858 # gives unlimited permission to copy and/or distribute it,
859 # with or without modifications, as long as this notice is preserved.
860
861 # serial 3
843862
844863 # _AM_SUBST_NOTMAKE(VARIABLE)
845864 # ---------------------------
848867 AC_DEFUN([_AM_SUBST_NOTMAKE])
849868
850869 # AM_SUBST_NOTMAKE(VARIABLE)
851 # ---------------------------
870 # --------------------------
852871 # Public sister of _AM_SUBST_NOTMAKE.
853872 AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
854873
855874 # Check how to create a tarball. -*- Autoconf -*-
856875
857 # Copyright (C) 2004, 2005 Free Software Foundation, Inc.
876 # Copyright (C) 2004, 2005, 2012 Free Software Foundation, Inc.
858877 #
859878 # This file is free software; the Free Software Foundation
860879 # gives unlimited permission to copy and/or distribute it,
876895 # a tarball read from stdin.
877896 # $(am__untar) < result.tar
878897 AC_DEFUN([_AM_PROG_TAR],
879 [# Always define AMTAR for backward compatibility.
880 AM_MISSING_PROG([AMTAR], [tar])
898 [# Always define AMTAR for backward compatibility. Yes, it's still used
899 # in the wild :-( We should find a proper way to deprecate it ...
900 AC_SUBST([AMTAR], ['$${TAR-tar}'])
881901 m4_if([$1], [v7],
882 [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
902 [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
883903 [m4_case([$1], [ustar],, [pax],,
884904 [m4_fatal([Unknown tar format])])
885905 AC_MSG_CHECKING([how to create a $1 tar archive])
00 #! /bin/sh
11 # Attempt to guess a canonical system name.
22 # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
4 # Free Software Foundation, Inc.
5
6 timestamp='2009-11-20'
3 # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
4 # 2011, 2012 Free Software Foundation, Inc.
5
6 timestamp='2012-02-10'
77
88 # This file is free software; you can redistribute it and/or modify it
99 # under the terms of the GNU General Public License as published by
1616 # General Public License for more details.
1717 #
1818 # You should have received a copy of the GNU General Public License
19 # along with this program; if not, write to the Free Software
20 # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
21 # 02110-1301, USA.
19 # along with this program; if not, see <http://www.gnu.org/licenses/>.
2220 #
2321 # As a special exception to the GNU General Public License, if you
2422 # distribute this file as part of a program that contains a
5553 GNU config.guess ($timestamp)
5654
5755 Originally written by Per Bothner.
58 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
59 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
56 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
57 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
58 Free Software Foundation, Inc.
6059
6160 This is free software; see the source for copying conditions. There is NO
6261 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
143142 case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
144143 *:NetBSD:*:*)
145144 # NetBSD (nbsd) targets should (where applicable) match one or
146 # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
145 # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
147146 # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
148147 # switched to ELF, *-*-netbsd* would select the old
149148 # object file format. This provides both forward
179178 fi
180179 ;;
181180 *)
182 os=netbsd
181 os=netbsd
183182 ;;
184183 esac
185184 # The OS release
222221 UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
223222 ;;
224223 *5.*)
225 UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
224 UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
226225 ;;
227226 esac
228227 # According to Compaq, /usr/sbin/psrinfo has been available on
268267 # A Xn.n version is an unreleased experimental baselevel.
269268 # 1.2 uses "1.2" for uname -r.
270269 echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
271 exit ;;
270 # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
271 exitcode=$?
272 trap '' 0
273 exit $exitcode ;;
272274 Alpha\ *:Windows_NT*:*)
273275 # How do we know it's Interix rather than the generic POSIX subsystem?
274276 # Should we change UNAME_MACHINE based on the output of uname instead
294296 echo s390-ibm-zvmoe
295297 exit ;;
296298 *:OS400:*:*)
297 echo powerpc-ibm-os400
299 echo powerpc-ibm-os400
298300 exit ;;
299301 arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
300302 echo arm-acorn-riscix${UNAME_RELEASE}
393395 # MiNT. But MiNT is downward compatible to TOS, so this should
394396 # be no problem.
395397 atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
396 echo m68k-atari-mint${UNAME_RELEASE}
398 echo m68k-atari-mint${UNAME_RELEASE}
397399 exit ;;
398400 atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
399401 echo m68k-atari-mint${UNAME_RELEASE}
400 exit ;;
402 exit ;;
401403 *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
402 echo m68k-atari-mint${UNAME_RELEASE}
404 echo m68k-atari-mint${UNAME_RELEASE}
403405 exit ;;
404406 milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
405 echo m68k-milan-mint${UNAME_RELEASE}
406 exit ;;
407 echo m68k-milan-mint${UNAME_RELEASE}
408 exit ;;
407409 hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
408 echo m68k-hades-mint${UNAME_RELEASE}
409 exit ;;
410 echo m68k-hades-mint${UNAME_RELEASE}
411 exit ;;
410412 *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
411 echo m68k-unknown-mint${UNAME_RELEASE}
412 exit ;;
413 echo m68k-unknown-mint${UNAME_RELEASE}
414 exit ;;
413415 m68k:machten:*:*)
414416 echo m68k-apple-machten${UNAME_RELEASE}
415417 exit ;;
479481 echo m88k-motorola-sysv3
480482 exit ;;
481483 AViiON:dgux:*:*)
482 # DG/UX returns AViiON for all architectures
483 UNAME_PROCESSOR=`/usr/bin/uname -p`
484 # DG/UX returns AViiON for all architectures
485 UNAME_PROCESSOR=`/usr/bin/uname -p`
484486 if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
485487 then
486488 if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
493495 else
494496 echo i586-dg-dgux${UNAME_RELEASE}
495497 fi
496 exit ;;
498 exit ;;
497499 M88*:DolphinOS:*:*) # DolphinOS (SVR3)
498500 echo m88k-dolphin-sysv3
499501 exit ;;
550552 echo rs6000-ibm-aix3.2
551553 fi
552554 exit ;;
553 *:AIX:*:[456])
555 *:AIX:*:[4567])
554556 IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
555557 if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
556558 IBM_ARCH=rs6000
593595 9000/[678][0-9][0-9])
594596 if [ -x /usr/bin/getconf ]; then
595597 sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
596 sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
597 case "${sc_cpu_version}" in
598 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
599 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
600 532) # CPU_PA_RISC2_0
601 case "${sc_kernel_bits}" in
602 32) HP_ARCH="hppa2.0n" ;;
603 64) HP_ARCH="hppa2.0w" ;;
598 sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
599 case "${sc_cpu_version}" in
600 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
601 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
602 532) # CPU_PA_RISC2_0
603 case "${sc_kernel_bits}" in
604 32) HP_ARCH="hppa2.0n" ;;
605 64) HP_ARCH="hppa2.0w" ;;
604606 '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
605 esac ;;
606 esac
607 esac ;;
608 esac
607609 fi
608610 if [ "${HP_ARCH}" = "" ]; then
609611 eval $set_cc_for_build
610 sed 's/^ //' << EOF >$dummy.c
611
612 #define _HPUX_SOURCE
613 #include <stdlib.h>
614 #include <unistd.h>
615
616 int main ()
617 {
618 #if defined(_SC_KERNEL_BITS)
619 long bits = sysconf(_SC_KERNEL_BITS);
620 #endif
621 long cpu = sysconf (_SC_CPU_VERSION);
622
623 switch (cpu)
624 {
625 case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
626 case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
627 case CPU_PA_RISC2_0:
628 #if defined(_SC_KERNEL_BITS)
629 switch (bits)
630 {
631 case 64: puts ("hppa2.0w"); break;
632 case 32: puts ("hppa2.0n"); break;
633 default: puts ("hppa2.0"); break;
634 } break;
635 #else /* !defined(_SC_KERNEL_BITS) */
636 puts ("hppa2.0"); break;
637 #endif
638 default: puts ("hppa1.0"); break;
639 }
640 exit (0);
641 }
612 sed 's/^ //' << EOF >$dummy.c
613
614 #define _HPUX_SOURCE
615 #include <stdlib.h>
616 #include <unistd.h>
617
618 int main ()
619 {
620 #if defined(_SC_KERNEL_BITS)
621 long bits = sysconf(_SC_KERNEL_BITS);
622 #endif
623 long cpu = sysconf (_SC_CPU_VERSION);
624
625 switch (cpu)
626 {
627 case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
628 case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
629 case CPU_PA_RISC2_0:
630 #if defined(_SC_KERNEL_BITS)
631 switch (bits)
632 {
633 case 64: puts ("hppa2.0w"); break;
634 case 32: puts ("hppa2.0n"); break;
635 default: puts ("hppa2.0"); break;
636 } break;
637 #else /* !defined(_SC_KERNEL_BITS) */
638 puts ("hppa2.0"); break;
639 #endif
640 default: puts ("hppa1.0"); break;
641 }
642 exit (0);
643 }
642644 EOF
643645 (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
644646 test -z "$HP_ARCH" && HP_ARCH=hppa
729731 exit ;;
730732 C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
731733 echo c1-convex-bsd
732 exit ;;
734 exit ;;
733735 C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
734736 if getsysinfo -f scalar_acc
735737 then echo c32-convex-bsd
736738 else echo c2-convex-bsd
737739 fi
738 exit ;;
740 exit ;;
739741 C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
740742 echo c34-convex-bsd
741 exit ;;
743 exit ;;
742744 C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
743745 echo c38-convex-bsd
744 exit ;;
746 exit ;;
745747 C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
746748 echo c4-convex-bsd
747 exit ;;
749 exit ;;
748750 CRAY*Y-MP:*:*:*)
749751 echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
750752 exit ;;
768770 exit ;;
769771 F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
770772 FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
771 FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
772 FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
773 echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
774 exit ;;
773 FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
774 FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
775 echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
776 exit ;;
775777 5000:UNIX_System_V:4.*:*)
776 FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
777 FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
778 echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
778 FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
779 FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
780 echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
779781 exit ;;
780782 i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
781783 echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
787789 echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
788790 exit ;;
789791 *:FreeBSD:*:*)
790 case ${UNAME_MACHINE} in
791 pc98)
792 echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
792 UNAME_PROCESSOR=`/usr/bin/uname -p`
793 case ${UNAME_PROCESSOR} in
793794 amd64)
794795 echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
795796 *)
796 echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
797 echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
797798 esac
798799 exit ;;
799800 i*:CYGWIN*:*)
802803 *:MINGW*:*)
803804 echo ${UNAME_MACHINE}-pc-mingw32
804805 exit ;;
806 i*:MSYS*:*)
807 echo ${UNAME_MACHINE}-pc-msys
808 exit ;;
805809 i*:windows32*:*)
806 # uname -m includes "-pc" on this system.
807 echo ${UNAME_MACHINE}-mingw32
810 # uname -m includes "-pc" on this system.
811 echo ${UNAME_MACHINE}-mingw32
808812 exit ;;
809813 i*:PW*:*)
810814 echo ${UNAME_MACHINE}-pc-pw32
811815 exit ;;
812816 *:Interix*:*)
813 case ${UNAME_MACHINE} in
817 case ${UNAME_MACHINE} in
814818 x86)
815819 echo i586-pc-interix${UNAME_RELEASE}
816820 exit ;;
856860 i*86:Minix:*:*)
857861 echo ${UNAME_MACHINE}-pc-minix
858862 exit ;;
863 aarch64:Linux:*:*)
864 echo ${UNAME_MACHINE}-unknown-linux-gnu
865 exit ;;
866 aarch64_be:Linux:*:*)
867 UNAME_MACHINE=aarch64_be
868 echo ${UNAME_MACHINE}-unknown-linux-gnu
869 exit ;;
859870 alpha:Linux:*:*)
860871 case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
861872 EV5) UNAME_MACHINE=alphaev5 ;;
865876 EV6) UNAME_MACHINE=alphaev6 ;;
866877 EV67) UNAME_MACHINE=alphaev67 ;;
867878 EV68*) UNAME_MACHINE=alphaev68 ;;
868 esac
879 esac
869880 objdump --private-headers /bin/sh | grep -q ld.so.1
870881 if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
871882 echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
877888 then
878889 echo ${UNAME_MACHINE}-unknown-linux-gnu
879890 else
880 echo ${UNAME_MACHINE}-unknown-linux-gnueabi
891 if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
892 | grep -q __ARM_PCS_VFP
893 then
894 echo ${UNAME_MACHINE}-unknown-linux-gnueabi
895 else
896 echo ${UNAME_MACHINE}-unknown-linux-gnueabihf
897 fi
881898 fi
882899 exit ;;
883900 avr32*:Linux:*:*)
884901 echo ${UNAME_MACHINE}-unknown-linux-gnu
885902 exit ;;
886903 cris:Linux:*:*)
887 echo cris-axis-linux-gnu
904 echo ${UNAME_MACHINE}-axis-linux-gnu
888905 exit ;;
889906 crisv32:Linux:*:*)
890 echo crisv32-axis-linux-gnu
907 echo ${UNAME_MACHINE}-axis-linux-gnu
891908 exit ;;
892909 frv:Linux:*:*)
893 echo frv-unknown-linux-gnu
910 echo ${UNAME_MACHINE}-unknown-linux-gnu
911 exit ;;
912 hexagon:Linux:*:*)
913 echo ${UNAME_MACHINE}-unknown-linux-gnu
894914 exit ;;
895915 i*86:Linux:*:*)
896916 LIBC=gnu
932952 test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
933953 ;;
934954 or32:Linux:*:*)
935 echo or32-unknown-linux-gnu
955 echo ${UNAME_MACHINE}-unknown-linux-gnu
936956 exit ;;
937957 padre:Linux:*:*)
938958 echo sparc-unknown-linux-gnu
958978 echo ${UNAME_MACHINE}-ibm-linux
959979 exit ;;
960980 sh64*:Linux:*:*)
961 echo ${UNAME_MACHINE}-unknown-linux-gnu
981 echo ${UNAME_MACHINE}-unknown-linux-gnu
962982 exit ;;
963983 sh*:Linux:*:*)
964984 echo ${UNAME_MACHINE}-unknown-linux-gnu
966986 sparc:Linux:*:* | sparc64:Linux:*:*)
967987 echo ${UNAME_MACHINE}-unknown-linux-gnu
968988 exit ;;
989 tile*:Linux:*:*)
990 echo ${UNAME_MACHINE}-unknown-linux-gnu
991 exit ;;
969992 vax:Linux:*:*)
970993 echo ${UNAME_MACHINE}-dec-linux-gnu
971994 exit ;;
972995 x86_64:Linux:*:*)
973 echo x86_64-unknown-linux-gnu
996 echo ${UNAME_MACHINE}-unknown-linux-gnu
974997 exit ;;
975998 xtensa*:Linux:*:*)
976 echo ${UNAME_MACHINE}-unknown-linux-gnu
999 echo ${UNAME_MACHINE}-unknown-linux-gnu
9771000 exit ;;
9781001 i*86:DYNIX/ptx:4*:*)
9791002 # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
9821005 echo i386-sequent-sysv4
9831006 exit ;;
9841007 i*86:UNIX_SV:4.2MP:2.*)
985 # Unixware is an offshoot of SVR4, but it has its own version
986 # number series starting with 2...
987 # I am not positive that other SVR4 systems won't match this,
1008 # Unixware is an offshoot of SVR4, but it has its own version
1009 # number series starting with 2...
1010 # I am not positive that other SVR4 systems won't match this,
9881011 # I just have to hope. -- rms.
989 # Use sysv4.2uw... so that sysv4* matches it.
1012 # Use sysv4.2uw... so that sysv4* matches it.
9901013 echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
9911014 exit ;;
9921015 i*86:OS/2:*:*)
10181041 fi
10191042 exit ;;
10201043 i*86:*:5:[678]*)
1021 # UnixWare 7.x, OpenUNIX and OpenServer 6.
1044 # UnixWare 7.x, OpenUNIX and OpenServer 6.
10221045 case `/bin/uname -X | grep "^Machine"` in
10231046 *486*) UNAME_MACHINE=i486 ;;
10241047 *Pentium) UNAME_MACHINE=i586 ;;
10461069 exit ;;
10471070 pc:*:*:*)
10481071 # Left here for compatibility:
1049 # uname -m prints for DJGPP always 'pc', but it prints nothing about
1050 # the processor, so we play safe by assuming i586.
1072 # uname -m prints for DJGPP always 'pc', but it prints nothing about
1073 # the processor, so we play safe by assuming i586.
10511074 # Note: whatever this is, it MUST be the same as what config.sub
10521075 # prints for the "djgpp" host, or else GDB configury will decide that
10531076 # this is a cross-build.
10541077 echo i586-pc-msdosdjgpp
1055 exit ;;
1078 exit ;;
10561079 Intel:Mach:3*:*)
10571080 echo i386-pc-mach3
10581081 exit ;;
10871110 /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
10881111 && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
10891112 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
1090 /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
1091 && { echo i486-ncr-sysv4; exit; } ;;
1113 /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
1114 && { echo i486-ncr-sysv4; exit; } ;;
10921115 NCR*:*:4.2:* | MPRAS*:*:4.2:*)
10931116 OS_REL='.3'
10941117 test -r /etc/.relid \
11311154 echo ns32k-sni-sysv
11321155 fi
11331156 exit ;;
1134 PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
1135 # says <Richard.M.Bartel@ccMail.Census.GOV>
1136 echo i586-unisys-sysv4
1137 exit ;;
1157 PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
1158 # says <Richard.M.Bartel@ccMail.Census.GOV>
1159 echo i586-unisys-sysv4
1160 exit ;;
11381161 *:UNIX_System_V:4*:FTX*)
11391162 # From Gerald Hewes <hewes@openmarket.com>.
11401163 # How about differentiating between stratus architectures? -djm
11601183 exit ;;
11611184 R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
11621185 if [ -d /usr/nec ]; then
1163 echo mips-nec-sysv${UNAME_RELEASE}
1186 echo mips-nec-sysv${UNAME_RELEASE}
11641187 else
1165 echo mips-unknown-sysv${UNAME_RELEASE}
1166 fi
1167 exit ;;
1188 echo mips-unknown-sysv${UNAME_RELEASE}
1189 fi
1190 exit ;;
11681191 BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
11691192 echo powerpc-be-beos
11701193 exit ;;
12291252 *:QNX:*:4*)
12301253 echo i386-pc-qnx
12311254 exit ;;
1255 NEO-?:NONSTOP_KERNEL:*:*)
1256 echo neo-tandem-nsk${UNAME_RELEASE}
1257 exit ;;
12321258 NSE-?:NONSTOP_KERNEL:*:*)
12331259 echo nse-tandem-nsk${UNAME_RELEASE}
12341260 exit ;;
12741300 echo pdp10-unknown-its
12751301 exit ;;
12761302 SEI:*:*:SEIUX)
1277 echo mips-sei-seiux${UNAME_RELEASE}
1303 echo mips-sei-seiux${UNAME_RELEASE}
12781304 exit ;;
12791305 *:DragonFly:*:*)
12801306 echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
12811307 exit ;;
12821308 *:*VMS:*:*)
1283 UNAME_MACHINE=`(uname -p) 2>/dev/null`
1309 UNAME_MACHINE=`(uname -p) 2>/dev/null`
12841310 case "${UNAME_MACHINE}" in
12851311 A*) echo alpha-dec-vms ; exit ;;
12861312 I*) echo ia64-dec-vms ; exit ;;
12971323 exit ;;
12981324 i*86:AROS:*:*)
12991325 echo ${UNAME_MACHINE}-pc-aros
1326 exit ;;
1327 x86_64:VMkernel:*:*)
1328 echo ${UNAME_MACHINE}-unknown-esx
13001329 exit ;;
13011330 esac
13021331
13201349 #include <sys/param.h>
13211350 printf ("m68k-sony-newsos%s\n",
13221351 #ifdef NEWSOS4
1323 "4"
1352 "4"
13241353 #else
1325 ""
1326 #endif
1327 ); exit (0);
1354 ""
1355 #endif
1356 ); exit (0);
13281357 #endif
13291358 #endif
13301359
0 /* config.h.in. Generated from configure.in by autoheader. */
0 /* config.h.in. Generated from configure.ac by autoheader. */
11
22 /* Enable GIF images */
33 #undef ENABLE_GIF
00 #! /bin/sh
11 # Configuration validation subroutine script.
22 # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
4 # Free Software Foundation, Inc.
5
6 timestamp='2009-11-20'
3 # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
4 # 2011, 2012 Free Software Foundation, Inc.
5
6 timestamp='2012-04-18'
77
88 # This file is (in principle) common to ALL GNU software.
99 # The presence of a machine in this file suggests that SOME GNU software
2020 # GNU General Public License for more details.
2121 #
2222 # You should have received a copy of the GNU General Public License
23 # along with this program; if not, write to the Free Software
24 # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
25 # 02110-1301, USA.
23 # along with this program; if not, see <http://www.gnu.org/licenses/>.
2624 #
2725 # As a special exception to the GNU General Public License, if you
2826 # distribute this file as part of a program that contains a
7472 version="\
7573 GNU config.sub ($timestamp)
7674
77 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
78 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
75 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
76 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
77 Free Software Foundation, Inc.
7978
8079 This is free software; see the source for copying conditions. There is NO
8180 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
122121 # Here we must recognize all the valid KERNEL-OS combinations.
123122 maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
124123 case $maybe_os in
125 nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
126 uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
124 nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
125 linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
126 knetbsd*-gnu* | netbsd*-gnu* | \
127127 kopensolaris*-gnu* | \
128128 storm-chaos* | os2-emx* | rtmk-nova*)
129129 os=-$maybe_os
130130 basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
131 ;;
132 android-linux)
133 os=-linux-android
134 basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
131135 ;;
132136 *)
133137 basic_machine=`echo $1 | sed 's/-[^-]*$//'`
155159 os=
156160 basic_machine=$1
157161 ;;
158 -bluegene*)
159 os=-cnk
162 -bluegene*)
163 os=-cnk
160164 ;;
161165 -sim | -cisco | -oki | -wec | -winbond)
162166 os=
172176 os=-chorusos
173177 basic_machine=$1
174178 ;;
175 -chorusrdb)
176 os=-chorusrdb
179 -chorusrdb)
180 os=-chorusrdb
177181 basic_machine=$1
178 ;;
182 ;;
179183 -hiux*)
180184 os=-hiuxwe2
181185 ;;
219223 ;;
220224 -isc*)
221225 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
226 ;;
227 -lynx*178)
228 os=-lynxos178
229 ;;
230 -lynx*5)
231 os=-lynxos5
222232 ;;
223233 -lynx*)
224234 os=-lynxos
244254 # Some are omitted here because they have special meanings below.
245255 1750a | 580 \
246256 | a29k \
257 | aarch64 | aarch64_be \
247258 | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
248259 | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
249260 | am33_2.0 \
250261 | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
262 | be32 | be64 \
251263 | bfin \
252264 | c4x | clipper \
253265 | d10v | d30v | dlx | dsp16xx \
266 | epiphany \
254267 | fido | fr30 | frv \
255268 | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
269 | hexagon \
256270 | i370 | i860 | i960 | ia64 \
257271 | ip2k | iq2000 \
272 | le32 | le64 \
258273 | lm32 \
259274 | m32c | m32r | m32rle | m68000 | m68k | m88k \
260275 | maxq | mb | microblaze | mcore | mep | metag \
280295 | moxie \
281296 | mt \
282297 | msp430 \
298 | nds32 | nds32le | nds32be \
283299 | nios | nios2 \
284300 | ns16k | ns32k \
301 | open8 \
285302 | or32 \
286303 | pdp10 | pdp11 | pj | pjl \
287 | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
304 | powerpc | powerpc64 | powerpc64le | powerpcle \
288305 | pyramid \
289 | rx \
306 | rl78 | rx \
290307 | score \
291308 | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
292309 | sh64 | sh64le \
293310 | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
294311 | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
295 | spu | strongarm \
296 | tahoe | thumb | tic4x | tic80 | tron \
312 | spu \
313 | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
297314 | ubicom32 \
298 | v850 | v850e \
315 | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
299316 | we32k \
300 | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
317 | x86 | xc16x | xstormy16 | xtensa \
301318 | z8k | z80)
302319 basic_machine=$basic_machine-unknown
303320 ;;
304 m6811 | m68hc11 | m6812 | m68hc12 | picochip)
305 # Motorola 68HC11/12.
321 c54x)
322 basic_machine=tic54x-unknown
323 ;;
324 c55x)
325 basic_machine=tic55x-unknown
326 ;;
327 c6x)
328 basic_machine=tic6x-unknown
329 ;;
330 m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
306331 basic_machine=$basic_machine-unknown
307332 os=-none
308333 ;;
310335 ;;
311336 ms1)
312337 basic_machine=mt-unknown
338 ;;
339
340 strongarm | thumb | xscale)
341 basic_machine=arm-unknown
342 ;;
343 xgate)
344 basic_machine=$basic_machine-unknown
345 os=-none
346 ;;
347 xscaleeb)
348 basic_machine=armeb-unknown
349 ;;
350
351 xscaleel)
352 basic_machine=armel-unknown
313353 ;;
314354
315355 # We use `pc' rather than `unknown'
326366 # Recognize the basic CPU types with company name.
327367 580-* \
328368 | a29k-* \
369 | aarch64-* | aarch64_be-* \
329370 | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
330371 | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
331372 | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
332373 | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
333374 | avr-* | avr32-* \
375 | be32-* | be64-* \
334376 | bfin-* | bs2000-* \
335 | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
377 | c[123]* | c30-* | [cjt]90-* | c4x-* \
336378 | clipper-* | craynv-* | cydra-* \
337379 | d10v-* | d30v-* | dlx-* \
338380 | elxsi-* \
339381 | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
340382 | h8300-* | h8500-* \
341383 | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
384 | hexagon-* \
342385 | i*86-* | i860-* | i960-* | ia64-* \
343386 | ip2k-* | iq2000-* \
387 | le32-* | le64-* \
344388 | lm32-* \
345389 | m32c-* | m32r-* | m32rle-* \
346390 | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
366410 | mmix-* \
367411 | mt-* \
368412 | msp430-* \
413 | nds32-* | nds32le-* | nds32be-* \
369414 | nios-* | nios2-* \
370415 | none-* | np1-* | ns16k-* | ns32k-* \
416 | open8-* \
371417 | orion-* \
372418 | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
373 | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
419 | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
374420 | pyramid-* \
375 | romp-* | rs6000-* | rx-* \
421 | rl78-* | romp-* | rs6000-* | rx-* \
376422 | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
377423 | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
378424 | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
379425 | sparclite-* \
380 | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
381 | tahoe-* | thumb-* \
382 | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \
426 | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
427 | tahoe-* \
428 | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
429 | tile*-* \
383430 | tron-* \
384431 | ubicom32-* \
385 | v850-* | v850e-* | vax-* \
432 | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
433 | vax-* \
386434 | we32k-* \
387 | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
435 | x86-* | x86_64-* | xc16x-* | xps100-* \
388436 | xstormy16-* | xtensa*-* \
389437 | ymp-* \
390438 | z8k-* | z80-*)
409457 basic_machine=a29k-amd
410458 os=-udi
411459 ;;
412 abacus)
460 abacus)
413461 basic_machine=abacus-unknown
414462 ;;
415463 adobe68k)
479527 basic_machine=powerpc-ibm
480528 os=-cnk
481529 ;;
530 c54x-*)
531 basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
532 ;;
533 c55x-*)
534 basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
535 ;;
536 c6x-*)
537 basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
538 ;;
482539 c90)
483540 basic_machine=c90-cray
484541 os=-unicos
485542 ;;
486 cegcc)
543 cegcc)
487544 basic_machine=arm-unknown
488545 os=-cegcc
489546 ;;
515572 basic_machine=craynv-cray
516573 os=-unicosmp
517574 ;;
518 cr16)
575 cr16 | cr16-*)
519576 basic_machine=cr16-unknown
520577 os=-elf
521578 ;;
673730 i370-ibm* | ibm*)
674731 basic_machine=i370-ibm
675732 ;;
676 # I'm not sure what "Sysv32" means. Should this be sysv3.2?
677733 i*86v32)
678734 basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
679735 os=-sysv32
731787 basic_machine=ns32k-utek
732788 os=-sysv
733789 ;;
734 microblaze)
790 microblaze)
735791 basic_machine=microblaze-xilinx
736792 ;;
737793 mingw32)
770826 ms1-*)
771827 basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
772828 ;;
829 msys)
830 basic_machine=i386-pc
831 os=-msys
832 ;;
773833 mvs)
774834 basic_machine=i370-ibm
775835 os=-mvs
836 ;;
837 nacl)
838 basic_machine=le32-unknown
839 os=-nacl
776840 ;;
777841 ncr3000)
778842 basic_machine=i486-ncr
838902 np1)
839903 basic_machine=np1-gould
840904 ;;
905 neo-tandem)
906 basic_machine=neo-tandem
907 ;;
908 nse-tandem)
909 basic_machine=nse-tandem
910 ;;
841911 nsr-tandem)
842912 basic_machine=nsr-tandem
843913 ;;
920990 ;;
921991 power) basic_machine=power-ibm
922992 ;;
923 ppc) basic_machine=powerpc-unknown
924 ;;
925 ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
993 ppc | ppcbe) basic_machine=powerpc-unknown
994 ;;
995 ppc-* | ppcbe-*)
996 basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
926997 ;;
927998 ppcle | powerpclittle | ppc-le | powerpc-little)
928999 basic_machine=powerpcle-unknown
10161087 basic_machine=i860-stratus
10171088 os=-sysv4
10181089 ;;
1090 strongarm-* | thumb-*)
1091 basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
1092 ;;
10191093 sun2)
10201094 basic_machine=m68000-sun
10211095 ;;
10721146 basic_machine=t90-cray
10731147 os=-unicos
10741148 ;;
1075 tic54x | c54x*)
1076 basic_machine=tic54x-unknown
1077 os=-coff
1078 ;;
1079 tic55x | c55x*)
1080 basic_machine=tic55x-unknown
1081 os=-coff
1082 ;;
1083 tic6x | c6x*)
1084 basic_machine=tic6x-unknown
1085 os=-coff
1086 ;;
10871149 tile*)
1088 basic_machine=tile-unknown
1150 basic_machine=$basic_machine-unknown
10891151 os=-linux-gnu
10901152 ;;
10911153 tx39)
11541216 ;;
11551217 xps | xps100)
11561218 basic_machine=xps100-honeywell
1219 ;;
1220 xscale-* | xscalee[bl]-*)
1221 basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
11571222 ;;
11581223 ymp)
11591224 basic_machine=ymp-cray
12521317 if [ x"$os" != x"" ]
12531318 then
12541319 case $os in
1255 # First match some system type aliases
1256 # that might get confused with valid system types.
1320 # First match some system type aliases
1321 # that might get confused with valid system types.
12571322 # -solaris* is a basic system type, with this one exception.
1258 -auroraux)
1259 os=-auroraux
1323 -auroraux)
1324 os=-auroraux
12601325 ;;
12611326 -solaris1 | -solaris1.*)
12621327 os=`echo $os | sed -e 's|solaris1|sunos4|'`
12921357 | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
12931358 | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
12941359 | -chorusos* | -chorusrdb* | -cegcc* \
1295 | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
1296 | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
1360 | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
1361 | -mingw32* | -linux-gnu* | -linux-android* \
1362 | -linux-newlib* | -linux-uclibc* \
12971363 | -uxpv* | -beos* | -mpeix* | -udk* \
12981364 | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
12991365 | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
13401406 -opened*)
13411407 os=-openedition
13421408 ;;
1343 -os400*)
1409 -os400*)
13441410 os=-os400
13451411 ;;
13461412 -wince*)
13891455 -sinix*)
13901456 os=-sysv4
13911457 ;;
1392 -tpf*)
1458 -tpf*)
13931459 os=-tpf
13941460 ;;
13951461 -triton*)
14331499 ;;
14341500 -dicos*)
14351501 os=-dicos
1502 ;;
1503 -nacl*)
14361504 ;;
14371505 -none)
14381506 ;;
14561524 # system, and we'll never get to this point.
14571525
14581526 case $basic_machine in
1459 score-*)
1527 score-*)
14601528 os=-elf
14611529 ;;
1462 spu-*)
1530 spu-*)
14631531 os=-elf
14641532 ;;
14651533 *-acorn)
14711539 arm*-semi)
14721540 os=-aout
14731541 ;;
1474 c4x-* | tic4x-*)
1475 os=-coff
1542 c4x-* | tic4x-*)
1543 os=-coff
1544 ;;
1545 hexagon-*)
1546 os=-elf
1547 ;;
1548 tic54x-*)
1549 os=-coff
1550 ;;
1551 tic55x-*)
1552 os=-coff
1553 ;;
1554 tic6x-*)
1555 os=-coff
14761556 ;;
14771557 # This must come before the *-dec entry.
14781558 pdp10-*)
14921572 ;;
14931573 m68000-sun)
14941574 os=-sunos3
1495 # This also exists in the configure program, but was not the
1496 # default.
1497 # os=-sunos4
14981575 ;;
14991576 m68*-cisco)
15001577 os=-aout
15011578 ;;
1502 mep-*)
1579 mep-*)
15031580 os=-elf
15041581 ;;
15051582 mips*-cisco)
15261603 *-ibm)
15271604 os=-aix
15281605 ;;
1529 *-knuth)
1606 *-knuth)
15301607 os=-mmixware
15311608 ;;
15321609 *-wec)
00 #! /bin/sh
11 # Guess values for system-dependent variables and create Makefiles.
2 # Generated by GNU Autoconf 2.68 for dillo 3.0.2.
2 # Generated by GNU Autoconf 2.69 for dillo 3.0.3.
33 #
44 #
5 # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
6 # 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
7 # Foundation, Inc.
5 # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
86 #
97 #
108 # This configure script is free software; the Free Software Foundation
133131 # CDPATH.
134132 (unset CDPATH) >/dev/null 2>&1 && unset CDPATH
135133
134 # Use a proper internal environment variable to ensure we don't fall
135 # into an infinite loop, continuously re-executing ourselves.
136 if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
137 _as_can_reexec=no; export _as_can_reexec;
138 # We cannot yet assume a decent shell, so we have to provide a
139 # neutralization value for shells without unset; and this also
140 # works around shells that cannot unset nonexistent variables.
141 # Preserve -v and -x to the replacement shell.
142 BASH_ENV=/dev/null
143 ENV=/dev/null
144 (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
145 case $- in # ((((
146 *v*x* | *x*v* ) as_opts=-vx ;;
147 *v* ) as_opts=-v ;;
148 *x* ) as_opts=-x ;;
149 * ) as_opts= ;;
150 esac
151 exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
152 # Admittedly, this is quite paranoid, since all the known shells bail
153 # out after a failed `exec'.
154 $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
155 as_fn_exit 255
156 fi
157 # We don't want this to propagate to other subprocesses.
158 { _as_can_reexec=; unset _as_can_reexec;}
136159 if test "x$CONFIG_SHELL" = x; then
137160 as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
138161 emulate sh
166189 else
167190 exitcode=1; echo positional parameters were not saved.
168191 fi
169 test x\$exitcode = x0 || exit 1"
192 test x\$exitcode = x0 || exit 1
193 test -x / || exit 1"
170194 as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
171195 as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
172196 eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
211235
212236
213237 if test "x$CONFIG_SHELL" != x; then :
214 # We cannot yet assume a decent shell, so we have to provide a
215 # neutralization value for shells without unset; and this also
216 # works around shells that cannot unset nonexistent variables.
217 # Preserve -v and -x to the replacement shell.
218 BASH_ENV=/dev/null
219 ENV=/dev/null
220 (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
221 export CONFIG_SHELL
222 case $- in # ((((
223 *v*x* | *x*v* ) as_opts=-vx ;;
224 *v* ) as_opts=-v ;;
225 *x* ) as_opts=-x ;;
226 * ) as_opts= ;;
227 esac
228 exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"}
238 export CONFIG_SHELL
239 # We cannot yet assume a decent shell, so we have to provide a
240 # neutralization value for shells without unset; and this also
241 # works around shells that cannot unset nonexistent variables.
242 # Preserve -v and -x to the replacement shell.
243 BASH_ENV=/dev/null
244 ENV=/dev/null
245 (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
246 case $- in # ((((
247 *v*x* | *x*v* ) as_opts=-vx ;;
248 *v* ) as_opts=-v ;;
249 *x* ) as_opts=-x ;;
250 * ) as_opts= ;;
251 esac
252 exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
253 # Admittedly, this is quite paranoid, since all the known shells bail
254 # out after a failed `exec'.
255 $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
256 exit 255
229257 fi
230258
231259 if test x$as_have_required = xno; then :
327355
328356
329357 } # as_fn_mkdir_p
358
359 # as_fn_executable_p FILE
360 # -----------------------
361 # Test if FILE is an executable regular file.
362 as_fn_executable_p ()
363 {
364 test -f "$1" && test -x "$1"
365 } # as_fn_executable_p
330366 # as_fn_append VAR VALUE
331367 # ----------------------
332368 # Append the text in VALUE to the end of the definition contained in VAR. Take
448484 chmod +x "$as_me.lineno" ||
449485 { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
450486
487 # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
488 # already done that, so ensure we don't try to do so again and fall
489 # in an infinite loop. This has already happened in practice.
490 _as_can_reexec=no; export _as_can_reexec
451491 # Don't try to exec as it changes $[0], causing all sort of problems
452492 # (the dirname of $[0] is not the place where we might find the
453493 # original and so on. Autoconf is especially sensitive to this).
482522 # ... but there are two gotchas:
483523 # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
484524 # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
485 # In both cases, we have to default to `cp -p'.
525 # In both cases, we have to default to `cp -pR'.
486526 ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
487 as_ln_s='cp -p'
527 as_ln_s='cp -pR'
488528 elif ln conf$$.file conf$$ 2>/dev/null; then
489529 as_ln_s=ln
490530 else
491 as_ln_s='cp -p'
531 as_ln_s='cp -pR'
492532 fi
493533 else
494 as_ln_s='cp -p'
534 as_ln_s='cp -pR'
495535 fi
496536 rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
497537 rmdir conf$$.dir 2>/dev/null
503543 as_mkdir_p=false
504544 fi
505545
506 if test -x / >/dev/null 2>&1; then
507 as_test_x='test -x'
508 else
509 if ls -dL / >/dev/null 2>&1; then
510 as_ls_L_option=L
511 else
512 as_ls_L_option=
513 fi
514 as_test_x='
515 eval sh -c '\''
516 if test -d "$1"; then
517 test -d "$1/.";
518 else
519 case $1 in #(
520 -*)set "./$1";;
521 esac;
522 case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
523 ???[sx]*):;;*)false;;esac;fi
524 '\'' sh
525 '
526 fi
527 as_executable_p=$as_test_x
546 as_test_x='test -x'
547 as_executable_p=as_fn_executable_p
528548
529549 # Sed expression to map a string onto a valid CPP name.
530550 as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
556576 # Identity of this package.
557577 PACKAGE_NAME='dillo'
558578 PACKAGE_TARNAME='dillo'
559 PACKAGE_VERSION='3.0.2'
560 PACKAGE_STRING='dillo 3.0.2'
579 PACKAGE_VERSION='3.0.3'
580 PACKAGE_STRING='dillo 3.0.3'
561581 PACKAGE_BUGREPORT=''
562582 PACKAGE_URL=''
563583
628648 am__fastdepCC_FALSE
629649 am__fastdepCC_TRUE
630650 CCDEPMODE
651 am__nodep
631652 AMDEPBACKSLASH
632653 AMDEP_FALSE
633654 AMDEP_TRUE
11991220 if test "x$host_alias" != x; then
12001221 if test "x$build_alias" = x; then
12011222 cross_compiling=maybe
1202 $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host.
1203 If a cross compiler is detected then cross compile mode will be used" >&2
12041223 elif test "x$build_alias" != "x$host_alias"; then
12051224 cross_compiling=yes
12061225 fi
12861305 # Omit some internal or obsolete options to make the list less imposing.
12871306 # This message is too long to be a string in the A/UX 3.1 sh.
12881307 cat <<_ACEOF
1289 \`configure' configures dillo 3.0.2 to adapt to many kinds of systems.
1308 \`configure' configures dillo 3.0.3 to adapt to many kinds of systems.
12901309
12911310 Usage: $0 [OPTION]... [VAR=VALUE]...
12921311
13571376
13581377 if test -n "$ac_init_help"; then
13591378 case $ac_init_help in
1360 short | recursive ) echo "Configuration of dillo 3.0.2:";;
1379 short | recursive ) echo "Configuration of dillo 3.0.3:";;
13611380 esac
13621381 cat <<\_ACEOF
13631382
14631482 test -n "$ac_init_help" && exit $ac_status
14641483 if $ac_init_version; then
14651484 cat <<\_ACEOF
1466 dillo configure 3.0.2
1467 generated by GNU Autoconf 2.68
1468
1469 Copyright (C) 2010 Free Software Foundation, Inc.
1485 dillo configure 3.0.3
1486 generated by GNU Autoconf 2.69
1487
1488 Copyright (C) 2012 Free Software Foundation, Inc.
14701489 This configure script is free software; the Free Software Foundation
14711490 gives unlimited permission to copy, distribute and modify it.
14721491 _ACEOF
16491668 main ()
16501669 {
16511670 static int test_array [1 - 2 * !(($2) >= 0)];
1652 test_array [0] = 0
1671 test_array [0] = 0;
1672 return test_array [0];
16531673
16541674 ;
16551675 return 0;
16651685 main ()
16661686 {
16671687 static int test_array [1 - 2 * !(($2) <= $ac_mid)];
1668 test_array [0] = 0
1688 test_array [0] = 0;
1689 return test_array [0];
16691690
16701691 ;
16711692 return 0;
16911712 main ()
16921713 {
16931714 static int test_array [1 - 2 * !(($2) < 0)];
1694 test_array [0] = 0
1715 test_array [0] = 0;
1716 return test_array [0];
16951717
16961718 ;
16971719 return 0;
17071729 main ()
17081730 {
17091731 static int test_array [1 - 2 * !(($2) >= $ac_mid)];
1710 test_array [0] = 0
1732 test_array [0] = 0;
1733 return test_array [0];
17111734
17121735 ;
17131736 return 0;
17411764 main ()
17421765 {
17431766 static int test_array [1 - 2 * !(($2) <= $ac_mid)];
1744 test_array [0] = 0
1767 test_array [0] = 0;
1768 return test_array [0];
17451769
17461770 ;
17471771 return 0;
18661890 main ()
18671891 {
18681892 static int test_array [1 - 2 * !(0 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1))];
1869 test_array [0] = 0
1893 test_array [0] = 0;
1894 return test_array [0];
18701895
18711896 ;
18721897 return 0;
18821907 {
18831908 static int test_array [1 - 2 * !(($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1)
18841909 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 2))];
1885 test_array [0] = 0
1910 test_array [0] = 0;
1911 return test_array [0];
18861912
18871913 ;
18881914 return 0;
19391965 main ()
19401966 {
19411967 static int test_array [1 - 2 * !((($ac_type) -1 >> ($2 / 2 - 1)) >> ($2 / 2 - 1) == 3)];
1942 test_array [0] = 0
1968 test_array [0] = 0;
1969 return test_array [0];
19431970
19441971 ;
19451972 return 0;
19952022 test ! -s conftest.err
19962023 } && test -s conftest$ac_exeext && {
19972024 test "$cross_compiling" = yes ||
1998 $as_test_x conftest$ac_exeext
2025 test -x conftest$ac_exeext
19992026 }; then :
20002027 ac_retval=0
20012028 else
21712198 This file contains any messages produced by compilers while
21722199 running configure, to aid debugging if configure makes a mistake.
21732200
2174 It was created by dillo $as_me 3.0.2, which was
2175 generated by GNU Autoconf 2.68. Invocation command line was
2201 It was created by dillo $as_me 3.0.3, which was
2202 generated by GNU Autoconf 2.69. Invocation command line was
21762203
21772204 $ $0 $@
21782205
26992726 # by default.
27002727 for ac_prog in ginstall scoinst install; do
27012728 for ac_exec_ext in '' $ac_executable_extensions; do
2702 if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
2729 if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
27032730 if test $ac_prog = install &&
27042731 grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
27052732 # AIX install. It has an incompatible calling convention.
28682895 IFS=$as_save_IFS
28692896 test -z "$as_dir" && as_dir=.
28702897 for ac_exec_ext in '' $ac_executable_extensions; do
2871 if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
2898 if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
28722899 ac_cv_prog_STRIP="${ac_tool_prefix}strip"
28732900 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
28742901 break 2
29082935 IFS=$as_save_IFS
29092936 test -z "$as_dir" && as_dir=.
29102937 for ac_exec_ext in '' $ac_executable_extensions; do
2911 if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
2938 if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
29122939 ac_cv_prog_ac_ct_STRIP="strip"
29132940 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
29142941 break 2
29592986 test -z "$as_dir" && as_dir=.
29602987 for ac_prog in mkdir gmkdir; do
29612988 for ac_exec_ext in '' $ac_executable_extensions; do
2962 { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue
2989 as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue
29632990 case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
29642991 'mkdir (GNU coreutils) '* | \
29652992 'mkdir (coreutils) '* | \
30123039 IFS=$as_save_IFS
30133040 test -z "$as_dir" && as_dir=.
30143041 for ac_exec_ext in '' $ac_executable_extensions; do
3015 if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
3042 if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
30163043 ac_cv_prog_AWK="$ac_prog"
30173044 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
30183045 break 2
30983125
30993126 # Define the identity of the package.
31003127 PACKAGE='dillo'
3101 VERSION='3.0.2'
3128 VERSION='3.0.3'
31023129
31033130
31043131 cat >>confdefs.h <<_ACEOF
31283155
31293156 # We need awk for the "check" target. The system "awk" is bad on
31303157 # some platforms.
3131 # Always define AMTAR for backward compatibility.
3132
3133 AMTAR=${AMTAR-"${am_missing_run}tar"}
3134
3135 am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
3158 # Always define AMTAR for backward compatibility. Yes, it's still used
3159 # in the wild :-( We should find a proper way to deprecate it ...
3160 AMTAR='$${TAR-tar}'
3161
3162 am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
31363163
31373164
31383165
32533280 IFS=$as_save_IFS
32543281 test -z "$as_dir" && as_dir=.
32553282 for ac_exec_ext in '' $ac_executable_extensions; do
3256 if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
3283 if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
32573284 ac_cv_prog_CC="${ac_tool_prefix}gcc"
32583285 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
32593286 break 2
32933320 IFS=$as_save_IFS
32943321 test -z "$as_dir" && as_dir=.
32953322 for ac_exec_ext in '' $ac_executable_extensions; do
3296 if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
3323 if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
32973324 ac_cv_prog_ac_ct_CC="gcc"
32983325 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
32993326 break 2
33463373 IFS=$as_save_IFS
33473374 test -z "$as_dir" && as_dir=.
33483375 for ac_exec_ext in '' $ac_executable_extensions; do
3349 if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
3376 if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
33503377 ac_cv_prog_CC="${ac_tool_prefix}cc"
33513378 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
33523379 break 2
33873414 IFS=$as_save_IFS
33883415 test -z "$as_dir" && as_dir=.
33893416 for ac_exec_ext in '' $ac_executable_extensions; do
3390 if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
3417 if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
33913418 if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
33923419 ac_prog_rejected=yes
33933420 continue
34453472 IFS=$as_save_IFS
34463473 test -z "$as_dir" && as_dir=.
34473474 for ac_exec_ext in '' $ac_executable_extensions; do
3448 if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
3475 if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
34493476 ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
34503477 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
34513478 break 2
34893516 IFS=$as_save_IFS
34903517 test -z "$as_dir" && as_dir=.
34913518 for ac_exec_ext in '' $ac_executable_extensions; do
3492 if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
3519 if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
34933520 ac_cv_prog_ac_ct_CC="$ac_prog"
34943521 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
34953522 break 2
39353962 /* end confdefs.h. */
39363963 #include <stdarg.h>
39373964 #include <stdio.h>
3938 #include <sys/types.h>
3939 #include <sys/stat.h>
3965 struct stat;
39403966 /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
39413967 struct buf { int x; };
39423968 FILE * (*rcsopen) (struct buf *, struct stat *, int);
40724098 if test "x$enable_dependency_tracking" != xno; then
40734099 am_depcomp="$ac_aux_dir/depcomp"
40744100 AMDEPBACKSLASH='\'
4101 am__nodep='_no'
40754102 fi
40764103 if test "x$enable_dependency_tracking" != xno; then
40774104 AMDEP_TRUE=
40964123 # instance it was reported that on HP-UX the gcc test will end up
40974124 # making a dummy file named `D' -- because `-MD' means `put the output
40984125 # in D'.
4126 rm -rf conftest.dir
40994127 mkdir conftest.dir
41004128 # Copy depcomp to subdir because otherwise we won't find it if we're
41014129 # using a relative directory.
41554183 break
41564184 fi
41574185 ;;
4158 msvisualcpp | msvcmsys)
4186 msvc7 | msvc7msys | msvisualcpp | msvcmsys)
41594187 # This compiler won't grok `-c -o', but also, the minuso test has
41604188 # not run yet. These depmodes are late enough in the game, and
41614189 # so weak that their functioning should not be impacted.
42384266 IFS=$as_save_IFS
42394267 test -z "$as_dir" && as_dir=.
42404268 for ac_exec_ext in '' $ac_executable_extensions; do
4241 if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
4269 if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
42424270 ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
42434271 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
42444272 break 2
42824310 IFS=$as_save_IFS
42834311 test -z "$as_dir" && as_dir=.
42844312 for ac_exec_ext in '' $ac_executable_extensions; do
4285 if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
4313 if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
42864314 ac_cv_prog_ac_ct_CXX="$ac_prog"
42874315 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
42884316 break 2
44804508 # instance it was reported that on HP-UX the gcc test will end up
44814509 # making a dummy file named `D' -- because `-MD' means `put the output
44824510 # in D'.
4511 rm -rf conftest.dir
44834512 mkdir conftest.dir
44844513 # Copy depcomp to subdir because otherwise we won't find it if we're
44854514 # using a relative directory.
45394568 break
45404569 fi
45414570 ;;
4542 msvisualcpp | msvcmsys)
4571 msvc7 | msvc7msys | msvisualcpp | msvcmsys)
45434572 # This compiler won't grok `-c -o', but also, the minuso test has
45444573 # not run yet. These depmodes are late enough in the game, and
45454574 # so weak that their functioning should not be impacted.
46114640 IFS=$as_save_IFS
46124641 test -z "$as_dir" && as_dir=.
46134642 for ac_exec_ext in '' $ac_executable_extensions; do
4614 if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
4643 if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
46154644 ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
46164645 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
46174646 break 2
46514680 IFS=$as_save_IFS
46524681 test -z "$as_dir" && as_dir=.
46534682 for ac_exec_ext in '' $ac_executable_extensions; do
4654 if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
4683 if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
46554684 ac_cv_prog_ac_ct_RANLIB="ranlib"
46564685 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
46574686 break 2
48424871 for ac_prog in grep ggrep; do
48434872 for ac_exec_ext in '' $ac_executable_extensions; do
48444873 ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
4845 { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
4874 as_fn_executable_p "$ac_path_GREP" || continue
48464875 # Check for GNU ac_path_GREP and select it if it is found.
48474876 # Check for GNU $ac_path_GREP
48484877 case `"$ac_path_GREP" --version 2>&1` in
49084937 for ac_prog in egrep; do
49094938 for ac_exec_ext in '' $ac_executable_extensions; do
49104939 ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
4911 { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
4940 as_fn_executable_p "$ac_path_EGREP" || continue
49124941 # Check for GNU ac_path_EGREP and select it if it is found.
49134942 # Check for GNU $ac_path_EGREP
49144943 case `"$ac_path_EGREP" --version 2>&1` in
57165745 $as_echo_n "checking for libpng version... " >&6; }
57175746 png_version=`$PNG_CONFIG --version`
57185747 case $png_version in
5719 1.4.*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: $png_version (newer version)" >&5
5720 $as_echo "$png_version (newer version)" >&6; } ;;
5721 1.2.*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: $png_version (newer version)" >&5
5722 $as_echo "$png_version (newer version)" >&6; } ;;
5723 1.0.*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: $png_version (older version)" >&5
5724 $as_echo "$png_version (older version)" >&6; } ;;
5725 *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: ERROR" >&5
5726 $as_echo "ERROR" >&6; } ;;
5748 1.[024].*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: $png_version" >&5
5749 $as_echo "$png_version" >&6; } ;;
5750 *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: $png_version (unrecognised version)" >&5
5751 $as_echo "$png_version (unrecognised version)" >&6; } ;;
57275752 esac
57285753
57295754 LIBPNG_CFLAGS=`$PNG_CONFIG --cflags`
68726897 # ... but there are two gotchas:
68736898 # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
68746899 # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
6875 # In both cases, we have to default to `cp -p'.
6900 # In both cases, we have to default to `cp -pR'.
68766901 ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
6877 as_ln_s='cp -p'
6902 as_ln_s='cp -pR'
68786903 elif ln conf$$.file conf$$ 2>/dev/null; then
68796904 as_ln_s=ln
68806905 else
6881 as_ln_s='cp -p'
6906 as_ln_s='cp -pR'
68826907 fi
68836908 else
6884 as_ln_s='cp -p'
6909 as_ln_s='cp -pR'
68856910 fi
68866911 rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
68876912 rmdir conf$$.dir 2>/dev/null
69416966 as_mkdir_p=false
69426967 fi
69436968
6944 if test -x / >/dev/null 2>&1; then
6945 as_test_x='test -x'
6946 else
6947 if ls -dL / >/dev/null 2>&1; then
6948 as_ls_L_option=L
6949 else
6950 as_ls_L_option=
6951 fi
6952 as_test_x='
6953 eval sh -c '\''
6954 if test -d "$1"; then
6955 test -d "$1/.";
6956 else
6957 case $1 in #(
6958 -*)set "./$1";;
6959 esac;
6960 case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
6961 ???[sx]*):;;*)false;;esac;fi
6962 '\'' sh
6963 '
6964 fi
6965 as_executable_p=$as_test_x
6969
6970 # as_fn_executable_p FILE
6971 # -----------------------
6972 # Test if FILE is an executable regular file.
6973 as_fn_executable_p ()
6974 {
6975 test -f "$1" && test -x "$1"
6976 } # as_fn_executable_p
6977 as_test_x='test -x'
6978 as_executable_p=as_fn_executable_p
69666979
69676980 # Sed expression to map a string onto a valid CPP name.
69686981 as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
69836996 # report actual input values of CONFIG_FILES etc. instead of their
69846997 # values after options handling.
69856998 ac_log="
6986 This file was extended by dillo $as_me 3.0.2, which was
6987 generated by GNU Autoconf 2.68. Invocation command line was
6999 This file was extended by dillo $as_me 3.0.3, which was
7000 generated by GNU Autoconf 2.69. Invocation command line was
69887001
69897002 CONFIG_FILES = $CONFIG_FILES
69907003 CONFIG_HEADERS = $CONFIG_HEADERS
70497062 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
70507063 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
70517064 ac_cs_version="\\
7052 dillo config.status 3.0.2
7053 configured by $0, generated by GNU Autoconf 2.68,
7065 dillo config.status 3.0.3
7066 configured by $0, generated by GNU Autoconf 2.69,
70547067 with options \\"\$ac_cs_config\\"
70557068
7056 Copyright (C) 2010 Free Software Foundation, Inc.
7069 Copyright (C) 2012 Free Software Foundation, Inc.
70577070 This config.status script is free software; the Free Software Foundation
70587071 gives unlimited permission to copy, distribute and modify it."
70597072
71447157 _ACEOF
71457158 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
71467159 if \$ac_cs_recheck; then
7147 set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
7160 set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
71487161 shift
71497162 \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
71507163 CONFIG_SHELL='$SHELL'
0 dnl Process this file with aclocal, autoconf and automake.
1
2 AC_INIT([dillo], [3.0.3])
3
4 dnl Detect the canonical target build environment
5 AC_CANONICAL_TARGET
6
7 AM_INIT_AUTOMAKE
8 AC_CONFIG_SRCDIR([src/dillo.cc])
9 AC_CONFIG_HEADERS([config.h])
10
11 sysconfdir=${sysconfdir}/${PACKAGE}
12
13 dnl Options
14
15 AC_ARG_WITH(jpeg-lib, [ --with-jpeg-lib=DIR Specify where to find libjpeg], LIBJPEG_LIBDIR=$withval)
16 AC_ARG_WITH(jpeg-inc, [ --with-jpeg-inc=DIR Specify where to find libjpeg's headers], LIBJPEG_INCDIR=$withval)
17
18 AC_ARG_ENABLE(efence, [ --enable-efence Try to compile and run with Electric Fence],
19 , enable_efence=no)
20 AC_ARG_ENABLE(gprof, [ --enable-gprof Try to compile and run with profiling enabled],
21 , enable_gprof=no)
22 AC_ARG_ENABLE(insure, [ --enable-insure Try to compile and run with Insure++],
23 , enable_insure=no)
24 AC_ARG_ENABLE(ssl, [ --enable-ssl Enable ssl, https (ALPHA CODE)],
25 , enable_ssl=no)
26 AC_ARG_ENABLE(ipv6, [ --enable-ipv6 Build with support for IPv6], , )
27 AC_ARG_ENABLE(cookies,[ --disable-cookies Don't compile support for cookies],
28 , enable_cookies=yes)
29 AC_ARG_ENABLE(png, [ --disable-png Disable support for PNG images],
30 enable_png=$enableval, enable_png=yes)
31 AC_ARG_ENABLE(jpeg, [ --disable-jpeg Disable support for JPEG images],
32 enable_jpeg=$enableval, enable_jpeg=yes)
33 AC_ARG_ENABLE(gif, [ --disable-gif Disable support for GIF images],
34 enable_gif=$enableval, enable_gif=yes)
35 AC_ARG_ENABLE(threaded-dns,[ --disable-threaded-dns Disable the advantage of a reentrant resolver library],
36 enable_threaded_dns=$enableval, enable_threaded_dns=yes)
37 AC_ARG_ENABLE(rtfl, [ --enable-rtfl Build with rtfl messages (for debugging rendering)])
38 AC_PROG_CC
39 AC_PROG_CXX
40 AC_PROG_RANLIB
41 AC_PROG_CPP
42
43 dnl ----------------------------
44 dnl Check our char and int types
45 dnl ----------------------------
46 dnl
47 AC_CHECK_SIZEOF(char)
48 AC_CHECK_SIZEOF(short)
49 AC_CHECK_SIZEOF(long)
50 AC_CHECK_SIZEOF(int)
51 AC_CHECK_SIZEOF(void *)
52
53 AC_TYPE_INT16_T
54 AC_TYPE_UINT16_T
55 AC_TYPE_INT32_T
56 AC_TYPE_UINT32_T
57
58 dnl --------------------------------------
59 dnl Check whether to add /usr/local or not
60 dnl (this is somewhat a religious problem)
61 dnl --------------------------------------
62 dnl
63 if test "`$CPP -v < /dev/null 2>&1 | grep '/usr/local/include' 2>&1`" = ""; then
64 CPPFLAGS="$CPPFLAGS -I/usr/local/include"
65 LDFLAGS="$LDFLAGS -L/usr/local/lib"
66 fi
67
68 dnl ------------------------------------
69 dnl Check for socket libs (AIX, Solaris)
70 dnl ------------------------------------
71 dnl
72 AC_CHECK_FUNCS(gethostbyname,,
73 [AC_CHECK_LIB(nsl,gethostbyname,,[AC_CHECK_LIB(socket,gethostbyname)])])
74 AC_CHECK_FUNCS(setsockopt,,[AC_CHECK_LIB(socket,setsockopt)])
75
76 dnl --------------------
77 dnl Checks for socklen_t
78 dnl --------------------
79 dnl
80 AC_MSG_CHECKING([for socklen_t])
81 ac_cv_socklen_t=""
82 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
83 #include <sys/types.h>
84 #include <sys/socket.h>
85 ]],[[
86 socklen_t a=0;
87 getsockname(0,(struct sockaddr*)0, &a);
88 ]])],
89 ac_cv_socklen_t="socklen_t",
90 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
91 #include <sys/types.h>
92 #include <sys/socket.h>
93 ]],[[
94 int a=0;
95 getsockname(0,(struct sockaddr*)0, &a);
96 ]])],
97 ac_cv_socklen_t="int",
98 ac_cv_socklen_t="size_t"
99 )
100 )
101 AC_MSG_RESULT($ac_cv_socklen_t)
102 if test "$ac_cv_socklen_t" != "socklen_t"; then
103 AC_DEFINE_UNQUOTED([socklen_t], [$ac_cv_socklen_t],
104 [Define the real type of socklen_t])
105 fi
106
107
108 dnl ----------------------
109 dnl Test for FLTK 1.3 library
110 dnl ----------------------
111 dnl
112 dnl For debugging and to be user friendly
113 AC_MSG_CHECKING([FLTK 1.3])
114 fltk_version="`fltk-config --version 2>/dev/null`"
115 case $fltk_version in
116 1.3.*) AC_MSG_RESULT(yes)
117 LIBFLTK_CXXFLAGS=`fltk-config --cxxflags`
118 LIBFLTK_CFLAGS=`fltk-config --cflags`
119 LIBFLTK_LIBS=`fltk-config --ldflags`;;
120 ?*) AC_MSG_RESULT(no)
121 AC_MSG_ERROR(FLTK 1.3 required; version found: $fltk_version);;
122 *) AC_MSG_RESULT(no)
123 AC_MSG_ERROR(FLTK 1.3 required; fltk-config not found)
124 esac
125
126
127 dnl ----------------
128 dnl Test for libjpeg
129 dnl ----------------
130 dnl
131 if test "x$enable_jpeg" = "xyes"; then
132 AC_CHECK_HEADER(jpeglib.h, jpeg_ok=yes, jpeg_ok=no)
133
134 if test "x$jpeg_ok" = "xyes"; then
135 old_libs="$LIBS"
136 AC_CHECK_LIB(jpeg, jpeg_destroy_decompress, jpeg_ok=yes, jpeg_ok=no)
137 LIBS="$old_libs"
138 fi
139
140 if test "x$jpeg_ok" = "xyes"; then
141 LIBJPEG_LIBS="-ljpeg"
142 if test -n "$LIBJPEG_LIBDIR"; then
143 LIBJPEG_LDFLAGS="-L$LIBJPEG_LIBDIR"
144 fi
145 if test -n "$LIBJPEG_INCDIR"; then
146 LIBJPEG_CPPFLAGS="-I$LIBJPEG_INCDIR"
147 fi
148 else
149 AC_MSG_WARN([*** No libjpeg found. Disabling jpeg images.***])
150 fi
151 fi
152
153 if test "x$jpeg_ok" = "xyes"; then
154 AC_DEFINE([ENABLE_JPEG], [1], [Enable JPEG images])
155 fi
156
157 dnl -------------
158 dnl Test for zlib
159 dnl -------------
160 dnl
161 AC_CHECK_HEADER(zlib.h, libz_ok=yes, libz_ok=no)
162
163 if test "x$libz_ok" = "xyes"; then
164 old_libs="$LIBS"
165 AC_CHECK_LIB(z, zlibVersion, libz_ok=yes, libz_ok=no)
166 LIBS="$old_libs"
167 fi
168
169 if test "x$libz_ok" = xyes; then
170 LIBZ_LIBS="-lz"
171 else
172 AC_MSG_ERROR(zlib must be installed!)
173 fi
174
175 dnl ---------------
176 dnl Test for libpng
177 dnl ---------------
178 dnl
179 if test "x$enable_png" = "xyes"; then
180 AC_MSG_CHECKING([for libpng-config])
181
182 dnl Check if the user hasn't set the variable $PNG_CONFIG
183 if test -z "$PNG_CONFIG"; then
184 PNG_CONFIG=`which libpng14-config`
185 if test -z "$PNG_CONFIG"; then
186 PNG_CONFIG=`which libpng12-config`
187 fi
188 if test -z "$PNG_CONFIG"; then
189 PNG_CONFIG=`which libpng-config`
190 fi
191 if test -z "$PNG_CONFIG"; then
192 PNG_CONFIG=`which libpng10-config`
193 fi
194 fi
195
196 dnl Check if the libpng-config script was found and is executable
197 if test -n "$PNG_CONFIG" && test -x "$PNG_CONFIG"; then
198 AC_MSG_RESULT([$PNG_CONFIG])
199 png_ok="yes"
200 else
201 AC_MSG_RESULT([missing])
202 png_ok="no"
203 fi
204
205 if test "x$png_ok" = "xyes"; then
206 dnl For debugging and to be user friendly
207 AC_MSG_CHECKING([for libpng version])
208 png_version=`$PNG_CONFIG --version`
209 case $png_version in
210 1.[[024]].*) AC_MSG_RESULT([$png_version]) ;;
211 *) AC_MSG_RESULT([$png_version (unrecognised version)]) ;;
212 esac
213
214 dnl Try to use options that are supported by all libpng-config versions...
215 LIBPNG_CFLAGS=`$PNG_CONFIG --cflags`
216 LIBPNG_LIBS=`$PNG_CONFIG --ldflags`
217 case $png_version in
218 1.2.4*) LIBPNG_LIBS="$LIBPNG_LIBS `$PNG_CONFIG --libs`" ;;
219 esac
220 else
221 dnl Try to find libpng even though libpng-config wasn't found
222 AC_CHECK_HEADERS(png.h libpng/png.h, png_ok=yes && break, png_ok=no)
223
224 if test "x$png_ok" = "xyes"; then
225 old_libs="$LIBS"
226 AC_CHECK_LIB(png, png_sig_cmp, png_ok=yes, png_ok=no, $LIBZ_LIBS -lm)
227 LIBS="$old_libs"
228
229 if test "x$png_ok" = "xyes"; then
230 LIBPNG_LIBS="-lpng -lm"
231 fi
232 fi
233
234 if test "x$png_ok" = "xno"; then
235 AC_MSG_WARN([*** No libpng found. Disabling PNG images ***])
236 fi
237 fi
238 fi
239
240 if test "x$png_ok" = "xyes"; then
241 AC_DEFINE([ENABLE_PNG], [1], [Enable PNG images])
242 fi
243
244 dnl Check if support for GIF images should be compiled in
245 if test "x$enable_gif" = "xyes"; then
246 AC_DEFINE([ENABLE_GIF], [1], [Enable GIF images])
247 fi
248
249 dnl --------------------------
250 dnl Test for support for SSL
251 dnl --------------------------
252 dnl
253 if test "x$enable_ssl" = "xyes"; then
254 AC_CHECK_HEADER(openssl/ssl.h, ssl_ok=yes, ssl_ok=no)
255
256 if test "x$ssl_ok" = "xyes"; then
257 old_libs="$LIBS"
258 AC_CHECK_LIB(ssl, SSL_library_init, ssl_ok=yes, ssl_ok=no, -lcrypto)
259 LIBS="$old_libs"
260 fi
261
262 if test "x$ssl_ok" = "xyes"; then
263 LIBSSL_LIBS="-lcrypto -lssl"
264 AC_MSG_WARN([*** Enabling ssl support. THIS IS ALPHA CODE!***])
265 else
266 AC_MSG_WARN([*** No libssl found. Disabling ssl support.***])
267 fi
268 fi
269
270 if test "x$ssl_ok" = "xyes"; then
271 AC_DEFINE([ENABLE_SSL], [1], [Enable SSL support])
272 fi
273
274 dnl --------------------------------------------------------------
275 dnl Test for iconv functionality in libc or for libiconv usability
276 dnl --------------------------------------------------------------
277 AC_CHECK_HEADER(iconv.h, iconv_ok=yes, iconv_ok=no)
278 if test "x$iconv_ok" = "xyes"; then
279 AC_CHECK_LIB(c, iconv_open, LIBICONV_LIBS="",
280 AC_CHECK_LIB(iconv, iconv_open, LIBICONV_LIBS="-liconv", iconv_ok=no))
281 fi
282 if test "x$iconv_ok" = "xno"; then
283 dnl Test for OpenBSD
284 old_libs="$LIBS"
285 LIBS="$old_libs -liconv"
286 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
287 #include <iconv.h>
288 ]],[[
289 iconv_open("","");
290 ]])],
291 iconv_ok=yes,iconv_ok=no)
292 LIBS="$old_libs"
293 if test "x$iconv_ok" = "xyes"; then
294 LIBICONV_LIBS="-liconv"
295 fi
296 fi
297
298 if test "x$iconv_ok" = "xno"; then
299 AC_MSG_ERROR(libiconv must be installed!)
300 fi
301
302 dnl ----------------------
303 dnl Check if we need to
304 dnl support the old
305 dnl iconv interface
306 dnl ----------------------
307 if test "x$iconv_ok" = "xyes"; then
308 old_libs="$LIBS"
309 LIBS="$old_libs $LIBICONV_LIBS"
310 old_cflags="$CFLAGS"
311 CFLAGS="$CFLAGS -Werror"
312 AC_LANG_PUSH([C++])
313 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
314 #include <iconv.h>
315 ]],[[
316 const char *inPtr;
317 char *outPtr;
318 size_t inLeft = 0, outRoom = 0;
319 iconv_t encoder = iconv_open("ASCII", "UTF-8");
320 iconv(encoder, &inPtr, &inLeft, &outPtr, &outRoom);
321 ]])],
322 iconv_old=yes,iconv_old=no)
323 AC_LANG_POP([C++])
324 LIBS="$old_libs"
325 CFLAGS="$old_cflags"
326
327 if test "x$iconv_old" = "xyes"; then
328 AC_DEFINE([inbuf_t], [const char], [Use const char pointers for older libiconv])
329 else
330 AC_DEFINE([inbuf_t], [char], [Use char pointers for newer libiconv])
331 fi
332 fi
333
334 dnl ----------------------
335 dnl Test for POSIX threads
336 dnl ----------------------
337 dnl
338 if test -z "$LIBPTHREAD_LIBS"; then
339 case $target in
340 *-*-linux*|*-*-solaris*)
341 old_libs="$LIBS"
342 AC_CHECK_LIB(pthread, pthread_create, LIBPTHREAD_LIBS="-lpthread")
343 LIBS="$old_libs"
344 ;;
345
346 *-*-osf1*)
347 AC_MSG_CHECKING(whether pthreads work)
348 LIBPTHREAD_LIBS="-lpthread -lexc -ldb"
349 AC_MSG_WARN([*** _Untested pthreads_ try setting LIBPTHREAD_LIBS manually if it doesn't work ***])
350 ;;
351
352 *-*-minix*)
353 AC_MSG_NOTICE([Minix detected, skipping pthread detection])
354 ;;
355
356 *)
357 AC_MSG_CHECKING(whether threads work with -pthread)
358 LDSAVEFLAGS=$LDFLAGS
359 LDFLAGS="$LDFLAGS -pthread"
360 AC_LINK_IFELSE([AC_LANG_CALL([],[pthread_create])],
361 pthread_ok=yes, pthread_ok=no)
362 LDFLAGS=$LDSAVEFLAGS
363
364 if test "x$pthread_ok" = "xyes"; then
365 AC_MSG_RESULT(yes)
366 LIBPTHREAD_LDFLAGS="-pthread"
367 else
368 AC_MSG_RESULT(no. Now we will try some libraries.)
369
370 AC_SEARCH_LIBS(pthread_create, pthread,
371 LIBPTHREADS_LIBS="-lpthread",
372 AC_SEARCH_LIBS(pthread_create, pthreads,
373 LIBPTHREADS_LIBS="-lpthreads",
374 AC_SEARCH_LIBS(pthread_create, c_r,
375 LIBPTHREADS_LIBS="-lc_r", thread_ok=no)))
376
377 if test "x$thread_ok" = "xno"; then
378 AC_MSG_WARN([*** No pthreads found. ***])
379 AC_MSG_ERROR([*** Try setting LIBPTHREAD_LIBS manually to point to your pthreads library. ***])
380 exit 1
381 else
382 AC_MSG_WARN([found a way to link threads, but it may not work...])
383 fi
384 fi
385 ;;
386
387 esac
388 fi
389
390 dnl --------------------
391 dnl Command line options
392 dnl --------------------
393 dnl
394 if test "x$enable_cookies" = "xno" ; then
395 CFLAGS="$CFLAGS -DDISABLE_COOKIES"
396 CXXFLAGS="$CXXFLAGS -DDISABLE_COOKIES"
397 fi
398 if test "x$enable_ipv6" = "xyes" ; then
399 CFLAGS="$CFLAGS -DENABLE_IPV6"
400 fi
401 if test "x$enable_efence" = "xyes" ; then
402 LIBS="-lefence $LIBS"
403 fi
404 if test "x$enable_gprof" = "xyes" ; then
405 CFLAGS="$CFLAGS -pg"
406 CXXFLAGS="$CXXFLAGS -pg"
407 fi
408 if test "x$enable_insure" = "xyes" ; then
409 CC="insure -Zoi \"compiler $CC\""
410 LIBS="$LIBS -lstdc++-2-libc6.1-1-2.9.0"
411 fi
412 if test "x$enable_threaded_dns" = "xyes" ; then
413 CFLAGS="$CFLAGS -DD_DNS_THREADED"
414 fi
415 if test "x$enable_rtfl" = "xyes" ; then
416 CXXFLAGS="$CXXFLAGS -DDBG_RTFL"
417 fi
418
419 dnl -----------------------
420 dnl Checks for header files
421 dnl -----------------------
422 dnl
423 AC_CHECK_HEADERS(fcntl.h unistd.h sys/uio.h)
424
425 dnl --------------------------
426 dnl Check for compiler options
427 dnl --------------------------
428 dnl
429 if eval "test x$GCC = xyes"; then
430 if test "`echo $CFLAGS | grep '\-D_REENTRANT' 2> /dev/null`" = ""; then
431 CFLAGS="$CFLAGS -D_REENTRANT"
432 fi
433 if test "`echo $CFLAGS | grep '\-D_THREAD_SAFE' 2> /dev/null`" = ""; then
434 CFLAGS="$CFLAGS -D_THREAD_SAFE"
435 fi
436 if test "`echo $CFLAGS | grep '\-Wall' 2> /dev/null`" = ""; then
437 CFLAGS="$CFLAGS -Wall"
438 fi
439 if test "`echo $CFLAGS | grep -e '-W ' -e '-W$' 2> /dev/null`" = ""; then
440 CFLAGS="$CFLAGS -W"
441 fi
442 if test "`echo $CFLAGS | grep '\-Wno-unused-parameter' 2> /dev/null`" = ""; then
443 CFLAGS="$CFLAGS -Wno-unused-parameter"
444 fi
445 if test "`echo $CFLAGS | grep '\-Waggregate-return' 2> /dev/null`" = ""; then
446 CFLAGS="$CFLAGS -Waggregate-return"
447 fi
448 fi
449 dnl -----------
450 dnl CXX options
451 dnl -----------
452 dnl
453
454 if eval "test x$GCC = xyes"; then
455 CXXFLAGS="$CXXFLAGS -Wall -W -Wno-unused-parameter -fno-rtti -fno-exceptions"
456 fi
457
458 AC_SUBST(LIBJPEG_LIBS)
459 AC_SUBST(LIBJPEG_LDFLAGS)
460 AC_SUBST(LIBJPEG_CPPFLAGS)
461 AC_SUBST(LIBPNG_LIBS)
462 AC_SUBST(LIBPNG_CFLAGS)
463 AC_SUBST(LIBZ_LIBS)
464 AC_SUBST(LIBSSL_LIBS)
465 AC_SUBST(LIBPTHREAD_LIBS)
466 AC_SUBST(LIBPTHREAD_LDFLAGS)
467 AC_SUBST(LIBFLTK_CXXFLAGS)
468 AC_SUBST(LIBFLTK_CFLAGS)
469 AC_SUBST(LIBFLTK_LIBS)
470 AC_SUBST(LIBICONV_LIBS)
471 AC_SUBST(datadir)
472
473 AC_CONFIG_FILES([
474 Makefile
475 dlib/Makefile
476 dpip/Makefile
477 dpid/Makefile
478 dpi/Makefile
479 doc/Makefile
480 dw/Makefile
481 lout/Makefile
482 src/Makefile
483 src/IO/Makefile
484 test/Makefile
485 ])
486
487 AC_OUTPUT
+0
-490
configure.in less more
0 dnl Process this file with aclocal, autoconf and automake.
1
2 AC_INIT([dillo], [3.0.2])
3
4 dnl Detect the canonical target build environment
5 AC_CANONICAL_TARGET
6
7 AM_INIT_AUTOMAKE
8 AC_CONFIG_SRCDIR([src/dillo.cc])
9 AC_CONFIG_HEADERS([config.h])
10
11 sysconfdir=${sysconfdir}/${PACKAGE}
12
13 dnl Options
14
15 AC_ARG_WITH(jpeg-lib, [ --with-jpeg-lib=DIR Specify where to find libjpeg], LIBJPEG_LIBDIR=$withval)
16 AC_ARG_WITH(jpeg-inc, [ --with-jpeg-inc=DIR Specify where to find libjpeg's headers], LIBJPEG_INCDIR=$withval)
17
18 AC_ARG_ENABLE(efence, [ --enable-efence Try to compile and run with Electric Fence],
19 , enable_efence=no)
20 AC_ARG_ENABLE(gprof, [ --enable-gprof Try to compile and run with profiling enabled],
21 , enable_gprof=no)
22 AC_ARG_ENABLE(insure, [ --enable-insure Try to compile and run with Insure++],
23 , enable_insure=no)
24 AC_ARG_ENABLE(ssl, [ --enable-ssl Enable ssl, https (ALPHA CODE)],
25 , enable_ssl=no)
26 AC_ARG_ENABLE(ipv6, [ --enable-ipv6 Build with support for IPv6], , )
27 AC_ARG_ENABLE(cookies,[ --disable-cookies Don't compile support for cookies],
28 , enable_cookies=yes)
29 AC_ARG_ENABLE(png, [ --disable-png Disable support for PNG images],
30 enable_png=$enableval, enable_png=yes)
31 AC_ARG_ENABLE(jpeg, [ --disable-jpeg Disable support for JPEG images],
32 enable_jpeg=$enableval, enable_jpeg=yes)
33 AC_ARG_ENABLE(gif, [ --disable-gif Disable support for GIF images],
34 enable_gif=$enableval, enable_gif=yes)
35 AC_ARG_ENABLE(threaded-dns,[ --disable-threaded-dns Disable the advantage of a reentrant resolver library],
36 enable_threaded_dns=$enableval, enable_threaded_dns=yes)
37 AC_ARG_ENABLE(rtfl, [ --enable-rtfl Build with rtfl messages (for debugging rendering)])
38 AC_PROG_CC
39 AC_PROG_CXX
40 AC_PROG_RANLIB
41 AC_PROG_CPP
42
43 dnl ----------------------------
44 dnl Check our char and int types
45 dnl ----------------------------
46 dnl
47 AC_CHECK_SIZEOF(char)
48 AC_CHECK_SIZEOF(short)
49 AC_CHECK_SIZEOF(long)
50 AC_CHECK_SIZEOF(int)
51 AC_CHECK_SIZEOF(void *)
52
53 AC_TYPE_INT16_T
54 AC_TYPE_UINT16_T
55 AC_TYPE_INT32_T
56 AC_TYPE_UINT32_T
57
58 dnl --------------------------------------
59 dnl Check whether to add /usr/local or not
60 dnl (this is somewhat a religious problem)
61 dnl --------------------------------------
62 dnl
63 if test "`$CPP -v < /dev/null 2>&1 | grep '/usr/local/include' 2>&1`" = ""; then
64 CPPFLAGS="$CPPFLAGS -I/usr/local/include"
65 LDFLAGS="$LDFLAGS -L/usr/local/lib"
66 fi
67
68 dnl ------------------------------------
69 dnl Check for socket libs (AIX, Solaris)
70 dnl ------------------------------------
71 dnl
72 AC_CHECK_FUNCS(gethostbyname,,
73 [AC_CHECK_LIB(nsl,gethostbyname,,[AC_CHECK_LIB(socket,gethostbyname)])])
74 AC_CHECK_FUNCS(setsockopt,,[AC_CHECK_LIB(socket,setsockopt)])
75
76 dnl --------------------
77 dnl Checks for socklen_t
78 dnl --------------------
79 dnl
80 AC_MSG_CHECKING([for socklen_t])
81 ac_cv_socklen_t=""
82 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
83 #include <sys/types.h>
84 #include <sys/socket.h>
85 ]],[[
86 socklen_t a=0;
87 getsockname(0,(struct sockaddr*)0, &a);
88 ]])],
89 ac_cv_socklen_t="socklen_t",
90 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
91 #include <sys/types.h>
92 #include <sys/socket.h>
93 ]],[[
94 int a=0;
95 getsockname(0,(struct sockaddr*)0, &a);
96 ]])],
97 ac_cv_socklen_t="int",
98 ac_cv_socklen_t="size_t"
99 )
100 )
101 AC_MSG_RESULT($ac_cv_socklen_t)
102 if test "$ac_cv_socklen_t" != "socklen_t"; then
103 AC_DEFINE_UNQUOTED([socklen_t], [$ac_cv_socklen_t],
104 [Define the real type of socklen_t])
105 fi
106
107
108 dnl ----------------------
109 dnl Test for FLTK 1.3 library
110 dnl ----------------------
111 dnl
112 dnl For debugging and to be user friendly
113 AC_MSG_CHECKING([FLTK 1.3])
114 fltk_version="`fltk-config --version 2>/dev/null`"
115 case $fltk_version in
116 1.3.*) AC_MSG_RESULT(yes)
117 LIBFLTK_CXXFLAGS=`fltk-config --cxxflags`
118 LIBFLTK_CFLAGS=`fltk-config --cflags`
119 LIBFLTK_LIBS=`fltk-config --ldflags`;;
120 ?*) AC_MSG_RESULT(no)
121 AC_ERROR(FLTK 1.3 required; version found: $fltk_version);;
122 *) AC_MSG_RESULT(no)
123 AC_ERROR(FLTK 1.3 required; fltk-config not found)
124 esac
125
126
127 dnl ----------------
128 dnl Test for libjpeg
129 dnl ----------------
130 dnl
131 if test "x$enable_jpeg" = "xyes"; then
132 AC_CHECK_HEADER(jpeglib.h, jpeg_ok=yes, jpeg_ok=no)
133
134 if test "x$jpeg_ok" = "xyes"; then
135 old_libs="$LIBS"
136 AC_CHECK_LIB(jpeg, jpeg_destroy_decompress, jpeg_ok=yes, jpeg_ok=no)
137 LIBS="$old_libs"
138 fi
139
140 if test "x$jpeg_ok" = "xyes"; then
141 LIBJPEG_LIBS="-ljpeg"
142 if test -n "$LIBJPEG_LIBDIR"; then
143 LIBJPEG_LDFLAGS="-L$LIBJPEG_LIBDIR"
144 fi
145 if test -n "$LIBJPEG_INCDIR"; then
146 LIBJPEG_CPPFLAGS="-I$LIBJPEG_INCDIR"
147 fi
148 else
149 AC_MSG_WARN([*** No libjpeg found. Disabling jpeg images.***])
150 fi
151 fi
152
153 if test "x$jpeg_ok" = "xyes"; then
154 AC_DEFINE([ENABLE_JPEG], [1], [Enable JPEG images])
155 fi
156
157 dnl -------------
158 dnl Test for zlib
159 dnl -------------
160 dnl
161 AC_CHECK_HEADER(zlib.h, libz_ok=yes, libz_ok=no)
162
163 if test "x$libz_ok" = "xyes"; then
164 old_libs="$LIBS"
165 AC_CHECK_LIB(z, zlibVersion, libz_ok=yes, libz_ok=no)
166 LIBS="$old_libs"
167 fi
168
169 if test "x$libz_ok" = xyes; then
170 LIBZ_LIBS="-lz"
171 else
172 AC_MSG_ERROR(zlib must be installed!)
173 fi
174
175 dnl ---------------
176 dnl Test for libpng
177 dnl ---------------
178 dnl
179 if test "x$enable_png" = "xyes"; then
180 AC_MSG_CHECKING([for libpng-config])
181
182 dnl Check if the user hasn't set the variable $PNG_CONFIG
183 if test -z "$PNG_CONFIG"; then
184 PNG_CONFIG=`which libpng14-config`
185 if test -z "$PNG_CONFIG"; then
186 PNG_CONFIG=`which libpng12-config`
187 fi
188 if test -z "$PNG_CONFIG"; then
189 PNG_CONFIG=`which libpng-config`
190 fi
191 if test -z "$PNG_CONFIG"; then
192 PNG_CONFIG=`which libpng10-config`
193 fi
194 fi
195
196 dnl Check if the libpng-config script was found and is executable
197 if test -n "$PNG_CONFIG" && test -x "$PNG_CONFIG"; then
198 AC_MSG_RESULT([$PNG_CONFIG])
199 png_ok="yes"
200 else
201 AC_MSG_RESULT([missing])
202 png_ok="no"
203 fi
204
205 if test "x$png_ok" = "xyes"; then
206 dnl For debugging and to be user friendly
207 AC_MSG_CHECKING([for libpng version])
208 png_version=`$PNG_CONFIG --version`
209 case $png_version in
210 1.4.*) AC_MSG_RESULT([$png_version (newer version)]) ;;
211 1.2.*) AC_MSG_RESULT([$png_version (newer version)]) ;;
212 1.0.*) AC_MSG_RESULT([$png_version (older version)]) ;;
213 *) AC_MSG_RESULT([ERROR]) ;;
214 esac
215
216 dnl Try to use options that are supported by all libpng-config versions...
217 LIBPNG_CFLAGS=`$PNG_CONFIG --cflags`
218 LIBPNG_LIBS=`$PNG_CONFIG --ldflags`
219 case $png_version in
220 1.2.4*) LIBPNG_LIBS="$LIBPNG_LIBS `$PNG_CONFIG --libs`" ;;
221 esac
222 else
223 dnl Try to find libpng even though libpng-config wasn't found
224 AC_CHECK_HEADERS(png.h libpng/png.h, png_ok=yes && break, png_ok=no)
225
226 if test "x$png_ok" = "xyes"; then
227 old_libs="$LIBS"
228 AC_CHECK_LIB(png, png_sig_cmp, png_ok=yes, png_ok=no, $LIBZ_LIBS -lm)
229 LIBS="$old_libs"
230
231 if test "x$png_ok" = "xyes"; then
232 LIBPNG_LIBS="-lpng -lm"
233 fi
234 fi
235
236 if test "x$png_ok" = "xno"; then
237 AC_MSG_WARN([*** No libpng found. Disabling PNG images ***])
238 fi
239 fi
240 fi
241
242 if test "x$png_ok" = "xyes"; then
243 AC_DEFINE([ENABLE_PNG], [1], [Enable PNG images])
244 fi
245
246 dnl Check if support for GIF images should be compiled in
247 if test "x$enable_gif" = "xyes"; then
248 AC_DEFINE([ENABLE_GIF], [1], [Enable GIF images])
249 fi
250
251 dnl --------------------------
252 dnl Test for support for SSL
253 dnl --------------------------
254 dnl
255 if test "x$enable_ssl" = "xyes"; then
256 AC_CHECK_HEADER(openssl/ssl.h, ssl_ok=yes, ssl_ok=no)
257
258 if test "x$ssl_ok" = "xyes"; then
259 old_libs="$LIBS"
260 AC_CHECK_LIB(ssl, SSL_library_init, ssl_ok=yes, ssl_ok=no, -lcrypto)
261 LIBS="$old_libs"
262 fi
263
264 if test "x$ssl_ok" = "xyes"; then
265 LIBSSL_LIBS="-lcrypto -lssl"
266 AC_MSG_WARN([*** Enabling ssl support. THIS IS ALPHA CODE!***])
267 else
268 AC_MSG_WARN([*** No libssl found. Disabling ssl support.***])
269 fi
270 fi
271
272 if test "x$ssl_ok" = "xyes"; then
273 AC_DEFINE([ENABLE_SSL], [1], [Enable SSL support])
274 fi
275
276 dnl --------------------------------------------------------------
277 dnl Test for iconv functionality in libc or for libiconv usability
278 dnl --------------------------------------------------------------
279 AC_CHECK_HEADER(iconv.h, iconv_ok=yes, iconv_ok=no)
280 if test "x$iconv_ok" = "xyes"; then
281 AC_CHECK_LIB(c, iconv_open, LIBICONV_LIBS="",
282 AC_CHECK_LIB(iconv, iconv_open, LIBICONV_LIBS="-liconv", iconv_ok=no))
283 fi
284 if test "x$iconv_ok" = "xno"; then
285 dnl Test for OpenBSD
286 old_libs="$LIBS"
287 LIBS="$old_libs -liconv"
288 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
289 #include <iconv.h>
290 ]],[[
291 iconv_open("","");
292 ]])],
293 iconv_ok=yes,iconv_ok=no)
294 LIBS="$old_libs"
295 if test "x$iconv_ok" = "xyes"; then
296 LIBICONV_LIBS="-liconv"
297 fi
298 fi
299
300 if test "x$iconv_ok" = "xno"; then
301 AC_MSG_ERROR(libiconv must be installed!)
302 fi
303
304 dnl ----------------------
305 dnl Check if we need to
306 dnl support the old
307 dnl iconv interface
308 dnl ----------------------
309 if test "x$iconv_ok" = "xyes"; then
310 old_libs="$LIBS"
311 LIBS="$old_libs $LIBICONV_LIBS"
312 old_cflags="$CFLAGS"
313 CFLAGS="$CFLAGS -Werror"
314 AC_LANG_PUSH([C++])
315 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
316 #include <iconv.h>
317 ]],[[
318 const char *inPtr;
319 char *outPtr;
320 size_t inLeft = 0, outRoom = 0;
321 iconv_t encoder = iconv_open("ASCII", "UTF-8");
322 iconv(encoder, &inPtr, &inLeft, &outPtr, &outRoom);
323 ]])],
324 iconv_old=yes,iconv_old=no)
325 AC_LANG_POP([C++])
326 LIBS="$old_libs"
327 CFLAGS="$old_cflags"
328
329 if test "x$iconv_old" = "xyes"; then
330 AC_DEFINE([inbuf_t], [const char], [Use const char pointers for older libiconv])
331 else
332 AC_DEFINE([inbuf_t], [char], [Use char pointers for newer libiconv])
333 fi
334 fi
335
336 dnl ----------------------
337 dnl Test for POSIX threads
338 dnl ----------------------
339 dnl
340 if test -z "$LIBPTHREAD_LIBS"; then
341 case $target in
342 *-*-linux*|*-*-solaris*)
343 old_libs="$LIBS"
344 AC_CHECK_LIB(pthread, pthread_create, LIBPTHREAD_LIBS="-lpthread")
345 LIBS="$old_libs"
346 ;;
347
348 *-*-osf1*)
349 AC_MSG_CHECKING(whether pthreads work)
350 LIBPTHREAD_LIBS="-lpthread -lexc -ldb"
351 AC_MSG_WARN([*** _Untested pthreads_ try setting LIBPTHREAD_LIBS manually if it doesn't work ***])
352 ;;
353
354 *-*-minix*)
355 AC_MSG_NOTICE([Minix detected, skipping pthread detection])
356 ;;
357
358 *)
359 AC_MSG_CHECKING(whether threads work with -pthread)
360 LDSAVEFLAGS=$LDFLAGS
361 LDFLAGS="$LDFLAGS -pthread"
362 AC_LINK_IFELSE([AC_LANG_CALL([],[pthread_create])],
363 pthread_ok=yes, pthread_ok=no)
364 LDFLAGS=$LDSAVEFLAGS
365
366 if test "x$pthread_ok" = "xyes"; then
367 AC_MSG_RESULT(yes)
368 LIBPTHREAD_LDFLAGS="-pthread"
369 else
370 AC_MSG_RESULT(no. Now we will try some libraries.)
371
372 AC_SEARCH_LIBS(pthread_create, pthread,
373 LIBPTHREADS_LIBS="-lpthread",
374 AC_SEARCH_LIBS(pthread_create, pthreads,
375 LIBPTHREADS_LIBS="-lpthreads",
376 AC_SEARCH_LIBS(pthread_create, c_r,
377 LIBPTHREADS_LIBS="-lc_r", thread_ok=no)))
378
379 if test "x$thread_ok" = "xno"; then
380 AC_MSG_WARN([*** No pthreads found. ***])
381 AC_MSG_ERROR([*** Try setting LIBPTHREAD_LIBS manually to point to your pthreads library. ***])
382 exit 1
383 else
384 AC_MSG_WARN([found a way to link threads, but it may not work...])
385 fi
386 fi
387 ;;
388
389 esac
390 fi
391
392 dnl --------------------
393 dnl Command line options
394 dnl --------------------
395 dnl
396 if test "x$enable_cookies" = "xno" ; then
397 CFLAGS="$CFLAGS -DDISABLE_COOKIES"
398 CXXFLAGS="$CXXFLAGS -DDISABLE_COOKIES"
399 fi
400 if test "x$enable_ipv6" = "xyes" ; then
401 CFLAGS="$CFLAGS -DENABLE_IPV6"
402 fi
403 if test "x$enable_efence" = "xyes" ; then
404 LIBS="-lefence $LIBS"
405 fi
406 if test "x$enable_gprof" = "xyes" ; then
407 CFLAGS="$CFLAGS -pg"
408 CXXFLAGS="$CXXFLAGS -pg"
409 fi
410 if test "x$enable_insure" = "xyes" ; then
411 CC="insure -Zoi \"compiler $CC\""
412 LIBS="$LIBS -lstdc++-2-libc6.1-1-2.9.0"
413 fi
414 if test "x$enable_threaded_dns" = "xyes" ; then
415 CFLAGS="$CFLAGS -DD_DNS_THREADED"
416 fi
417 if test "x$enable_rtfl" = "xyes" ; then
418 CXXFLAGS="$CXXFLAGS -DDBG_RTFL"
419 fi
420
421 dnl -----------------------
422 dnl Checks for header files
423 dnl -----------------------
424 dnl
425 AC_CHECK_HEADERS(fcntl.h unistd.h sys/uio.h)
426
427 dnl --------------------------
428 dnl Check for compiler options
429 dnl --------------------------
430 dnl
431 if eval "test x$GCC = xyes"; then
432 if test "`echo $CFLAGS | grep '\-D_REENTRANT' 2> /dev/null`" = ""; then
433 CFLAGS="$CFLAGS -D_REENTRANT"
434 fi
435 if test "`echo $CFLAGS | grep '\-D_THREAD_SAFE' 2> /dev/null`" = ""; then
436 CFLAGS="$CFLAGS -D_THREAD_SAFE"
437 fi
438 if test "`echo $CFLAGS | grep '\-Wall' 2> /dev/null`" = ""; then
439 CFLAGS="$CFLAGS -Wall"
440 fi
441 if test "`echo $CFLAGS | grep -e '-W ' -e '-W$' 2> /dev/null`" = ""; then
442 CFLAGS="$CFLAGS -W"
443 fi
444 if test "`echo $CFLAGS | grep '\-Wno-unused-parameter' 2> /dev/null`" = ""; then
445 CFLAGS="$CFLAGS -Wno-unused-parameter"
446 fi
447 if test "`echo $CFLAGS | grep '\-Waggregate-return' 2> /dev/null`" = ""; then
448 CFLAGS="$CFLAGS -Waggregate-return"
449 fi
450 fi
451 dnl -----------
452 dnl CXX options
453 dnl -----------
454 dnl
455
456 if eval "test x$GCC = xyes"; then
457 CXXFLAGS="$CXXFLAGS -Wall -W -Wno-unused-parameter -fno-rtti -fno-exceptions"
458 fi
459
460 AC_SUBST(LIBJPEG_LIBS)
461 AC_SUBST(LIBJPEG_LDFLAGS)
462 AC_SUBST(LIBJPEG_CPPFLAGS)
463 AC_SUBST(LIBPNG_LIBS)
464 AC_SUBST(LIBPNG_CFLAGS)
465 AC_SUBST(LIBZ_LIBS)
466 AC_SUBST(LIBSSL_LIBS)
467 AC_SUBST(LIBPTHREAD_LIBS)
468 AC_SUBST(LIBPTHREAD_LDFLAGS)
469 AC_SUBST(LIBFLTK_CXXFLAGS)
470 AC_SUBST(LIBFLTK_CFLAGS)
471 AC_SUBST(LIBFLTK_LIBS)
472 AC_SUBST(LIBICONV_LIBS)
473 AC_SUBST(datadir)
474
475 AC_CONFIG_FILES([
476 Makefile
477 dlib/Makefile
478 dpip/Makefile
479 dpid/Makefile
480 dpi/Makefile
481 doc/Makefile
482 dw/Makefile
483 lout/Makefile
484 src/Makefile
485 src/IO/Makefile
486 test/Makefile
487 ])
488
489 AC_OUTPUT
00 #! /bin/sh
11 # depcomp - compile a program generating dependencies as side-effects
22
3 scriptversion=2009-04-28.21; # UTC
4
5 # Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 Free
6 # Software Foundation, Inc.
3 scriptversion=2012-03-27.16; # UTC
4
5 # Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009, 2010,
6 # 2011, 2012 Free Software Foundation, Inc.
77
88 # This program is free software; you can redistribute it and/or modify
99 # it under the terms of the GNU General Public License as published by
2727
2828 case $1 in
2929 '')
30 echo "$0: No command. Try \`$0 --help' for more information." 1>&2
30 echo "$0: No command. Try '$0 --help' for more information." 1>&2
3131 exit 1;
3232 ;;
3333 -h | --h*)
3939
4040 Environment variables:
4141 depmode Dependency tracking mode.
42 source Source file read by `PROGRAMS ARGS'.
43 object Object file output by `PROGRAMS ARGS'.
42 source Source file read by 'PROGRAMS ARGS'.
43 object Object file output by 'PROGRAMS ARGS'.
4444 DEPDIR directory where to store dependencies.
4545 depfile Dependency file to output.
46 tmpdepfile Temporary file to use when outputing dependencies.
46 tmpdepfile Temporary file to use when outputting dependencies.
4747 libtool Whether libtool is used (yes/no).
4848
4949 Report bugs to <bug-automake@gnu.org>.
5656 ;;
5757 esac
5858
59 # A tabulation character.
60 tab=' '
61 # A newline character.
62 nl='
63 '
64
5965 if test -z "$depmode" || test -z "$source" || test -z "$object"; then
6066 echo "depcomp: Variables source, object and depmode must be set" 1>&2
6167 exit 1
8995 # This is just like msvisualcpp but w/o cygpath translation.
9096 # Just convert the backslash-escaped backslashes to single forward
9197 # slashes to satisfy depend.m4
92 cygpath_u="sed s,\\\\\\\\,/,g"
98 cygpath_u='sed s,\\\\,/,g'
9399 depmode=msvisualcpp
100 fi
101
102 if test "$depmode" = msvc7msys; then
103 # This is just like msvc7 but w/o cygpath translation.
104 # Just convert the backslash-escaped backslashes to single forward
105 # slashes to satisfy depend.m4
106 cygpath_u='sed s,\\\\,/,g'
107 depmode=msvc7
108 fi
109
110 if test "$depmode" = xlc; then
111 # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency informations.
112 gccflag=-qmakedep=gcc,-MF
113 depmode=gcc
94114 fi
95115
96116 case "$depmode" in
147167 ## The second -e expression handles DOS-style file names with drive letters.
148168 sed -e 's/^[^:]*: / /' \
149169 -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
150 ## This next piece of magic avoids the `deleted header file' problem.
170 ## This next piece of magic avoids the "deleted header file" problem.
151171 ## The problem is that when a header file which appears in a .P file
152172 ## is deleted, the dependency causes make to die (because there is
153173 ## typically no way to rebuild the header). We avoid this by adding
154174 ## dummy dependencies for each header file. Too bad gcc doesn't do
155175 ## this for us directly.
156 tr ' ' '
157 ' < "$tmpdepfile" |
158 ## Some versions of gcc put a space before the `:'. On the theory
176 tr ' ' "$nl" < "$tmpdepfile" |
177 ## Some versions of gcc put a space before the ':'. On the theory
159178 ## that the space means something, we add a space to the output as
160 ## well.
179 ## well. hp depmode also adds that space, but also prefixes the VPATH
180 ## to the object. Take care to not repeat it in the output.
161181 ## Some versions of the HPUX 10.20 sed can't process this invocation
162182 ## correctly. Breaking it into two sed invocations is a workaround.
163 sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
183 sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
184 | sed -e 's/$/ :/' >> "$depfile"
164185 rm -f "$tmpdepfile"
165186 ;;
166187
192213 # clever and replace this with sed code, as IRIX sed won't handle
193214 # lines with more than a fixed number of characters (4096 in
194215 # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
195 # the IRIX cc adds comments like `#:fec' to the end of the
216 # the IRIX cc adds comments like '#:fec' to the end of the
196217 # dependency line.
197 tr ' ' '
198 ' < "$tmpdepfile" \
218 tr ' ' "$nl" < "$tmpdepfile" \
199219 | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
200 tr '
201 ' ' ' >> "$depfile"
220 tr "$nl" ' ' >> "$depfile"
202221 echo >> "$depfile"
203222
204223 # The second pass generates a dummy entry for each header file.
205 tr ' ' '
206 ' < "$tmpdepfile" \
224 tr ' ' "$nl" < "$tmpdepfile" \
207225 | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
208226 >> "$depfile"
209227 else
215233 rm -f "$tmpdepfile"
216234 ;;
217235
236 xlc)
237 # This case exists only to let depend.m4 do its work. It works by
238 # looking at the text of this script. This case will never be run,
239 # since it is checked for above.
240 exit 1
241 ;;
242
218243 aix)
219244 # The C for AIX Compiler uses -M and outputs the dependencies
220245 # in a .u file. In older versions, this file always lives in the
221 # current directory. Also, the AIX compiler puts `$object:' at the
246 # current directory. Also, the AIX compiler puts '$object:' at the
222247 # start of each line; $object doesn't have directory information.
223248 # Version 6 uses the directory in both cases.
224249 dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
248273 test -f "$tmpdepfile" && break
249274 done
250275 if test -f "$tmpdepfile"; then
251 # Each line is of the form `foo.o: dependent.h'.
276 # Each line is of the form 'foo.o: dependent.h'.
252277 # Do two passes, one to just change these to
253 # `$object: dependent.h' and one to simply `dependent.h:'.
278 # '$object: dependent.h' and one to simply 'dependent.h:'.
254279 sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
255 # That's a tab and a space in the [].
256 sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
280 sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
257281 else
258282 # The sourcefile does not contain any dependencies, so just
259283 # store a dummy comment line, to avoid errors with the Makefile
264288 ;;
265289
266290 icc)
267 # Intel's C compiler understands `-MD -MF file'. However on
268 # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
291 # Intel's C compiler anf tcc (Tiny C Compiler) understand '-MD -MF file'.
292 # However on
293 # $CC -MD -MF foo.d -c -o sub/foo.o sub/foo.c
269294 # ICC 7.0 will fill foo.d with something like
270295 # foo.o: sub/foo.c
271296 # foo.o: sub/foo.h
272 # which is wrong. We want:
297 # which is wrong. We want
273298 # sub/foo.o: sub/foo.c
274299 # sub/foo.o: sub/foo.h
275300 # sub/foo.c:
276301 # sub/foo.h:
277302 # ICC 7.1 will output
278303 # foo.o: sub/foo.c sub/foo.h
279 # and will wrap long lines using \ :
304 # and will wrap long lines using '\':
280305 # foo.o: sub/foo.c ... \
281306 # sub/foo.h ... \
282307 # ...
283
308 # tcc 0.9.26 (FIXME still under development at the moment of writing)
309 # will emit a similar output, but also prepend the continuation lines
310 # with horizontal tabulation characters.
284311 "$@" -MD -MF "$tmpdepfile"
285312 stat=$?
286313 if test $stat -eq 0; then :
289316 exit $stat
290317 fi
291318 rm -f "$depfile"
292 # Each line is of the form `foo.o: dependent.h',
293 # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
319 # Each line is of the form 'foo.o: dependent.h',
320 # or 'foo.o: dep1.h dep2.h \', or ' dep3.h dep4.h \'.
294321 # Do two passes, one to just change these to
295 # `$object: dependent.h' and one to simply `dependent.h:'.
296 sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
297 # Some versions of the HPUX 10.20 sed can't process this invocation
298 # correctly. Breaking it into two sed invocations is a workaround.
299 sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
300 sed -e 's/$/ :/' >> "$depfile"
322 # '$object: dependent.h' and one to simply 'dependent.h:'.
323 sed -e "s/^[ $tab][ $tab]*/ /" -e "s,^[^:]*:,$object :," \
324 < "$tmpdepfile" > "$depfile"
325 sed '
326 s/[ '"$tab"'][ '"$tab"']*/ /g
327 s/^ *//
328 s/ *\\*$//
329 s/^[^:]*: *//
330 /^$/d
331 /:$/d
332 s/$/ :/
333 ' < "$tmpdepfile" >> "$depfile"
301334 rm -f "$tmpdepfile"
302335 ;;
303336
333366 done
334367 if test -f "$tmpdepfile"; then
335368 sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
336 # Add `dependent.h:' lines.
369 # Add 'dependent.h:' lines.
337370 sed -ne '2,${
338371 s/^ *//
339372 s/ \\*$//
348381
349382 tru64)
350383 # The Tru64 compiler uses -MD to generate dependencies as a side
351 # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
384 # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
352385 # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
353 # dependencies in `foo.d' instead, so we check for that too.
386 # dependencies in 'foo.d' instead, so we check for that too.
354387 # Subdirectories are respected.
355388 dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
356389 test "x$dir" = "x$object" && dir=
396429 done
397430 if test -f "$tmpdepfile"; then
398431 sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
399 # That's a tab and a space in the [].
400 sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
432 sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
401433 else
402434 echo "#dummy" > "$depfile"
403435 fi
404436 rm -f "$tmpdepfile"
405437 ;;
406438
439 msvc7)
440 if test "$libtool" = yes; then
441 showIncludes=-Wc,-showIncludes
442 else
443 showIncludes=-showIncludes
444 fi
445 "$@" $showIncludes > "$tmpdepfile"
446 stat=$?
447 grep -v '^Note: including file: ' "$tmpdepfile"
448 if test "$stat" = 0; then :
449 else
450 rm -f "$tmpdepfile"
451 exit $stat
452 fi
453 rm -f "$depfile"
454 echo "$object : \\" > "$depfile"
455 # The first sed program below extracts the file names and escapes
456 # backslashes for cygpath. The second sed program outputs the file
457 # name when reading, but also accumulates all include files in the
458 # hold buffer in order to output them again at the end. This only
459 # works with sed implementations that can handle large buffers.
460 sed < "$tmpdepfile" -n '
461 /^Note: including file: *\(.*\)/ {
462 s//\1/
463 s/\\/\\\\/g
464 p
465 }' | $cygpath_u | sort -u | sed -n '
466 s/ /\\ /g
467 s/\(.*\)/'"$tab"'\1 \\/p
468 s/.\(.*\) \\/\1:/
469 H
470 $ {
471 s/.*/'"$tab"'/
472 G
473 p
474 }' >> "$depfile"
475 rm -f "$tmpdepfile"
476 ;;
477
478 msvc7msys)
479 # This case exists only to let depend.m4 do its work. It works by
480 # looking at the text of this script. This case will never be run,
481 # since it is checked for above.
482 exit 1
483 ;;
484
407485 #nosideeffect)
408486 # This comment above is used by automake to tell side-effect
409487 # dependency tracking mechanisms from slower ones.
421499 shift
422500 fi
423501
424 # Remove `-o $object'.
502 # Remove '-o $object'.
425503 IFS=" "
426504 for arg
427505 do
441519 done
442520
443521 test -z "$dashmflag" && dashmflag=-M
444 # Require at least two characters before searching for `:'
522 # Require at least two characters before searching for ':'
445523 # in the target name. This is to cope with DOS-style filenames:
446 # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
524 # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
447525 "$@" $dashmflag |
448 sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
526 sed 's:^['"$tab"' ]*[^:'"$tab"' ][^:][^:]*\:['"$tab"' ]*:'"$object"'\: :' > "$tmpdepfile"
449527 rm -f "$depfile"
450528 cat < "$tmpdepfile" > "$depfile"
451 tr ' ' '
452 ' < "$tmpdepfile" | \
529 tr ' ' "$nl" < "$tmpdepfile" | \
453530 ## Some versions of the HPUX 10.20 sed can't process this invocation
454531 ## correctly. Breaking it into two sed invocations is a workaround.
455532 sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
502579 touch "$tmpdepfile"
503580 ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
504581 rm -f "$depfile"
505 cat < "$tmpdepfile" > "$depfile"
506 sed '1,2d' "$tmpdepfile" | tr ' ' '
507 ' | \
582 # makedepend may prepend the VPATH from the source file name to the object.
583 # No need to regex-escape $object, excess matching of '.' is harmless.
584 sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
585 sed '1,2d' "$tmpdepfile" | tr ' ' "$nl" | \
508586 ## Some versions of the HPUX 10.20 sed can't process this invocation
509587 ## correctly. Breaking it into two sed invocations is a workaround.
510588 sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
524602 shift
525603 fi
526604
527 # Remove `-o $object'.
605 # Remove '-o $object'.
528606 IFS=" "
529607 for arg
530608 do
593671 sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
594672 rm -f "$depfile"
595673 echo "$object : \\" > "$depfile"
596 sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
597 echo " " >> "$depfile"
674 sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
675 echo "$tab" >> "$depfile"
598676 sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
599677 rm -f "$tmpdepfile"
600678 ;;
0 #!/usr/bin/env perl
1 use POSIX;
2 use File::Basename;
3 use Net::FTP;
4 use Getopt::Long;
5
6 $host = "mirrors.dotsrc.org";
7 $basesourcedir = "/ctan";
8 $sourcedir = "";
9
10 # Determine ${prefix}, for the default target directory for pattern
11 # files. Two different strategies ...
12 $makefile = (dirname $0) . "/Makefile";
13 if (-e $makefile) {
14 # 1. Makefile exists in the same directory, so it can be assumed
15 # that this script is not yet installed, but called from the source
16 # directory. Search Makefile for prexix.
17 open MF, $makefile or die "Cannot open $makefile: $!";
18 while (<MF>) {
19 if (/^\s*prefix\s*=\s*(.*)\s*$/) {
20 $prefix = $1;
21 }
22 }
23 close MF;
24
25 if ($prefix eq "") {
26 die "Prefix not defined in $makefile.";
27 }
28 } else {
29 # 2. Assume that this is script is installed, so its path contains
30 # the prefix.
31 if ($0 =~ /(.*)\/bin\/[^\/]+$/) {
32 $prefix = $1;
33 } else {
34 die "Failed to determine prefix from $0.";
35 }
36 }
37
38 $targetdir = "$prefix/lib/dillo/hyphenation";
39
40 if (!GetOptions ("host=s" => \$host,
41 "basesourcedir=s" => \$basesourcedir,
42 "sourcedir=s" => \$sourcedir,
43 "targetdir=s" => \$targetdir)
44 || @ARGV == 0) {
45 print "Usage: $0 [OPTIONS] LANG [LANG ...]\n\n";
46 print <<EOT;
47 Download and install hyphenation patterns from CTAN for different languages,
48 via FTP. Languages are specified as defined by ISO 639-1 ("en" for English
49 etc.).
50
51 If there are multiple pattern files for a language (and so the filename is not
52 "hyph-LANG.pat.txt"), you must specify the respective part of the filename,
53 e. g. "en-gb" or "en-us". In this case, the extra part ("-gb" or "-us") is
54 automatically removed.
55
56 If you are not sure, simply specify the language code ("en" in this example);
57 you will then given a list of existing pattern files.
58
59 Options:
60 -h, --host=HOST the host to connect to (default:
61 mirrors.dotrc.org)
62 -s, --sourcedir=DIR the directory on the FTP server
63 -b, --basesourcedir=DIR alternatively, the base directory, after which
64 /language/hyph-utf8/tex/generic/hyph-utf8...
65 .../patterns/txt is added (default: /ctan/)
66 -t, --targetdir=DIR where to install the hyphenation patterns
67 (default: where they are read by dillo)
68 EOT
69 } else {
70 if ($sourcedir eq "") {
71 $sourcedir =
72 "$basesourcedir/language/hyph-utf8/tex/generic/hyph-utf8/patterns/txt";
73 }
74
75 if (!-e $targetdir) {
76 mkdir $targetdir or die "Cannot create directory $targetdir: $!";
77 print "Created $targetdir.\n";
78 }
79
80 # Connect to CTAN FTP server, change to the directory where the
81 # patterns lie, and read files list (which may be useful later).
82 $ftp = Net::FTP->new($host,Timeout=>240)
83 or die "Cannot connect to $host: $!";
84 $ftp->login() or die "Cannot login: $!";
85 $ftp->cwd($sourcedir) or die "Cannot change to directory $sourcedir: $!";
86 @files = $ftp->ls or die "Cannot read directory: $!";
87
88 # Finally, read pattern files.
89 foreach $arg (@ARGV) {
90 if ($arg =~ /^([a-z]+)-.*$/) {
91 # More files per language, e. g. "en-gb".
92 $lang = $1;
93 } else {
94 # One file per language, e. g. "ru".
95 $lang = $arg;
96 }
97
98 # First, donwload the pattern file to a temporary file.
99 $tmppat = tmpnam();
100 if ($ftp->get ("hyph-$arg.pat.txt", $tmppat)) {
101 printf ("Successfully downloaded pattern file for \"$arg\".\n");
102
103 # Search for a licence file. (Only a warning, when it does
104 # not exist.)
105 $tmplic = tmpnam();
106 $licfound = 0;
107 if ($ftp->get ("hyph-$arg.lic.txt", $tmplic)) {
108 $licfound = 1;
109 } else {
110 print "Warning: Cannot download license file for \"$arg\": $!\n";
111 }
112
113 # Combine both, licence and pattern, to the final pattern
114 # file.
115 $outfile = "$targetdir/$lang.pat";
116 open OUT, "> $outfile" or die "Cannot open $outfile: $!";
117
118 if ($licfound) {
119 print OUT
120 "% Licence from ftp://$host$sourcedir/hyph-$arg.lic.txt\n";
121 print OUT "%\n";
122 open IN, $tmplic or die "Cannot open $tmplic: $!";
123 while (<IN>) {
124 # Each line from the licence file must be a comment.
125 if (!/^%/) {
126 print OUT "% ";
127 }
128 print OUT;
129 }
130 close IN;
131 unlink $tmplic;
132
133 print OUT "%\n";
134 }
135
136 print OUT "% Patterns from ftp://$host$sourcedir/hyph-$arg.pat.txt\n";
137 print OUT "%\n";
138 open IN, $tmppat or die "Cannot open $tmppat: $!";
139 while (<IN>) {
140 print OUT;
141 }
142 close IN;
143 unlink $tmppat;
144
145 close OUT;
146 } else {
147 # Not found. If a single language was specified (e. g. "en"),
148 # search for possibilities.
149 print "Error: Cannot download pattern file for \"$arg\": $!\n";
150 if ($lang eq $arg) {
151 print "Try one of these:\n";
152 foreach(@files) {
153 if (/^hyph-($lang-.*)\.pat\.txt$/) {
154 print " $1\n";
155 }
156 }
157 }
158 }
159 }
160
161 $ftp->quit;
162 }
2424 # Change this if you want to disable parsing of embedded CSS initially.
2525 # (While browsing, this can be changed from the tools/settings menu.)
2626 #parse_embedded_css=YES
27
28 # How should Dillo restrict automatic requests (e.g., redirections,
29 # pages containing images or stylesheets)?
30 # allow_all
31 # same_domain : Permit www.example.org to load an image from img.example.org,
32 # but not from the unrelated ad.doubleclick.net.
33 #filter_auto_requests=same_domain
3427
3528 # Change the buffering scheme for drawing
3629 # 0 no double buffering - useful for debugging
8376
8477
8578 #-------------------------------------------------------------------------
79 # PENALTIES
80 #-------------------------------------------------------------------------
81
82 # Penalties are used to control good and bad break points. The bigger
83 # the penalty for a given break point, the less likely the line is
84 # broken here. "inf" means that breaking is prohibited, "-inf" means
85 # that a line *must* be broken here. (The latter should not be used
86 # here, however.) Normal spaces get a penalty of 0. The exact
87 # definition can be found in doc/dw-line-breaking.doc.
88
89 # Penalties for hyphenation breaks; this covers automatic hyphenation,
90 # soft hyphens, and unconditional hyphens. Since hyphenation should
91 # rather be avoided, the default values are larger than 0.
92
93 # This is used for hyphenation points, when there is no hyphen or dash
94 # before:
95 #penalty_hyphen = 1
96
97 # This is used for hyphenation points, when the line before ends
98 # already with a hyphen or a dash. Consequent lines ending with
99 # hyphens or dashes should be avoided, so this value is bigger than
100 # "penalty_hyphen":
101 #penalty_hyphen_2 = 8
102
103 # The same for a break right of an em-dash, when there are no spaces
104 # surrounding it (as in English). The default values are the same as
105 # for hyphens:
106 #penalty_em_dash_right = 1
107 #penalty_em_dash_right_2 = 8
108
109 # Penalty for a break *left* of an em-dash. Since a line ending with
110 # an em-dash (and so breaking right of the em-dash) looks better than
111 # a line beginning with an em-dash (breaking left of an em-dash), the
112 # default value is bigger than "penalty_em_dash_right":
113 #penalty_em_dash_left = 8
114
115 # Notice that there is no "penalty_em_dash_left_2", since breaking
116 # left of an em-dash makes the line *begin*, not *end* with a dash.
117
118
119 #-------------------------------------------------------------------------
86120 # PARSING SECTION
87121 #-------------------------------------------------------------------------
88122
112146 # You can enable multiple search_url strings at once and select from among
113147 # them at runtime, with the first being the default.
114148 search_url="http://duckduckgo.com/lite/?kp=-1&q=%s"
115 search_url="Scroogle https://ssl.scroogle.org/cgi-bin/nbbwssl.cgi?Gw=%s"
116149 search_url="Wikipedia http://www.wikipedia.org/w/index.php?search=%s&go=Go"
117150 search_url="Free Dictionary http://www.thefreedictionary.com/%s"
118151 search_url="Google http://www.google.com/search?ie=UTF-8&oe=UTF-8&q=%s"
164197 #
165198 # See http://zytrax.com/tech/web/browser_ids.htm for a compilation of strings.
166199 #
167 # http_user_agent="Mozilla/5.0 (Windows NT 5.1; rv:7.0.1) Gecko/20100101 Firefox/7.0.1"
200 # http_user_agent="Mozilla/5.0 (Windows NT 5.1; rv:18.0) Gecko/20100101 Firefox/18.0"
168201 # http_user_agent="Wget/1.12 (linux-gnu)"
169202 #The default is "Dillo/"+current_version_number
170203
172205 # COLORS SECTION
173206 #-------------------------------------------------------------------------
174207
175 # Set the background color
208 # Set the page background color
176209 # bg_color=gray
177210 # bg_color=0xd6d6c0
178211 #bg_color=0xdcd1ba
197230 #theme=none
198231 # theme=gtk+
199232 # theme=plastic
233
234 # UI colors
235 # The first four colors map to concepts in the underlying FLTK toolkit. Note
236 # that FLTK may sometimes override colors, generally for contrast and
237 # readability.
238 #
239 #ui_fg_color=black
240 #ui_main_bg_color=silver
241 #ui_text_bg_color=white
242 #ui_selection_color=navy
243 #
244 # Background used when the mouse cursor is over a button.
245 #ui_button_highlight_color=(by default, the main background color, lightened)
246 #
247 # Colors for the current tab.
248 #ui_tab_active_bg_color=(by default, the text background color)
249 #ui_tab_active_fg_color=(by default, the main foreground color)
250 #
251 # Colors for the other tabs.
252 #ui_tab_bg_color=(by default, the main background color)
253 #ui_tab_fg_color=(by default, the main foreground color)
254
255
256 # Note to packagers: leaving these variables for the system to guess
257 # gives different results in different environments, so we played it safe
258 # by defining the traditional colors. Please choose the color theme that
259 # better fits your distro.
260
261 #
262 # Gray theme (traditional)
263 #
264 ui_fg_color=black
265 ui_main_bg_color=#c6c6c6
266 ui_text_bg_color=bfdabf
267 ui_selection_color=#191970
268 ui_button_highlight_color=#a9a9a9
269 ui_tab_active_bg_color=#87aca7
270 ui_tab_active_fg_color=black
271 ui_tab_bg_color=#b7beb7
272
273 #
274 # Earthly theme:
275 #
276 #ui_fg_color=#100404
277 #ui_main_bg_color=#c2a47b
278 #ui_text_bg_color=#cdc9a5
279 #ui_selection_color=#763024
280 #ui_tab_active_bg_color=#af4b3f
281 #ui_tab_active_fg_color=white
282 #ui_tab_bg_color=#d2b48c
283
284 #
285 # Greenish theme:
286 #
287 #ui_fg_color=#100404
288 #ui_main_bg_color=#c8d394
289 #ui_text_bg_color=#bdd8b6
290 #ui_selection_color=#7c5f42
291 #ui_button_highlight_color=#adad70
292 #ui_tab_active_bg_color=#b5b679
293 #ui_tab_active_fg_color=#b60907
294 #ui_tab_bg_color=#cac682
295
200296
201297 # Size of dillo panel
202298 # tiny : buttons, location, and progress boxes in one row
219315 #show_tools=YES
220316 #show_filemenu=YES
221317 #show_clear_url=YES
222 #show_url=YES
223318 #show_search=YES
224319 #show_help=YES
225320 #show_progress_box=YES
0 # Makefile.in generated by automake 1.11.1 from Makefile.am.
0 # Makefile.in generated by automake 1.11.6 from Makefile.am.
11 # @configure_input@
22
33 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
4 # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
5 # Inc.
4 # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
5 # Foundation, Inc.
66 # This Makefile.in is free software; the Free Software Foundation
77 # gives unlimited permission to copy and/or distribute it,
88 # with or without modifications, as long as this notice is preserved.
1515 @SET_MAKE@
1616
1717 VPATH = @srcdir@
18 am__make_dryrun = \
19 { \
20 am__dry=no; \
21 case $$MAKEFLAGS in \
22 *\\[\ \ ]*) \
23 echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
24 | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
25 *) \
26 for am__flg in $$MAKEFLAGS; do \
27 case $$am__flg in \
28 *=*|--*) ;; \
29 *n*) am__dry=yes; break;; \
30 esac; \
31 done;; \
32 esac; \
33 test $$am__dry = yes; \
34 }
1835 pkgdatadir = $(datadir)/@PACKAGE@
1936 pkgincludedir = $(includedir)/@PACKAGE@
2037 pkglibdir = $(libdir)/@PACKAGE@
3754 subdir = dlib
3855 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
3956 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
40 am__aclocal_m4_deps = $(top_srcdir)/configure.in
57 am__aclocal_m4_deps = $(top_srcdir)/configure.ac
4158 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
4259 $(ACLOCAL_M4)
4360 mkinstalldirs = $(install_sh) -d
6178 LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
6279 SOURCES = $(libDlib_a_SOURCES)
6380 DIST_SOURCES = $(libDlib_a_SOURCES)
81 am__can_run_installinfo = \
82 case $$AM_UPDATE_INFO_DIR in \
83 n|no|NO) false;; \
84 *) (install-info --version) >/dev/null 2>&1;; \
85 esac
6486 ETAGS = etags
6587 CTAGS = ctags
6688 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
225247
226248 clean-noinstLIBRARIES:
227249 -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
228 libDlib.a: $(libDlib_a_OBJECTS) $(libDlib_a_DEPENDENCIES)
250 libDlib.a: $(libDlib_a_OBJECTS) $(libDlib_a_DEPENDENCIES) $(EXTRA_libDlib_a_DEPENDENCIES)
229251 -rm -f libDlib.a
230252 $(libDlib_a_AR) libDlib.a $(libDlib_a_OBJECTS) $(libDlib_a_LIBADD)
231253 $(RANLIB) libDlib.a
348370
349371 installcheck: installcheck-am
350372 install-strip:
351 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
352 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
353 `test -z '$(STRIP)' || \
354 echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
373 if test -z '$(STRIP)'; then \
374 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
375 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
376 install; \
377 else \
378 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
379 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
380 "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
381 fi
355382 mostlyclean-generic:
356383
357384 clean-generic:
6464
6565 void dFree (void *mem)
6666 {
67 if (mem)
68 free(mem);
67 free(mem);
6968 }
7069
7170 /*
909908
910909 /*
911910 * Get a line from a FILE stream.
912 * It handles backslash as line-continues character.
913911 * Return value: read line on success, NULL on EOF.
914912 */
915913 char *dGetline (FILE *stream)
932930 return line;
933931 }
934932
933 /*
934 * Close a FD handling EINTR.
935 */
936 int dClose(int fd)
937 {
938 int st;
939
940 do
941 st = close(fd);
942 while (st == -1 && errno == EINTR);
943 return st;
944 }
9898 */
9999 #define Dstr_char_t char
100100
101 typedef struct _dstr {
101 typedef struct {
102102 int sz; /* allocated size (private) */
103103 int len;
104104 Dstr_char_t *str;
127127 /*
128128 *-- dList --------------------------------------------------------------------
129129 */
130 struct Dlist_ {
130 typedef struct {
131131 int sz; /* allocated size (private) */
132132 int len;
133133 void **list;
134 };
135
136 typedef struct Dlist_ Dlist;
134 } Dlist;
137135
138136 /* dCompareFunc:
139137 * Return: 0 if parameters are equal (for dList_find_custom).
174172 /*
175173 *- Misc utility functions ----------------------------------------------------
176174 */
177 char *dGetcwd ();
178 char *dGethomedir ();
179 char *dGetline (FILE *stream);
180
175 char *dGetcwd();
176 char *dGethomedir();
177 char *dGetline(FILE *stream);
178 int dClose(int fd);
181179
182180 #ifdef __cplusplus
183181 }
8484 controlling instance of dillo exits and another must "take
8585 over" the managing.
8686 * It increments dillo's core size.
87 * If dillo hangs/crashes, dpi activity is lost (e.g. downloads)
8788 * ...
8889
8990 That's why the managing daemon scheme was chosen.
00 dist_doc_DATA = user_help.html
11 man_MANS = dillo.1
22 EXTRA_DIST = \
3 $(man_MANS) \
43 index.doc \
54 lout.doc \
65 dw-map.doc \
2625 dw-textblock-collapsing-spaces-1-2.png \
2726 dw-textblock-collapsing-spaces-2-1.png \
2827 dw-textblock-collapsing-spaces-2-2.png \
29 Cache.txt \
30 Cookies.txt \
31 Dillo.txt \
32 Dw.txt \
33 HtmlParser.txt \
34 IO.txt \
35 Images.txt \
36 Imgbuf.txt \
37 NC_design.txt \
38 Selection.txt \
39 Dpid.txt \
40 README
28 Cache.txt \
29 Cookies.txt \
30 Dillo.txt \
31 Dw.txt \
32 HtmlParser.txt \
33 IO.txt \
34 Images.txt \
35 Imgbuf.txt \
36 NC_design.txt \
37 Selection.txt \
38 Dpid.txt \
39 README \
40 dillo.1.in
41
42 dillo.1: $(srcdir)/dillo.1.in Makefile
43 sed 's%/usr/local%${prefix}%g' < $(srcdir)/dillo.1.in > dillo.1
0 # Makefile.in generated by automake 1.11.1 from Makefile.am.
0 # Makefile.in generated by automake 1.11.6 from Makefile.am.
11 # @configure_input@
22
33 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
4 # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
5 # Inc.
4 # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
5 # Foundation, Inc.
66 # This Makefile.in is free software; the Free Software Foundation
77 # gives unlimited permission to copy and/or distribute it,
88 # with or without modifications, as long as this notice is preserved.
1515 @SET_MAKE@
1616
1717 VPATH = @srcdir@
18 am__make_dryrun = \
19 { \
20 am__dry=no; \
21 case $$MAKEFLAGS in \
22 *\\[\ \ ]*) \
23 echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
24 | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
25 *) \
26 for am__flg in $$MAKEFLAGS; do \
27 case $$am__flg in \
28 *=*|--*) ;; \
29 *n*) am__dry=yes; break;; \
30 esac; \
31 done;; \
32 esac; \
33 test $$am__dry = yes; \
34 }
1835 pkgdatadir = $(datadir)/@PACKAGE@
1936 pkgincludedir = $(includedir)/@PACKAGE@
2037 pkglibdir = $(libdir)/@PACKAGE@
3855 DIST_COMMON = README $(dist_doc_DATA) $(srcdir)/Makefile.am \
3956 $(srcdir)/Makefile.in
4057 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
41 am__aclocal_m4_deps = $(top_srcdir)/configure.in
58 am__aclocal_m4_deps = $(top_srcdir)/configure.ac
4259 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
4360 $(ACLOCAL_M4)
4461 mkinstalldirs = $(install_sh) -d
4764 CONFIG_CLEAN_VPATH_FILES =
4865 SOURCES =
4966 DIST_SOURCES =
67 am__can_run_installinfo = \
68 case $$AM_UPDATE_INFO_DIR in \
69 n|no|NO) false;; \
70 *) (install-info --version) >/dev/null 2>&1;; \
71 esac
5072 am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
5173 am__vpath_adj = case $$p in \
5274 $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
6890 am__base_list = \
6991 sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
7092 sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
93 am__uninstall_files_from_dir = { \
94 test -z "$$files" \
95 || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
96 || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
97 $(am__cd) "$$dir" && rm -f $$files; }; \
98 }
7199 man1dir = $(mandir)/man1
72100 am__installdirs = "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(docdir)"
73101 NROFF = nroff
193221 dist_doc_DATA = user_help.html
194222 man_MANS = dillo.1
195223 EXTRA_DIST = \
196 $(man_MANS) \
197224 index.doc \
198225 lout.doc \
199226 dw-map.doc \
219246 dw-textblock-collapsing-spaces-1-2.png \
220247 dw-textblock-collapsing-spaces-2-1.png \
221248 dw-textblock-collapsing-spaces-2-2.png \
222 Cache.txt \
223 Cookies.txt \
224 Dillo.txt \
225 Dw.txt \
226 HtmlParser.txt \
227 IO.txt \
228 Images.txt \
229 Imgbuf.txt \
230 NC_design.txt \
231 Selection.txt \
232 Dpid.txt \
233 README
249 Cache.txt \
250 Cookies.txt \
251 Dillo.txt \
252 Dw.txt \
253 HtmlParser.txt \
254 IO.txt \
255 Images.txt \
256 Imgbuf.txt \
257 NC_design.txt \
258 Selection.txt \
259 Dpid.txt \
260 README \
261 dillo.1.in
234262
235263 all: all-am
236264
267295 $(am__aclocal_m4_deps):
268296 install-man1: $(man_MANS)
269297 @$(NORMAL_INSTALL)
270 test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)"
271 @list=''; test -n "$(man1dir)" || exit 0; \
272 { for i in $$list; do echo "$$i"; done; \
273 l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
274 sed -n '/\.1[a-z]*$$/p'; \
298 @list1=''; \
299 list2='$(man_MANS)'; \
300 test -n "$(man1dir)" \
301 && test -n "`echo $$list1$$list2`" \
302 || exit 0; \
303 echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \
304 $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \
305 { for i in $$list1; do echo "$$i"; done; \
306 if test -n "$$list2"; then \
307 for i in $$list2; do echo "$$i"; done \
308 | sed -n '/\.1[a-z]*$$/p'; \
309 fi; \
275310 } | while read p; do \
276311 if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
277312 echo "$$d$$p"; echo "$$p"; \
300335 sed -n '/\.1[a-z]*$$/p'; \
301336 } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
302337 -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
303 test -z "$$files" || { \
304 echo " ( cd '$(DESTDIR)$(man1dir)' && rm -f" $$files ")"; \
305 cd "$(DESTDIR)$(man1dir)" && rm -f $$files; }
338 dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir)
306339 install-dist_docDATA: $(dist_doc_DATA)
307340 @$(NORMAL_INSTALL)
308 test -z "$(docdir)" || $(MKDIR_P) "$(DESTDIR)$(docdir)"
309341 @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \
342 if test -n "$$list"; then \
343 echo " $(MKDIR_P) '$(DESTDIR)$(docdir)'"; \
344 $(MKDIR_P) "$(DESTDIR)$(docdir)" || exit 1; \
345 fi; \
310346 for p in $$list; do \
311347 if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
312348 echo "$$d$$p"; \
320356 @$(NORMAL_UNINSTALL)
321357 @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \
322358 files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
323 test -n "$$files" || exit 0; \
324 echo " ( cd '$(DESTDIR)$(docdir)' && rm -f" $$files ")"; \
325 cd "$(DESTDIR)$(docdir)" && rm -f $$files
359 dir='$(DESTDIR)$(docdir)'; $(am__uninstall_files_from_dir)
326360 tags: TAGS
327361 TAGS:
328362
390424
391425 installcheck: installcheck-am
392426 install-strip:
393 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
394 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
395 `test -z '$(STRIP)' || \
396 echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
427 if test -z '$(STRIP)'; then \
428 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
429 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
430 install; \
431 else \
432 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
433 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
434 "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
435 fi
397436 mostlyclean-generic:
398437
399438 clean-generic:
488527 uninstall-man uninstall-man1
489528
490529
530 dillo.1: $(srcdir)/dillo.1.in Makefile
531 sed 's%/usr/local%${prefix}%g' < $(srcdir)/dillo.1.in > dillo.1
532
491533 # Tell versions [3.59,3.63) of GNU make to not export all variables.
492534 # Otherwise a system limit (for SysV at least) may be exceeded.
493535 .NOEXPORT:
+0
-102
doc/dillo.1 less more
0 .TH dillo 1 "October 13, 2011" "" "USER COMMANDS"
1 .SH NAME
2 dillo \- web browser
3 .SH SYNOPSIS
4 .B dillo
5 .RI [ OPTION ]...
6 .RB [ \-\- ]
7 .RI [ URL | FILE ]...
8 .SH DESCRIPTION
9 .PP
10 Dillo is a lightweight graphical web browser that aims to be secure.
11 It handles HTTP internally, and FILE, FTP, and
12 DATA URIs are handled through a plugin system (dpi). In addition,
13 .I INSECURE
14 HTTPS support can be enabled. Both FTP and Dillo's download manager use the
15 .BR wget (1)
16 downloader.
17 .PP
18 Dillo displays HTML, text, PNG, JPEG, and GIF files.
19 It handles cookies, HTTP authentication (basic and digest), proxying (basic),
20 and some CSS.
21 .PP
22 Framesets are displayed as links to frames, and there is currently
23 no support for javascript or video.
24 .SH OPTIONS
25 .TP
26 \fB\-f\fR, \fB\-\-fullwindow\fR
27 Start in full window mode: hide address bar, navigation buttons, menu, and
28 status bar.
29 .TP
30 \fB\-g\fR, \fB\-\-geometry \fIGEO\fR
31 Set initial window position where \fIGEO\fR is
32 \fIW\fBx\fIH\fR[{\fB+\-\fR}\fIX\fR{\fB+\-\fR}\fIY\fR].
33 .TP
34 \fB\-h\fR, \fB\-\-help\fR
35 Display this help text and exit.
36 .TP
37 \fB\-l\fR, \fB\-\-local\fR
38 Don't load images for these URL(s).
39 .TP
40 \fB\-v\fR, \fB\-\-version\fR
41 Display version info and exit.
42 .TP
43 \fB\-x\fR, \fB\-\-xid \fIXID\fR
44 Open first Dillo window in an existing window whose window ID is \fIXID\fR.
45 .SH EXIT STATUS
46 .TP
47 .B 0
48 No error.
49 .TP
50 .B 1
51 Internal error.
52 .TP
53 .B 2
54 Error in command line arguments.
55 .SH ENVIRONMENT
56 .TP
57 .BR "HOME " "(or " "HOMEDRIVE " "and " "HOMEPATH " "on Cygwin)"
58 User's home directory.
59 .TP
60 .B http_proxy
61 URL of proxy to send HTTP traffic through.
62 .SH FILES
63 .TP
64 .I dpid
65 Dillo plugin daemon
66 .TP
67 .I dpidc
68 Control program for dpid.
69 .TP
70 .I ~/.dillo/bm.txt
71 User bookmarks
72 .TP
73 .I ~/.dillo/certs/
74 Saved certificates for HTTPS.
75 .TP
76 .I ~/.dillo/cookies.txt
77 Stored cookies
78 .TP
79 .I ~/.dillo/cookiesrc
80 Cookie settings
81 .TP
82 .I ~/.dillo/dillorc
83 Configuration file.
84 .TP
85 .I ~/.dillo/dpid_comm_keys
86 Keys used in dpi daemon communication.
87 .TP
88 .I ~/.dillo/dpidrc
89 Contains name of directory containing dpis, and associates
90 dpi files with protocols.
91 .TP
92 .I ~/.dillo/keysrc
93 Keybindings.
94 .TP
95 .I ~/.dillo/style.css
96 User style sheet
97 .SH SEE ALSO
98 .BR wget (1)
99 .PP
100 Dillo website:
101 .B http://www.dillo.org
0 .TH dillo 1 "November 5, 2012" "" "USER COMMANDS"
1 .SH NAME
2 dillo \- web browser
3 .SH SYNOPSIS
4 .B dillo
5 .RI [ OPTION ]...
6 .RB [ \-\- ]
7 .RI [ URL | FILE ]...
8 .SH DESCRIPTION
9 .PP
10 Dillo is a lightweight graphical web browser that aims to be secure.
11 It handles HTTP internally, and FILE, FTP, and
12 DATA URIs are handled through a plugin system (dpi). In addition,
13 .I INSECURE
14 HTTPS support can be enabled. Both FTP and Dillo's download manager use the
15 .BR wget (1)
16 downloader.
17 .PP
18 Dillo displays HTML, text, PNG, JPEG, and GIF files.
19 It handles cookies, HTTP authentication (basic and digest), proxying (basic),
20 and some CSS.
21 .PP
22 Framesets are displayed as links to frames, and there is currently
23 no support for javascript or video.
24 .PP
25 In order to use the hyphenation feature, pattern files from CTAN need to
26 be installed to
27 .IR /usr/local/lib/dillo/hyphenation/ .
28 This can be done with the script
29 .IR dillo-install-hyphenation .
30 Call it with ISO-639-1 language codes as arguments, or without arguments
31 to get more help.
32 .SH OPTIONS
33 .TP
34 \fB\-f\fR, \fB\-\-fullwindow\fR
35 Start in full window mode: hide address bar, navigation buttons, menu, and
36 status bar.
37 .TP
38 \fB\-g\fR, \fB\-geometry \fIGEO\fR
39 Set initial window position where \fIGEO\fR is
40 \fIW\fBx\fIH\fR[{\fB+\-\fR}\fIX\fR{\fB+\-\fR}\fIY\fR].
41 .TP
42 \fB\-h\fR, \fB\-\-help\fR
43 Display this help text and exit.
44 .TP
45 \fB\-l\fR, \fB\-\-local\fR
46 Don't load images or stylesheets for these URL(s).
47 .TP
48 \fB\-v\fR, \fB\-\-version\fR
49 Display version info and exit.
50 .TP
51 \fB\-x\fR, \fB\-\-xid \fIXID\fR
52 Open first Dillo window in an existing window whose window ID is \fIXID\fR.
53 .SH EXIT STATUS
54 .TP
55 .B 0
56 No error.
57 .TP
58 .B 1
59 Internal error.
60 .TP
61 .B 2
62 Error in command line arguments.
63 .SH ENVIRONMENT
64 .TP
65 .BR "HOME " "(or " "HOMEDRIVE " "and " "HOMEPATH " "on Cygwin)"
66 User's home directory.
67 .TP
68 .B http_proxy
69 URL of proxy to send HTTP traffic through.
70 .SH FILES
71 .TP
72 .I dpid
73 Dillo plugin daemon
74 .TP
75 .I dpidc
76 Control program for dpid.
77 .TP
78 .I ~/.dillo/bm.txt
79 User bookmarks
80 .TP
81 .I ~/.dillo/certs/
82 Saved certificates for HTTPS.
83 .TP
84 .I ~/.dillo/cookies.txt
85 Stored cookies
86 .TP
87 .I ~/.dillo/cookiesrc
88 Cookie settings
89 .TP
90 .I ~/.dillo/dillorc
91 Configuration file.
92 .TP
93 .I ~/.dillo/domainrc
94 Rules for cross-domain requests.
95 .TP
96 .I ~/.dillo/dpid_comm_keys
97 Keys used in dpi daemon communication.
98 .TP
99 .I ~/.dillo/dpidrc
100 Contains name of directory containing dpis, and associates
101 dpi files with protocols.
102 .TP
103 .I ~/.dillo/keysrc
104 Keybindings.
105 .TP
106 .I ~/.dillo/style.css
107 User style sheet.
108 .TP
109 .I /usr/local/lib/dillo/hyphenation/
110 Hyphenation pattern files.
111 .SH SEE ALSO
112 .BR wget (1)
113 .PP
114 Dillo website:
115 .B http://www.dillo.org
4949 \dot
5050 digraph G {
5151 node [shape=record, fontname=Helvetica, fontsize=10];
52 edge [arrowhead="open", arrowtail="none", labelfontname=Helvetica,
53 labelfontsize=10, color="#404040", labelfontcolor="#000080"];
52 edge [arrowhead="open", dir="both", arrowtail="none",
53 labelfontname=Helvetica, labelfontsize=10, color="#404040",
54 labelfontcolor="#000080"];
5455 fontname=Helvetica; fontsize=10;
5556
5657 "background renderer (as a part of style)" -> "image buffer" [headlabel="*",
7273 \dot
7374 digraph G {
7475 node [shape=record, fontname=Helvetica, fontsize=10];
75 edge [arrowhead="open", arrowtail="none", labelfontname=Helvetica,
76 labelfontsize=10, color="#404040", labelfontcolor="#000080"];
76 edge [arrowhead="open", dir="both", arrowtail="none",
77 labelfontname=Helvetica, labelfontsize=10, color="#404040",
78 labelfontcolor="#000080"];
7779 fontname=Helvetica; fontsize=10;
7880
7981 "DICache Entry";
112114
113115 BgRenderer -> Imgbuf [headlabel="1", taillabel="*"];
114116 BgRenderer -> BgAllocation [headlabel="*", taillabel="1"];
115 ImageRenderer -> BgRenderer [arrowhead="none", arrowtail="empty",
117 ImageRenderer -> BgRenderer [arrowhead="none", arrowtail="empty", dir="both",
116118 style="dashed"];
117 ImageRenderer -> Image [arrowhead="none", arrowtail="empty",
119 ImageRenderer -> Image [arrowhead="none", arrowtail="empty", dir="both",
118120 style="dashed"];
119121
120122 Style -> BgRenderer [headlabel="0..1", taillabel="1"];
121123
122 Widget -> Textblock [arrowhead="none", arrowtail="empty"];
124 Widget -> Textblock [arrowhead="none", arrowtail="empty", dir="both"];
123125 Textblock -> "Textblock::Word" [headlabel="*", taillabel="1"];
124 Widget -> Table [arrowhead="none", arrowtail="empty"];
126 Widget -> Table [arrowhead="none", arrowtail="empty", dir="both"];
125127 Table -> "Table::Row" [headlabel="*", taillabel="1"];
126 Widget -> Image [arrowhead="none", arrowtail="empty"];
128 Widget -> Image [arrowhead="none", arrowtail="empty", dir="both"];
127129
128 BgAllocation -> Widget [arrowhead="none", arrowtail="empty",
130 BgAllocation -> Widget [arrowhead="none", arrowtail="empty", dir="both",
129131 style="dashed"];
130132 BgAllocation -> "Textblock::Word" [arrowhead="none", arrowtail="empty",
131 style="dashed"];
133 dir="both", style="dashed"];
132134 BgAllocation -> "Table::Row" [arrowhead="none", arrowtail="empty",
133 style="dashed"];
135 dir="both", style="dashed"];
134136 }
135137 \enddot
136138
7878 Layout -> Widget [headlabel="1", taillabel="1", label="topLevel"];
7979 Widget -> Widget [headlabel="*", taillabel="1", label="children"];
8080
81 Widget -> Textblock [arrowhead="none", arrowtail="empty"];
82 Widget -> Table [arrowhead="none", arrowtail="empty"];
83 Widget -> Image [arrowhead="none", arrowtail="empty"];
84 Widget -> etc1 [arrowhead="none", arrowtail="empty"];
85 Textblock -> AlignedTextblock [arrowhead="none", arrowtail="empty"];
86 AlignedTextblock -> etc2 [arrowhead="none", arrowtail="empty"];
81 Widget -> Textblock [arrowhead="none", arrowtail="empty", dir="both"];
82 Widget -> Table [arrowhead="none", arrowtail="empty", dir="both"];
83 Widget -> Image [arrowhead="none", arrowtail="empty", dir="both"];
84 Widget -> etc1 [arrowhead="none", arrowtail="empty", dir="both"];
85 Textblock -> AlignedTextblock [arrowhead="none", arrowtail="empty",
86 dir="both"];
87 AlignedTextblock -> etc2 [arrowhead="none", arrowtail="empty", dir="both"];
8788
88 Platform -> FltkPlatform [arrowhead="none", arrowtail="empty",
89 Platform -> FltkPlatform [arrowhead="none", arrowtail="empty", dir="both",
8990 style="dashed"];
9091 FltkPlatform -> FltkView [headlabel="*", taillabel="1"];
9192
92 View -> FltkView [arrowhead="none", arrowtail="empty"];
93 FltkView -> FltkViewport [arrowhead="none", arrowtail="empty",
93 View -> FltkView [arrowhead="none", arrowtail="empty", dir="both"];
94 FltkView -> FltkViewport [arrowhead="none", arrowtail="empty", dir="both",
9495 style="dashed"];
95 FltkView -> FltkPreview [arrowhead="none", arrowtail="empty",
96 FltkView -> FltkPreview [arrowhead="none", arrowtail="empty", dir="both",
9697 style="dashed"];
9798 }
9899 \enddot
2222 GtkObject is replaced by the following:
2323
2424 <ul>
25 <li> object::Object is a common base class for many classes used dillo. In
26 the namespace ::object, there are also some more common classes and
27 interfaces.
25 <li> lout::object::Object is a common base class for many classes used
26 dillo. In the namespace lout::object, there are also some more common
27 classes and interfaces.
2828
29 <li> A sub class of object::Object is identity::IdentifiableObject, which
30 allows to determine the class at run-time (equivalent to GTK_CHECK_CAST
31 in GtkObject).
29 <li> A sub class of lout::object::Object is
30 lout::identity::IdentifiableObject, which allows to determine the
31 class at run-time (equivalent to GTK_CHECK_CAST in GtkObject).
3232
33 <li> For signals, there is the namespace ::signal.
33 <li> For signals, there is the namespace lout::signal.
3434 </ul>
3535
36 Hash tables, linked lists etc. can be found in the ::container namespace,
36 Hash tables, linked lists etc. can be found in the lout::container namespace,
3737 several useful macros from GLib have been implemented as inline functions
38 in the ::misc namespace.
38 in the lout::misc namespace.
3939
4040 As an alternative to the macros defined in list.h, there is also a template
41 class, misc::SimpleVector, which does the same.
41 class, lout::misc::SimpleVector, which does the same.
4242
4343 <h3>Changes in Dw</h3>
4444
55
66 <h2>Common Base Class</h2>
77
8 Many classes are derived from object::Object, which defines some
8 Many classes are derived from lout::object::Object, which defines some
99 general methods. See there for more information.
1010
1111 For the case, that you need primitive C++ types, there are some
1313
1414 <table>
1515 <tr><th>C++ Type <th>Wrapper Class
16 <tr><td>void* <td>object::Pointer
17 <tr><td>specific pointer <td>object::TypedPointer (template class)
18 <tr><td>int <td>object::Integer
19 <tr><td>const char* <td>object::ConstString
20 <tr><td>char* <td>object::String
16 <tr><td>void* <td>lout::object::Pointer
17 <tr><td>specific pointer <td>lout::object::TypedPointer (template class)
18 <tr><td>int <td>lout::object::Integer
19 <tr><td>const char* <td>lout::object::ConstString
20 <tr><td>char* <td>lout::object::String
2121 </table>
2222
2323
2424 <h2>Containers</h2>
2525
26 In the namespace ::container, several container classes are defined,
27 which all deal with instances of object::Object.
26 In the namespace lout::container, several container classes are defined,
27 which all deal with instances of lout::object::Object.
2828
2929 <h3>Untyped Containers</h3>
3030
31 In container::untyped, there are the following containers:
31 In lout::container::untyped, there are the following containers:
3232
3333 <ul>
34 <li>container::untyped::Vector, a dynamically increases array,
35 <li>container::untyped::List, a linked list,
36 <li>container::untyped::HashTable, a hash table, and
37 <li>container::untyped::Stack, a stack.
34 <li>lout::container::untyped::Vector, a dynamically increases array,
35 <li>lout::container::untyped::List, a linked list,
36 <li>lout::container::untyped::HashTable, a hash table, and
37 <li>lout::container::untyped::Stack, a stack.
3838 </ul>
3939
4040 All provide specific methods, but since they have a common base class,
41 container::untyped::Collection, they all provide iterators, by the
42 method container::untyped::Collection::iterator.
41 lout::container::untyped::Collection, they all provide iterators, by the
42 method lout::container::untyped::Collection::iterator.
4343
4444 <h3>Typed Containers</h3>
4545
46 container::typed provides wrappers for the container classes defined
47 in container::untyped, which are more type safe, by using C++
46 lout::container::typed provides wrappers for the container classes defined
47 in lout::container::untyped, which are more type safe, by using C++
4848 templates.
4949
5050
5151 <h2>Signals</h2>
5252
5353 For how to connect objects at run-time (to reduce dependencies), take a
54 look at the ::signal namespace.
54 look at the lout::signal namespace.
5555
56 There is also a base class signal::ObservedObject, which implements
56 There is also a base class lout::signal::ObservedObject, which implements
5757 signals for deletion.
5858
5959
6666 <h2>Identifying Classes at Runtime</h2>
6767
6868 If the class of an object must be identified at runtime,
69 identity::IdentifiableObject should be used as the base class, see
70 there for more details.
69 lout::identity::IdentifiableObject should be used as the base class,
70 see there for more details.
7171
7272
7373 <h2>Miscellaneous</h2>
7474
75 The ::misc namespace provides several miscellaneous stuff:
75 The lout::misc namespace provides several miscellaneous stuff:
7676
7777 <ul>
7878 <li> In some contexts, it is necessary to compare objects
79 (less/greater), for this, also misc::Comparable must be
80 implemented. For example., container::untyped::Vector::sort and
81 container::typed::Vector::sort cast the elements to
82 misc::Comparable. This can be mixed with object::Object.
83 <li> misc::SimpleVector, a simple, template based vector class (not
84 depending on object::Object),
85 <li> misc::StringBuffer, class for fast concatenation of a large number
79 (less/greater), for this, also lout::misc::Comparable must be
80 implemented. For example., lout::container::untyped::Vector::sort and
81 lout::container::typed::Vector::sort cast the elements to
82 lout::misc::Comparable. This can be mixed with lout::object::Object.
83 <li> lout::misc::SimpleVector, a simple, template based vector class
84 (not depending on lout::object::Object) (a variant for handling a
85 special case in an efficient way is lout::misc::NotSoSimpleVector),
86 <li> lout::misc::StringBuffer, class for fast concatenation of a large number
8687 of strings,
87 <li> misc::BitSet implements a bitset.
88 <li> useful (template) functions (misc::min, misc::max), and
89 <li> some functions useful for runtime checks (misc::assert,
90 misc::assertNotReached).
88 <li> lout::misc::BitSet implements a bitset.
89 <li> useful (template) functions (lout::misc::min, lout::misc::max), and
90 <li> some functions useful for runtime checks (lout::misc::assert,
91 lout::misc::assertNotReached).
9192 </ul>
9293
9394 */
1414 because of rounding errors, due to the integer division. This can be
1515 avoided by transforming the formula into
1616
17 \f[y_i = {(\sum_{j=0}^{j=i} x_j) a \over b} - \sum_{j=0}^{j=i} y_j\f]
17 \f[y_i = {(\sum_{j=0}^{j=i} x_j) a \over b} - \sum_{j=0}^{j=i-1} y_j\f]
1818
1919 Of corse, when all \f$y_i\f$ are calculated in a sequence,
20 \f$\sum_{j=0}^{j=i} x_j\f$ and \f$\sum_{j=0}^{j=i} y_j\f$ can be
20 \f$\sum_{j=0}^{j=i} x_j\f$ and \f$\sum_{j=0}^{j=i-1} y_j\f$ can be
2121 accumulated in the same loop.
2222
2323 */
9696 \dot
9797 digraph G {
9898 node [shape=record, fontname=Helvetica, fontsize=10];
99 edge [arrowhead="none", arrowtail="empty", labelfontname=Helvetica,
100 labelfontsize=10, color="#404040", labelfontcolor="#000080"];
99 edge [arrowhead="none", dir="both", arrowtail="empty",
100 labelfontname=Helvetica, labelfontsize=10, color="#404040",
101 labelfontcolor="#000080"];
101102 fontname=Helvetica; fontsize=10;
102103 A[color="#ff8080"];
103104 B[color="#ff8080"];
126127 \dot
127128 digraph G {
128129 node [shape=record, fontname=Helvetica, fontsize=10];
129 edge [arrowhead="none", arrowtail="empty", labelfontname=Helvetica,
130 labelfontsize=10, color="#404040", labelfontcolor="#000080"];
130 edge [arrowhead="none", arrowtail="empty", dir="both",
131 labelfontname=Helvetica, labelfontsize=10, color="#404040",
132 labelfontcolor="#000080"];
131133 fontname=Helvetica; fontsize=10;
132134
133135 A[color="#ff8080"];
158160 \dot
159161 digraph G {
160162 node [shape=record, fontname=Helvetica, fontsize=10];
161 edge [arrowhead="none", arrowtail="empty", labelfontname=Helvetica,
162 labelfontsize=10, color="#404040", labelfontcolor="#000080"];
163 edge [arrowhead="none", arrowtail="empty", dir="both",
164 labelfontname=Helvetica, labelfontsize=10, color="#404040",
165 labelfontcolor="#000080"];
163166 fontname=Helvetica; fontsize=10;
164167
165168 subgraph cluster_1 {
1313
1414 <table width="100%" bgcolor="#8080f0" cellspacing="4" cellpadding="5"
1515 border="0o">
16 <tr><td><big><font color="#302080">Welcome to Dillo 3.0</font></big>
16 <tr><td><big><font color="#302080">Welcome to Dillo 3</font></big>
1717 </table>
1818 <p>
1919
6262 <tr><td BGCOLOR="#70a0c0">
6363 <ul>
6464 <li> You can scroll around your Dillo main window using
65 CTRL+{PgUp|PgDwn|Home|End} or using the mouse middle button
65 {PgUp|PgDn|Home|End} or using the mouse middle button
6666 or mouse wheel. If nothing happens when keys are pressed, try
6767 <b> <font color="#5040a0">focusing</font></b> your Dillo main
6868 window first by clicking it (not on any link!:)).
8383 of the page currently viewed, but it will *not* reload embedded
8484 images during this process.
8585
86 <li> Dialogs can be closed with the ESC key<br>
87 (ESC also hides the findbar and control panels).
86 <li> Dialogs can be closed with the ESC key.
87 (ESC also hides the findbar and control panels)
8888
8989 <li> If you want to try a different control panel, right-click over the
9090 tools button and select one that suits your needs, then make
120120
121121 <tr><td bgcolor="#70a0c0">
122122 <p>
123 This one is very useful;
124 it can be found in the right-mouse-button menu<br>
125 Find text is tuned for speed so don't hesitate to use it even for minimal
123 This one is very useful; it can be found in the right-mouse-button menu.
124 Find text is tuned for speed, so don't hesitate to use it even for minimal
126125 searches.
127126 <p>
128127 <u>Semantics:</u>
136135 the above rules apply for every word in it. </li>
137136 </ul>
138137 <p>
139 Dillo will scroll the page and highlight found text!
138 Dillo will scroll the page and highlight found text.
140139 <p>
141140 <small>Default shortcut: [CTRL]+"F".</small>
142141
197196 If you want to enable cookies in dillo, please read
198197 <a href="Cookies.txt">Cookies.txt</a>. It's very easy --
199198 just a matter of setting up a <code>cookiesrc</code> file).
199 </td></tr>
200 </table>
201
202 <table WIDTH="100%" BORDER=1 CELLSPACING=0 CELLPADDING=3>
203 <tr ALIGN=LEFT VALIGN=TOP><td bgcolor="wheat">
204 <h4><font color="green">Ad blocking:</font></h4>
205 </td></tr>
206
207 <tr><td bgcolor="#70a0c0">
208 <p>
209 With a
210 <code>~/.dillo/<a href="http://www.dillo.org/domainrc">domainrc</a></code>
211 file, you can control how dillo handles automatic requests for resources
212 (like images and style sheets) that aren't at the same domain as the
213 original page.
200214 </td></tr>
201215 </table>
202216
302316 <tr><td>Ctrl-T <td>Tab <td>New tab
303317 <tr><td>Ctrl-W <td>Window <td>quit tab/window
304318 <tr><td>Ctrl-O <td>Open <td>Open file
319 <tr><td>Ctrl-U <td>(conventional) <td>view source
305320 <tr><td>Ctrl-B <td>Bookmarks <td>view bookmarks
306321 <tr><td>Ctrl-Q <td>Quit <td>Quit dillo
307322 <tr><td>Back or "<b>,</b>" <td>< <td>previous page
0 # Makefile.in generated by automake 1.11.1 from Makefile.am.
0 # Makefile.in generated by automake 1.11.6 from Makefile.am.
11 # @configure_input@
22
33 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
4 # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
5 # Inc.
4 # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
5 # Foundation, Inc.
66 # This Makefile.in is free software; the Free Software Foundation
77 # gives unlimited permission to copy and/or distribute it,
88 # with or without modifications, as long as this notice is preserved.
1515 @SET_MAKE@
1616
1717 VPATH = @srcdir@
18 am__make_dryrun = \
19 { \
20 am__dry=no; \
21 case $$MAKEFLAGS in \
22 *\\[\ \ ]*) \
23 echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
24 | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
25 *) \
26 for am__flg in $$MAKEFLAGS; do \
27 case $$am__flg in \
28 *=*|--*) ;; \
29 *n*) am__dry=yes; break;; \
30 esac; \
31 done;; \
32 esac; \
33 test $$am__dry = yes; \
34 }
1835 pkgdatadir = $(datadir)/@PACKAGE@
1936 pkgincludedir = $(includedir)/@PACKAGE@
2037 pkglibdir = $(libdir)/@PACKAGE@
4663 subdir = dpi
4764 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
4865 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
49 am__aclocal_m4_deps = $(top_srcdir)/configure.in
66 am__aclocal_m4_deps = $(top_srcdir)/configure.ac
5067 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
5168 $(ACLOCAL_M4)
5269 mkinstalldirs = $(install_sh) -d
124141 $(file_dpi_SOURCES) $(ftp_filter_dpi_SOURCES) \
125142 $(hello_filter_dpi_SOURCES) $(https_filter_dpi_SOURCES) \
126143 $(vsource_filter_dpi_SOURCES)
144 am__can_run_installinfo = \
145 case $$AM_UPDATE_INFO_DIR in \
146 n|no|NO) false;; \
147 *) (install-info --version) >/dev/null 2>&1;; \
148 esac
127149 ETAGS = etags
128150 CTAGS = ctags
129151 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
337359 $(am__aclocal_m4_deps):
338360 install-bookmarksPROGRAMS: $(bookmarks_PROGRAMS)
339361 @$(NORMAL_INSTALL)
340 test -z "$(bookmarksdir)" || $(MKDIR_P) "$(DESTDIR)$(bookmarksdir)"
341362 @list='$(bookmarks_PROGRAMS)'; test -n "$(bookmarksdir)" || list=; \
363 if test -n "$$list"; then \
364 echo " $(MKDIR_P) '$(DESTDIR)$(bookmarksdir)'"; \
365 $(MKDIR_P) "$(DESTDIR)$(bookmarksdir)" || exit 1; \
366 fi; \
342367 for p in $$list; do echo "$$p $$p"; done | \
343368 sed 's/$(EXEEXT)$$//' | \
344369 while read p p1; do if test -f $$p; \
374399 -test -z "$(bookmarks_PROGRAMS)" || rm -f $(bookmarks_PROGRAMS)
375400 install-cookiesPROGRAMS: $(cookies_PROGRAMS)
376401 @$(NORMAL_INSTALL)
377 test -z "$(cookiesdir)" || $(MKDIR_P) "$(DESTDIR)$(cookiesdir)"
378402 @list='$(cookies_PROGRAMS)'; test -n "$(cookiesdir)" || list=; \
403 if test -n "$$list"; then \
404 echo " $(MKDIR_P) '$(DESTDIR)$(cookiesdir)'"; \
405 $(MKDIR_P) "$(DESTDIR)$(cookiesdir)" || exit 1; \
406 fi; \
379407 for p in $$list; do echo "$$p $$p"; done | \
380408 sed 's/$(EXEEXT)$$//' | \
381409 while read p p1; do if test -f $$p; \
411439 -test -z "$(cookies_PROGRAMS)" || rm -f $(cookies_PROGRAMS)
412440 install-datauriPROGRAMS: $(datauri_PROGRAMS)
413441 @$(NORMAL_INSTALL)
414 test -z "$(datauridir)" || $(MKDIR_P) "$(DESTDIR)$(datauridir)"
415442 @list='$(datauri_PROGRAMS)'; test -n "$(datauridir)" || list=; \
443 if test -n "$$list"; then \
444 echo " $(MKDIR_P) '$(DESTDIR)$(datauridir)'"; \
445 $(MKDIR_P) "$(DESTDIR)$(datauridir)" || exit 1; \
446 fi; \
416447 for p in $$list; do echo "$$p $$p"; done | \
417448 sed 's/$(EXEEXT)$$//' | \
418449 while read p p1; do if test -f $$p; \
448479 -test -z "$(datauri_PROGRAMS)" || rm -f $(datauri_PROGRAMS)
449480 install-downloadsPROGRAMS: $(downloads_PROGRAMS)
450481 @$(NORMAL_INSTALL)
451 test -z "$(downloadsdir)" || $(MKDIR_P) "$(DESTDIR)$(downloadsdir)"
452482 @list='$(downloads_PROGRAMS)'; test -n "$(downloadsdir)" || list=; \
483 if test -n "$$list"; then \
484 echo " $(MKDIR_P) '$(DESTDIR)$(downloadsdir)'"; \
485 $(MKDIR_P) "$(DESTDIR)$(downloadsdir)" || exit 1; \
486 fi; \
453487 for p in $$list; do echo "$$p $$p"; done | \
454488 sed 's/$(EXEEXT)$$//' | \
455489 while read p p1; do if test -f $$p; \
485519 -test -z "$(downloads_PROGRAMS)" || rm -f $(downloads_PROGRAMS)
486520 install-filePROGRAMS: $(file_PROGRAMS)
487521 @$(NORMAL_INSTALL)
488 test -z "$(filedir)" || $(MKDIR_P) "$(DESTDIR)$(filedir)"
489522 @list='$(file_PROGRAMS)'; test -n "$(filedir)" || list=; \
523 if test -n "$$list"; then \
524 echo " $(MKDIR_P) '$(DESTDIR)$(filedir)'"; \
525 $(MKDIR_P) "$(DESTDIR)$(filedir)" || exit 1; \
526 fi; \
490527 for p in $$list; do echo "$$p $$p"; done | \
491528 sed 's/$(EXEEXT)$$//' | \
492529 while read p p1; do if test -f $$p; \
522559 -test -z "$(file_PROGRAMS)" || rm -f $(file_PROGRAMS)
523560 install-ftpPROGRAMS: $(ftp_PROGRAMS)
524561 @$(NORMAL_INSTALL)
525 test -z "$(ftpdir)" || $(MKDIR_P) "$(DESTDIR)$(ftpdir)"
526562 @list='$(ftp_PROGRAMS)'; test -n "$(ftpdir)" || list=; \
563 if test -n "$$list"; then \
564 echo " $(MKDIR_P) '$(DESTDIR)$(ftpdir)'"; \
565 $(MKDIR_P) "$(DESTDIR)$(ftpdir)" || exit 1; \
566 fi; \
527567 for p in $$list; do echo "$$p $$p"; done | \
528568 sed 's/$(EXEEXT)$$//' | \
529569 while read p p1; do if test -f $$p; \
559599 -test -z "$(ftp_PROGRAMS)" || rm -f $(ftp_PROGRAMS)
560600 install-helloPROGRAMS: $(hello_PROGRAMS)
561601 @$(NORMAL_INSTALL)
562 test -z "$(hellodir)" || $(MKDIR_P) "$(DESTDIR)$(hellodir)"
563602 @list='$(hello_PROGRAMS)'; test -n "$(hellodir)" || list=; \
603 if test -n "$$list"; then \
604 echo " $(MKDIR_P) '$(DESTDIR)$(hellodir)'"; \
605 $(MKDIR_P) "$(DESTDIR)$(hellodir)" || exit 1; \
606 fi; \
564607 for p in $$list; do echo "$$p $$p"; done | \
565608 sed 's/$(EXEEXT)$$//' | \
566609 while read p p1; do if test -f $$p; \
596639 -test -z "$(hello_PROGRAMS)" || rm -f $(hello_PROGRAMS)
597640 install-httpsPROGRAMS: $(https_PROGRAMS)
598641 @$(NORMAL_INSTALL)
599 test -z "$(httpsdir)" || $(MKDIR_P) "$(DESTDIR)$(httpsdir)"
600642 @list='$(https_PROGRAMS)'; test -n "$(httpsdir)" || list=; \
643 if test -n "$$list"; then \
644 echo " $(MKDIR_P) '$(DESTDIR)$(httpsdir)'"; \
645 $(MKDIR_P) "$(DESTDIR)$(httpsdir)" || exit 1; \
646 fi; \
601647 for p in $$list; do echo "$$p $$p"; done | \
602648 sed 's/$(EXEEXT)$$//' | \
603649 while read p p1; do if test -f $$p; \
633679 -test -z "$(https_PROGRAMS)" || rm -f $(https_PROGRAMS)
634680 install-vsourcePROGRAMS: $(vsource_PROGRAMS)
635681 @$(NORMAL_INSTALL)
636 test -z "$(vsourcedir)" || $(MKDIR_P) "$(DESTDIR)$(vsourcedir)"
637682 @list='$(vsource_PROGRAMS)'; test -n "$(vsourcedir)" || list=; \
683 if test -n "$$list"; then \
684 echo " $(MKDIR_P) '$(DESTDIR)$(vsourcedir)'"; \
685 $(MKDIR_P) "$(DESTDIR)$(vsourcedir)" || exit 1; \
686 fi; \
638687 for p in $$list; do echo "$$p $$p"; done | \
639688 sed 's/$(EXEEXT)$$//' | \
640689 while read p p1; do if test -f $$p; \
668717
669718 clean-vsourcePROGRAMS:
670719 -test -z "$(vsource_PROGRAMS)" || rm -f $(vsource_PROGRAMS)
671 bookmarks.dpi$(EXEEXT): $(bookmarks_dpi_OBJECTS) $(bookmarks_dpi_DEPENDENCIES)
720 bookmarks.dpi$(EXEEXT): $(bookmarks_dpi_OBJECTS) $(bookmarks_dpi_DEPENDENCIES) $(EXTRA_bookmarks_dpi_DEPENDENCIES)
672721 @rm -f bookmarks.dpi$(EXEEXT)
673722 $(LINK) $(bookmarks_dpi_OBJECTS) $(bookmarks_dpi_LDADD) $(LIBS)
674 cookies.dpi$(EXEEXT): $(cookies_dpi_OBJECTS) $(cookies_dpi_DEPENDENCIES)
723 cookies.dpi$(EXEEXT): $(cookies_dpi_OBJECTS) $(cookies_dpi_DEPENDENCIES) $(EXTRA_cookies_dpi_DEPENDENCIES)
675724 @rm -f cookies.dpi$(EXEEXT)
676725 $(LINK) $(cookies_dpi_OBJECTS) $(cookies_dpi_LDADD) $(LIBS)
677 datauri.filter.dpi$(EXEEXT): $(datauri_filter_dpi_OBJECTS) $(datauri_filter_dpi_DEPENDENCIES)
726 datauri.filter.dpi$(EXEEXT): $(datauri_filter_dpi_OBJECTS) $(datauri_filter_dpi_DEPENDENCIES) $(EXTRA_datauri_filter_dpi_DEPENDENCIES)
678727 @rm -f datauri.filter.dpi$(EXEEXT)
679728 $(LINK) $(datauri_filter_dpi_OBJECTS) $(datauri_filter_dpi_LDADD) $(LIBS)
680 downloads.dpi$(EXEEXT): $(downloads_dpi_OBJECTS) $(downloads_dpi_DEPENDENCIES)
729 downloads.dpi$(EXEEXT): $(downloads_dpi_OBJECTS) $(downloads_dpi_DEPENDENCIES) $(EXTRA_downloads_dpi_DEPENDENCIES)
681730 @rm -f downloads.dpi$(EXEEXT)
682731 $(downloads_dpi_LINK) $(downloads_dpi_OBJECTS) $(downloads_dpi_LDADD) $(LIBS)
683 file.dpi$(EXEEXT): $(file_dpi_OBJECTS) $(file_dpi_DEPENDENCIES)
732 file.dpi$(EXEEXT): $(file_dpi_OBJECTS) $(file_dpi_DEPENDENCIES) $(EXTRA_file_dpi_DEPENDENCIES)
684733 @rm -f file.dpi$(EXEEXT)
685734 $(LINK) $(file_dpi_OBJECTS) $(file_dpi_LDADD) $(LIBS)
686 ftp.filter.dpi$(EXEEXT): $(ftp_filter_dpi_OBJECTS) $(ftp_filter_dpi_DEPENDENCIES)
735 ftp.filter.dpi$(EXEEXT): $(ftp_filter_dpi_OBJECTS) $(ftp_filter_dpi_DEPENDENCIES) $(EXTRA_ftp_filter_dpi_DEPENDENCIES)
687736 @rm -f ftp.filter.dpi$(EXEEXT)
688737 $(LINK) $(ftp_filter_dpi_OBJECTS) $(ftp_filter_dpi_LDADD) $(LIBS)
689 hello.filter.dpi$(EXEEXT): $(hello_filter_dpi_OBJECTS) $(hello_filter_dpi_DEPENDENCIES)
738 hello.filter.dpi$(EXEEXT): $(hello_filter_dpi_OBJECTS) $(hello_filter_dpi_DEPENDENCIES) $(EXTRA_hello_filter_dpi_DEPENDENCIES)
690739 @rm -f hello.filter.dpi$(EXEEXT)
691740 $(LINK) $(hello_filter_dpi_OBJECTS) $(hello_filter_dpi_LDADD) $(LIBS)
692 https.filter.dpi$(EXEEXT): $(https_filter_dpi_OBJECTS) $(https_filter_dpi_DEPENDENCIES)
741 https.filter.dpi$(EXEEXT): $(https_filter_dpi_OBJECTS) $(https_filter_dpi_DEPENDENCIES) $(EXTRA_https_filter_dpi_DEPENDENCIES)
693742 @rm -f https.filter.dpi$(EXEEXT)
694743 $(LINK) $(https_filter_dpi_OBJECTS) $(https_filter_dpi_LDADD) $(LIBS)
695 vsource.filter.dpi$(EXEEXT): $(vsource_filter_dpi_OBJECTS) $(vsource_filter_dpi_DEPENDENCIES)
744 vsource.filter.dpi$(EXEEXT): $(vsource_filter_dpi_OBJECTS) $(vsource_filter_dpi_DEPENDENCIES) $(EXTRA_vsource_filter_dpi_DEPENDENCIES)
696745 @rm -f vsource.filter.dpi$(EXEEXT)
697746 $(LINK) $(vsource_filter_dpi_OBJECTS) $(vsource_filter_dpi_LDADD) $(LIBS)
698747
854903
855904 installcheck: installcheck-am
856905 install-strip:
857 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
858 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
859 `test -z '$(STRIP)' || \
860 echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
906 if test -z '$(STRIP)'; then \
907 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
908 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
909 install; \
910 else \
911 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
912 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
913 "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
914 fi
861915 mostlyclean-generic:
862916
863917 clean-generic:
804804
805805 /* Get the value for the attribute and store it */
806806 if (first_attr) {
807 time_t now;
808 struct tm *tm;
809
807810 if (*str != '=' || *attr == '\0') {
808811 /* disregard nameless cookie */
809812 dFree(attr);
814817 cookie->value = Cookies_parse_value(&str);
815818
816819 /* let's arbitrarily initialise with a year for now */
817 time_t now = time(NULL);
818 struct tm *tm = gmtime(&now);
820 now = time(NULL);
821 tm = gmtime(&now);
819822 ++tm->tm_year;
820823 cookie->expires_at = mktime(tm);
821824 if (cookie->expires_at == (time_t) -1)
846849 dFree(value);
847850 } else if (dStrAsciiCasecmp(attr, "Expires") == 0) {
848851 if (!max_age) {
852 struct tm *tm;
853
849854 value = Cookies_parse_value(&str);
850855 Cookies_unquote_string(value);
851856 _MSG("Expires attribute gives %s\n", value);
852 struct tm *tm = Cookies_parse_date(value);
857 tm = Cookies_parse_date(value);
853858 if (tm) {
854859 tm->tm_sec += Cookies_server_timediff(server_date);
855860 cookie->expires_at = mktime(tm);
10361041
10371042 if (tld_len > 0) {
10381043 /* These TLDs were chosen by examining the current publicsuffix list
1039 * in September 2011 and picking out those where it was simplest for
1040 * them to describe the situation by beginning with a "*.[tld]" rule.
1044 * in October 2012 and picking out those where it was simplest for
1045 * them to describe the situation by beginning with a "*.[tld]" rule
1046 * or every rule was "[something].[tld]".
10411047 */
1042 const char *const tlds[] = {"ar","au","bd","bn","bt","ck","cy",
1043 "er","et","fj","fk","gt","gu","id",
1044 "il","jm","ke","kh","kw","ml","mm","mt",
1045 "mz","ni","np","nz","om","pg","py","qa",
1046 "sv","tr","uk","uy","ve","ye","yu","za",
1047 "zm","zw"};
1048 const char *const tlds[] = {"ar","au","bd","bn","ck","cy","er","et",
1049 "fj","fk","gt","gu","il","jm","ke","kh",
1050 "kp","kw","lb","lr","mm","mt","mz","ni",
1051 "np","nz","om","pg","py","sv","tr","uk",
1052 "ve","ye","za","zm","zw"};
10481053 uint_t i, tld_num = sizeof(tlds) / sizeof(tlds[0]);
10491054
10501055 for (i = 0; i < tld_num; i++) {
149149 }
150150 *dest = 0;
151151
152 *p_sz = (size_t)(dest - new_str);
152153 new_str = dRealloc(new_str, sizeof(char) * (dest - new_str + 1));
153 *p_sz = (size_t)(dest - new_str);
154154 return new_str;
155155 }
156156
215215
216216 /*
217217 * Get mime type from the data URI.
218 * TODO: there's no point in handling "charset" because current dillo
219 * only handles ISO-LATIN-1. The FLTK2 version (utf-8) could use it in the
220 * future.
221218 */
222219 static char *datauri_get_mime(char *url)
223220 {
242239 if (len == 0) {
243240 mime_type = dStrdup("text/plain;charset=US-ASCII");
244241 } else if (!dStrnAsciiCasecmp(buf, "charset", 7)) {
245 mime_type = dStrconcat("text/plain", buf, NULL);
242 mime_type = dStrconcat("text/plain;", buf, NULL);
246243 } else {
247244 mime_type = dStrdup(buf);
248245 }
2929 #include <sys/wait.h>
3030
3131 #include <FL/Fl.H>
32 #include <FL/fl_ask.H>
3233 #include <FL/fl_draw.H>
3334 #include <FL/Fl_File_Chooser.H>
3435 #include <FL/Fl_Window.H>
4748 */
4849 #define _MSG(...)
4950 #define MSG(...) printf("[downloads dpi]: " __VA_ARGS__)
50
51 /*
52 * Internal types
53 */
54 typedef enum {
55 DL_NEWFILE,
56 DL_CONTINUE,
57 DL_RENAME,
58 DL_OVERWRITE,
59 DL_ABORT
60 } DLAction;
6151
6252 /*
6353 * Class declarations
125115 Fl_Widget *prTitle, *prGot, *prSize, *prRate, *pr_Rate, *prETA, *prETAt;
126116
127117 public:
128 DLItem(const char *full_filename, const char *url, DLAction action);
118 DLItem(const char *full_filename, const char *url);
129119 ~DLItem();
130120 void child_init();
131121 void father_init();
179169
180170 public:
181171 DLWin(int ww, int wh);
182 void add(const char *full_filename, const char *url, DLAction action);
172 void add(const char *full_filename, const char *url);
183173 void del(int n_item);
184174 int num();
185175 int num_running();
187177 void show() { mWin->show(); }
188178 void hide() { mWin->hide(); }
189179 void abort_all();
190 DLAction check_filename(char **p_dl_dest);
191180 };
192181
193182 /*
290279 i->prButton_cb();
291280 }
292281
293 DLItem::DLItem(const char *full_filename, const char *url, DLAction action)
282 DLItem::DLItem(const char *full_filename, const char *url)
294283 {
295284 struct stat ss;
296285 const char *p;
331320 dl_argv = new char*[8];
332321 int i = 0;
333322 dl_argv[i++] = (char*)"wget";
334 if (action == DL_CONTINUE) {
335 if (stat(fullname, &ss) == 0)
336 init_bytesize = (int)ss.st_size;
337 dl_argv[i++] = (char*)"-c";
338 }
323 if (stat(fullname, &ss) == 0)
324 init_bytesize = (int)ss.st_size;
325 dl_argv[i++] = (char*)"-c";
339326 dl_argv[i++] = (char*)"--load-cookies";
340327 dl_argv[i++] = dStrconcat(dGethomedir(), "/.dillo/cookies.txt", NULL);
341328 dl_argv[i++] = (char*)"-O";
453440 void DLItem::abort_dl()
454441 {
455442 if (!log_done()) {
456 close(LogPipe[0]);
443 dClose(LogPipe[0]);
457444 Fl::remove_fd(LogPipe[0]);
458445 log_done(1);
459446 // Stop wget
471458
472459 void DLItem::child_init()
473460 {
474 close(0); // stdin
475 close(1); // stdout
476 close(LogPipe[0]);
461 dClose(0); // stdin
462 dClose(1); // stdout
463 dClose(LogPipe[0]);
477464 dup2(LogPipe[1], 2); // stderr
478465 // set the locale to C for log parsing
479466 setenv("LC_ALL", "C", 1);
630617 perror("read, ");
631618 break;
632619 } else if (st == 0) {
633 close(fd_in);
620 dClose(fd_in);
634621 Fl::remove_fd(fd_in, 1);
635622 dl_item->log_done(1);
636623 break;
642629
643630 void DLItem::father_init()
644631 {
645 close(LogPipe[1]);
632 dClose(LogPipe[1]);
646633 Fl::add_fd(LogPipe[0], 1, read_log_cb, this); // Read
647634
648635 // Start the timer after the child is running.
840827 // DLWin ---------------------------------------------------------------------
841828
842829 /*
843 * Make a new name and place it in 'dl_dest'.
844 */
845 static void make_new_name(char **dl_dest, const char *url)
846 {
847 Dstr *gstr = dStr_new(*dl_dest);
848 int idx = gstr->len;
849
850 if (gstr->str[idx - 1] != '/'){
851 dStr_append_c(gstr, '/');
852 ++idx;
853 }
854
855 /* Use a mangled url as name */
856 dStr_append(gstr, url);
857 for ( ; idx < gstr->len; ++idx)
858 if (!isalnum(gstr->str[idx]))
859 gstr->str[idx] = '_';
860
861 /* free memory */
862 dFree(*dl_dest);
863 *dl_dest = gstr->str;
864 dStr_free(gstr, FALSE);
865 }
866
867 /*
868830 * Callback function for the request socket.
869831 * Read the request, parse and start a new download.
870832 */
873835 struct sockaddr_un clnt_addr;
874836 int sock_fd;
875837 socklen_t csz;
876 struct stat sb;
877838 Dsh *sh = NULL;
878839 char *dpip_tag = NULL, *cmd = NULL, *url = NULL, *dl_dest = NULL;
879 DLAction action = DL_ABORT; /* compiler happiness */
880840
881841 /* Initialize the value-result parameter */
882842 csz = sizeof(struct sockaddr_un);
930890 MSG("Failed to parse 'destination' in {%s}\n", dpip_tag);
931891 goto end;
932892 }
933 /* 'dl_dest' may be a directory */
934 if (stat(dl_dest, &sb) == 0 && S_ISDIR(sb.st_mode)) {
935 make_new_name(&dl_dest, url);
936 }
937 action = dl_win->check_filename(&dl_dest);
938 if (action != DL_ABORT) {
939 // Start the whole thing within FLTK.
940 dl_win->add(dl_dest, url, action);
941 } else if (dl_win->num() == 0) {
942 exit(0);
943 }
893 dl_win->add(dl_dest, url);
944894
945895 end:
946896 dFree(cmd);
959909 "ABORT them and EXIT anyway?";
960910
961911 if (dl_win && dl_win->num_running() > 0) {
912 fl_message_title("Dillo Downloads: Abort downloads?");
962913 int ch = fl_choice("%s", "Cancel", "*No", "Yes", msg);
963914 if (ch == 0 || ch == 1)
964915 return;
972923 * Add a new download request to the main window and
973924 * fork a child to do the job.
974925 */
975 void DLWin::add(const char *full_filename, const char *url, DLAction action)
976 {
977 DLItem *dl_item = new DLItem(full_filename, url, action);
926 void DLWin::add(const char *full_filename, const char *url)
927 {
928 DLItem *dl_item = new DLItem(full_filename, url);
978929 mDList->add(dl_item);
979930 mPG->insert(*dl_item->get_widget(), 0);
980931
999950 }
1000951
1001952 /*
1002 * Decide what to do when the filename already exists.
1003 * (renaming takes place here when necessary)
1004 */
1005 DLAction DLWin::check_filename(char **p_fullname)
1006 {
1007 struct stat ss;
1008 Dstr *ds;
1009 int ch;
1010 DLAction ret = DL_ABORT;
1011
1012 if (stat(*p_fullname, &ss) == -1)
1013 return DL_NEWFILE;
1014
1015 ds = dStr_sized_new(128);
1016 dStr_sprintf(ds,
1017 "The file:\n %s (%d Bytes)\nalready exists. What do we do?",
1018 *p_fullname, (int)ss.st_size);
1019 ch = fl_choice("%s", "Abort", "Continue", "Rename", ds->str);
1020 dStr_free(ds, 1);
1021 MSG("Choice %d\n", ch);
1022 if (ch == 2) {
1023 const char *p;
1024 p = fl_file_chooser("Enter a new name:", NULL, *p_fullname);
1025 if (p) {
1026 dFree(*p_fullname);
1027 *p_fullname = dStrdup(p);
1028 ret = check_filename(p_fullname);
1029 }
1030 } else if (ch == 1) {
1031 ret = DL_CONTINUE;
1032 }
1033 return ret;
1034 }
1035
1036 /*
1037953 * Delete a download request from the main window.
1038954 */
1039955 void DLWin::del(int n_item)
10941010 public:
10951011 void resize(int x_, int y_, int w_, int h_)
10961012 {
1013 Fl_Scroll::resize(x_, y_, w_, h_);
10971014 Fl_Widget *resizable_ = resizable();
1015 int sb_size =
1016 resizable_->h() <= h() ? 0 :
1017 scrollbar_size() ? scrollbar_size() :
1018 Fl::scrollbar_size();
10981019 if (resizable_)
10991020 resizable_->resize(resizable_->x(),
11001021 resizable_->y(),
1101 w() - scrollbar_size(),
1022 w() - sb_size,
11021023 resizable_->h());
1103 Fl_Scroll::resize(x_, y_, w_, h_);
11041024 }
11051025 DlScroll(int x, int y, int w, int h, const char *l = 0)
11061026 : Fl_Scroll(x, y, w, h, l)
11171037 mDList = new DLItemList();
11181038
11191039 // Create the empty main window
1120 mWin = new Fl_Window(ww, wh, "Downloads:");
1040 mWin = new Fl_Window(ww, wh, "Dillo Downloads");
11211041 mWin->begin();
11221042 mScroll = new DlScroll(0,0,ww,wh);
11231043 mScroll->begin();
11361056 sigaddset(&mask_sigchld, SIGCHLD);
11371057 est_sigchld();
11381058
1059 fl_message_title_default("Dillo Downloads: Message");
1060
11391061 // Set the cleanup timeout
11401062 Fl::add_timeout(1.0, cleanup_cb, mDList);
11411063 // Set the update timeout
6161 /*---------------------------------------------------------------------------*/
6262
6363 /* TODO: could use dStr ADT! */
64 typedef struct ContentType_ {
64 typedef struct {
6565 const char *str;
6666 int len;
6767 } ContentType_t;
153153 char *esc_url;
154154
155155 if (dl_argv) {
156 dFree(dl_argv[2]);
156 dFree(dl_argv[3]);
157157 dFree(dl_argv);
158158 }
159159 dl_argv = dNew(char*, 10);
163163 Filter_smtp_hack(esc_url);
164164
165165 dl_argv[0] = "wget";
166 dl_argv[1] = "-O-";
167 dl_argv[2] = esc_url;
168 dl_argv[3] = NULL;
166 dl_argv[1] = "-t1"; /* try once, default is 20 */
167 dl_argv[2] = "-O-";
168 dl_argv[3] = esc_url;
169 dl_argv[4] = NULL;
169170 }
170171
171172 /*
185186 pid_t ch_pid;
186187 int aborted = 0;
187188 int DataPipe[2];
189
190 MSG("try_ftp_transfer: url=%s\n", url);
188191
189192 if (pipe(DataPipe) < 0) {
190193 MSG("pipe, %s\n", dStrerror(errno));
315318 if ((st = try_ftp_transfer(url)) == -1) {
316319 /* Transfer failed, the requested file may not exist or be a symlink
317320 * to a directory. Try again... */
318 if ((p = strrchr(url, '/')) && p[1]) {
321 if ((p = strrchr(url, '/')) && p[1] &&
322 p > url && p[-1] != '/') {
319323 url2 = dStrconcat(url, "/", NULL);
320324 st = try_ftp_transfer(url2);
321325 }
9090 /* Let's confirm the request */
9191 /* NOTE: you can send less alternatives (e.g. only alt1 and alt2) */
9292 d_cmd = a_Dpip_build_cmd(
93 "cmd=%s msg=%s alt1=%s alt2=%s alt3=%s alt4=%s alt5=%s",
94 "dialog", "Do you want to see the hello page?",
93 "cmd=%s title=%s msg=%s alt1=%s alt2=%s alt3=%s alt4=%s alt5=%s",
94 "dialog", "Dillo: Hello", "Do you want to see the hello page?",
9595 choice[1], choice[2], choice[3], choice[4], choice[5]);
9696 a_Dpip_dsh_write_str(sh, 1, d_cmd);
9797 dFree(d_cmd);
7474
7575 #ifdef ENABLE_SSL
7676
77 #include <openssl/err.h>
78 #include <openssl/rand.h>
7779 #include <openssl/ssl.h>
78 #include <openssl/rand.h>
7980
8081 static int get_network_connection(char * url);
8182 static int handle_certificate_problem(SSL * ssl_connection);
152153 MSG("Error creating SSL context\n");
153154 exit_error = 1;
154155 }
156 }
157
158 /* Do not use the SSLv2 protocol. */
159 if (exit_error == 0){
160 SSL_CTX_set_options(ssl_context, SSL_OP_NO_SSLv2);
155161 }
156162
157163 /*Set directory to load certificates from*/
285291 /*Actually do SSL connection handshake*/
286292 if (SSL_connect(ssl_connection) != 1){
287293 MSG("SSL_connect failed\n");
294 ERR_print_errors_fp(stderr);
288295 exit_error = 1;
289296 }
290297 }
329336 dFree(check_cert);
330337
331338 if (network_socket != -1){
332 close(network_socket);
339 dClose(network_socket);
333340 network_socket = -1;
334341 }
335342 if (ssl_connection != NULL){
401408
402409 s = socket(hp->h_addrtype, SOCK_STREAM, 0);
403410 if (connect(s, (struct sockaddr *)&address, sizeof(address)) != 0){
404 close(s);
411 dClose(s);
405412 s = -1;
406413 MSG("errno: %i\n", errno);
407414 }
433440 if (remote_cert == NULL){
434441 /*Inform user that remote system cannot be trusted*/
435442 d_cmd = a_Dpip_build_cmd(
436 "cmd=%s msg=%s alt1=%s alt2=%s",
443 "cmd=%s title=%s msg=%s alt1=%s alt2=%s",
437444 "dialog",
445 "Dillo HTTPS: No certificate!",
438446 "The remote system is NOT presenting a certificate.\n"
439447 "This site CAN NOT be trusted. Sending data is NOT SAFE.\n"
440448 "What do I do?",
476484 msg = dStrconcat("The remote certificate is self-signed and "
477485 "untrusted.\nFor address: ", buf, NULL);
478486 d_cmd = a_Dpip_build_cmd(
479 "cmd=%s msg=%s alt1=%s alt2=%s alt3=%s",
480 "dialog", msg, "Continue", "Cancel", "Save Certificate");
487 "cmd=%s title=%s msg=%s alt1=%s alt2=%s alt3=%s",
488 "dialog",
489 "Dillo HTTPS: Untrusted certificate!", msg,
490 "Continue", "Cancel", "Save Certificate");
481491 a_Dpip_dsh_write_str(sh, 1, d_cmd);
482492 dFree(d_cmd);
483493 dFree(msg);
503513 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
504514 case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
505515 d_cmd = a_Dpip_build_cmd(
506 "cmd=%s msg=%s alt1=%s alt2=%s",
507 "dialog",
516 "cmd=%s title=%s msg=%s alt1=%s alt2=%s",
517 "dialog",
518 "Dillo HTTPS: Missing certificate issuer!",
508519 "The issuer for the remote certificate cannot be found\n"
509520 "The authenticity of the remote certificate cannot be trusted",
510521 "Continue", "Cancel");
522533 case X509_V_ERR_CERT_SIGNATURE_FAILURE:
523534 case X509_V_ERR_CRL_SIGNATURE_FAILURE:
524535 d_cmd = a_Dpip_build_cmd(
525 "cmd=%s msg=%s alt1=%s alt2=%s",
526 "dialog",
536 "cmd=%s title=%s msg=%s alt1=%s alt2=%s",
537 "dialog",
538 "Dillo HTTPS: Invalid certificate!",
527539 "The remote certificate signature could not be read\n"
528540 "or is invalid and should not be trusted",
529541 "Continue", "Cancel");
538550 case X509_V_ERR_CERT_NOT_YET_VALID:
539551 case X509_V_ERR_CRL_NOT_YET_VALID:
540552 d_cmd = a_Dpip_build_cmd(
541 "cmd=%s msg=%s alt1=%s alt2=%s",
542 "dialog",
553 "cmd=%s title=%s msg=%s alt1=%s alt2=%s",
554 "dialog",
555 "Dillo HTTPS: Certificate not yet valid!",
543556 "Part of the remote certificate is not yet valid\n"
544557 "Certificates usually have a range of dates over which\n"
545558 "they are to be considered valid, and the certificate\n"
557570 case X509_V_ERR_CERT_HAS_EXPIRED:
558571 case X509_V_ERR_CRL_HAS_EXPIRED:
559572 d_cmd = a_Dpip_build_cmd(
560 "cmd=%s msg=%s alt1=%s alt2=%s",
561 "dialog",
573 "cmd=%s title=%s msg=%s alt1=%s alt2=%s",
574 "dialog",
575 "Dillo HTTPS: Expired certificate!",
562576 "The remote certificate has expired. The certificate\n"
563577 "wasn't designed to last this long. You should avoid \n"
564578 "this site.",
575589 case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
576590 case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
577591 d_cmd = a_Dpip_build_cmd(
578 "cmd=%s msg=%s alt1=%s alt2=%s",
579 "dialog",
592 "cmd=%s title=%s msg=%s alt1=%s alt2=%s",
593 "dialog",
594 "Dillo HTTPS: Certificate error!",
580595 "There was an error in the certificate presented.\n"
581596 "Some of the certificate data was improperly formatted\n"
582597 "making it impossible to determine if the certificate\n"
595610 case X509_V_ERR_CERT_REJECTED:
596611 case X509_V_ERR_KEYUSAGE_NO_CERTSIGN:
597612 d_cmd = a_Dpip_build_cmd(
598 "cmd=%s msg=%s alt1=%s alt2=%s",
599 "dialog",
613 "cmd=%s title=%s msg=%s alt1=%s alt2=%s",
614 "dialog",
615 "Dillo HTTPS: Certificate chain error!",
600616 "One of the certificates in the chain is being used\n"
601617 "incorrectly (possibly due to configuration problems\n"
602618 "with the remote system. The connection should not\n"
613629 case X509_V_ERR_AKID_SKID_MISMATCH:
614630 case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH:
615631 d_cmd = a_Dpip_build_cmd(
616 "cmd=%s msg=%s alt1=%s alt2=%s",
617 "dialog",
632 "cmd=%s title=%s msg=%s alt1=%s alt2=%s",
633 "dialog",
634 "Dillo HTTPS: Certificate mismatch!",
618635 "Some of the information presented by the remote system\n"
619636 "does not match other information presented\n"
620637 "This may be an attempt to eavesdrop on communications",
628645 break;
629646 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
630647 d_cmd = a_Dpip_build_cmd(
631 "cmd=%s msg=%s alt1=%s alt2=%s",
632 "dialog",
648 "cmd=%s title=%s msg=%s alt1=%s alt2=%s",
649 "dialog",
650 "Dillo HTTPS: Self signed certificate!",
633651 "Self signed certificate in certificate chain. The certificate "
634652 "chain could be built up using the untrusted certificates but the "
635653 "root could not be found locally.",
643661 break;
644662 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
645663 d_cmd = a_Dpip_build_cmd(
646 "cmd=%s msg=%s alt1=%s alt2=%s",
647 "dialog",
664 "cmd=%s title=%s msg=%s alt1=%s alt2=%s",
665 "dialog",
666 "Dillo HTTPS: Missing issuer certificate!",
648667 "Unable to get local issuer certificate. The issuer certificate "
649668 "of an untrusted certificate cannot be found.",
650669 "Continue", "Cancel");
659678 snprintf(buf, 80,
660679 "The remote certificate cannot be verified (code %ld)", st);
661680 d_cmd = a_Dpip_build_cmd(
662 "cmd=%s msg=%s alt1=%s alt2=%s",
663 "dialog", buf, "Continue", "Cancel");
681 "cmd=%s title=%s msg=%s alt1=%s alt2=%s",
682 "dialog",
683 "Dillo HTTPS: Unverifiable certificate!", buf,
684 "Continue", "Cancel");
664685 a_Dpip_dsh_write_str(sh, 1, d_cmd);
665686 dFree(d_cmd);
666687 response_number = dialog_get_answer_number();
7777 while (*p) {
7878 snprintf(line_str, 32, "%2d: ", line);
7979 a_Dpip_dsh_write_str(sh, 0, line_str);
80 if ((p = strchr(q, '\n'))) {
80 if ((p = strpbrk(q, "\r\n"))) {
8181 a_Dpip_dsh_write(sh, 0, q, p - q + 1);
82 if (p[1] == '\r')
82 if (*p == '\r' && p[1] == '\n')
8383 ++p;
8484 ++line;
8585 } else {
0 # Makefile.in generated by automake 1.11.1 from Makefile.am.
0 # Makefile.in generated by automake 1.11.6 from Makefile.am.
11 # @configure_input@
22
33 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
4 # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
5 # Inc.
4 # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
5 # Foundation, Inc.
66 # This Makefile.in is free software; the Free Software Foundation
77 # gives unlimited permission to copy and/or distribute it,
88 # with or without modifications, as long as this notice is preserved.
1616
1717
1818 VPATH = @srcdir@
19 am__make_dryrun = \
20 { \
21 am__dry=no; \
22 case $$MAKEFLAGS in \
23 *\\[\ \ ]*) \
24 echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
25 | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
26 *) \
27 for am__flg in $$MAKEFLAGS; do \
28 case $$am__flg in \
29 *=*|--*) ;; \
30 *n*) am__dry=yes; break;; \
31 esac; \
32 done;; \
33 esac; \
34 test $$am__dry = yes; \
35 }
1936 pkgdatadir = $(datadir)/@PACKAGE@
2037 pkgincludedir = $(includedir)/@PACKAGE@
2138 pkglibdir = $(libdir)/@PACKAGE@
3956 subdir = dpid
4057 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in TODO
4158 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
42 am__aclocal_m4_deps = $(top_srcdir)/configure.in
59 am__aclocal_m4_deps = $(top_srcdir)/configure.ac
4360 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
4461 $(ACLOCAL_M4)
4562 mkinstalldirs = $(install_sh) -d
6885 LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
6986 SOURCES = $(dpid_SOURCES) $(dpidc_SOURCES)
7087 DIST_SOURCES = $(dpid_SOURCES) $(dpidc_SOURCES)
88 am__can_run_installinfo = \
89 case $$AM_UPDATE_INFO_DIR in \
90 n|no|NO) false;; \
91 *) (install-info --version) >/dev/null 2>&1;; \
92 esac
7193 am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
7294 am__vpath_adj = case $$p in \
7395 $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
89111 am__base_list = \
90112 sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
91113 sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
114 am__uninstall_files_from_dir = { \
115 test -z "$$files" \
116 || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
117 || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
118 $(am__cd) "$$dir" && rm -f $$files; }; \
119 }
92120 DATA = $(sysconf_DATA)
93121 ETAGS = etags
94122 CTAGS = ctags
274302 $(am__aclocal_m4_deps):
275303 install-binPROGRAMS: $(bin_PROGRAMS)
276304 @$(NORMAL_INSTALL)
277 test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
278305 @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
306 if test -n "$$list"; then \
307 echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
308 $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
309 fi; \
279310 for p in $$list; do echo "$$p $$p"; done | \
280311 sed 's/$(EXEEXT)$$//' | \
281312 while read p p1; do if test -f $$p; \
309340
310341 clean-binPROGRAMS:
311342 -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
312 dpid$(EXEEXT): $(dpid_OBJECTS) $(dpid_DEPENDENCIES)
343 dpid$(EXEEXT): $(dpid_OBJECTS) $(dpid_DEPENDENCIES) $(EXTRA_dpid_DEPENDENCIES)
313344 @rm -f dpid$(EXEEXT)
314345 $(LINK) $(dpid_OBJECTS) $(dpid_LDADD) $(LIBS)
315 dpidc$(EXEEXT): $(dpidc_OBJECTS) $(dpidc_DEPENDENCIES)
346 dpidc$(EXEEXT): $(dpidc_OBJECTS) $(dpidc_DEPENDENCIES) $(EXTRA_dpidc_DEPENDENCIES)
316347 @rm -f dpidc$(EXEEXT)
317348 $(LINK) $(dpidc_OBJECTS) $(dpidc_LDADD) $(LIBS)
318349
345376 @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
346377 install-sysconfDATA: $(sysconf_DATA)
347378 @$(NORMAL_INSTALL)
348 test -z "$(sysconfdir)" || $(MKDIR_P) "$(DESTDIR)$(sysconfdir)"
349379 @list='$(sysconf_DATA)'; test -n "$(sysconfdir)" || list=; \
380 if test -n "$$list"; then \
381 echo " $(MKDIR_P) '$(DESTDIR)$(sysconfdir)'"; \
382 $(MKDIR_P) "$(DESTDIR)$(sysconfdir)" || exit 1; \
383 fi; \
350384 for p in $$list; do \
351385 if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
352386 echo "$$d$$p"; \
360394 @$(NORMAL_UNINSTALL)
361395 @list='$(sysconf_DATA)'; test -n "$(sysconfdir)" || list=; \
362396 files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
363 test -n "$$files" || exit 0; \
364 echo " ( cd '$(DESTDIR)$(sysconfdir)' && rm -f" $$files ")"; \
365 cd "$(DESTDIR)$(sysconfdir)" && rm -f $$files
397 dir='$(DESTDIR)$(sysconfdir)'; $(am__uninstall_files_from_dir)
366398
367399 ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
368400 list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
463495
464496 installcheck: installcheck-am
465497 install-strip:
466 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
467 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
468 `test -z '$(STRIP)' || \
469 echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
498 if test -z '$(STRIP)'; then \
499 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
500 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
501 install; \
502 else \
503 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
504 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
505 "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
506 fi
470507 mostlyclean-generic:
471508
472509 clean-generic:
335335 char *user_dpidir = NULL, *sys_dpidir = NULL, *dpidrc = NULL;
336336 struct dirent *user_dirent, *sys_dirent;
337337 int st;
338 int snum, usr_srv_num;
338 int snum;
339339 size_t dp_sz = sizeof(struct dp);
340340
341341 if (*attlist != NULL) {
369369 }
370370
371371 /* Get list of services in user's .dillo/dpi directory */
372 snum = usr_srv_num = 0;
372 snum = 0;
373373 if (user_dpidir && (user_dir_stream = opendir(user_dpidir)) != NULL) {
374374 while ((user_dirent = readdir(user_dir_stream)) != NULL) {
375375 if (user_dirent->d_name[0] == '.')
379379 if (st == 0)
380380 snum++;
381381 }
382 usr_srv_num = snum;
383382 closedir(user_dir_stream);
384383 }
385384 if (sys_dpidir && (sys_dir_stream = opendir(sys_dpidir)) != NULL) {
762761 } else if (CKD_WRITE(sock_fd, bye_cmd) == -1) {
763762 ERRMSG("stop_active_dpis", "write", errno);
764763 }
765 a_Misc_close_fd(sock_fd);
764 dClose(sock_fd);
766765 }
767766
768767 dFree(auth_cmd);
782781
783782 for (i = 0; i < numdpis; i++) {
784783 FD_CLR(dpi_attr_list[i].sock_fd, &sock_set);
785 a_Misc_close_fd(dpi_attr_list[i].sock_fd);
784 dClose(dpi_attr_list[i].sock_fd);
786785 }
787786 }
788787
2121 MSG_ERR("%s:%d: %s: %s\n", file, line, caller, called);
2222 if (errornum > 0)
2323 MSG_ERR("%s\n", dStrerror(errornum));
24 }
25
26 /*! Selector function for scandir
27 * Do not scan files starting with '.'
28 */
29 int no_dotfiles(const struct dirent *filedat)
30 {
31 if (filedat->d_name[0] == '.')
32 return 0;
33 else
34 return 1;
3524 }
3625
3726 /*!
6150 {
6251 ssize_t ret;
6352
64 do {
65 ret = close(fd);
66 } while (ret == -1 && errno == EINTR);
67 if (ret == -1) {
53 ret = dClose(fd);
54 if (ret == -1)
6855 MSG_ERR("%s:%d: close: %s\n", file, line, dStrerror(errno));
69 }
70 return (ret);
56 return ret;
7157 }
7258
5353
5454 void errmsg(char *caller, char *called, int errornum, char *file, int line);
5555
56 int no_dotfiles(const struct dirent *filedat);
57
5856 ssize_t ckd_write(int fd, char *msg, char *file, int line);
5957 ssize_t ckd_close(int fd, char *file, int line);
6058
88 #include <netdb.h>
99 #include <errno.h>
1010
11 #include "../dlib/dlib.h"
1112 #include "../dpip/dpip.h"
1213
1314 #define MSG_ERR(...) printf("** ERROR **: " __VA_ARGS__);
115116 error("ERROR reading from socket");
116117 printf("%s\n",buffer);
117118 */
118 close(sockfd);
119 dClose(sockfd);
119120 return 0;
120121 }
2525 #include "dpi.h"
2626 #include "dpi_socket_dir.h"
2727 #include "misc_new.h"
28
29 #include "../dlib/dlib.h"
2830 #include "../dpip/dpip.h"
2931
3032 sigset_t mask_sigchld;
7577 }
7678
7779 /* Parent, Close sockets fix stdio and return pid */
78 if (a_Misc_close_fd(newsock) == -1) {
80 if (dClose(newsock) == -1) {
7981 ERRMSG("start_plugin", "close", errno);
8082 MSG_ERR("ERROR in child proc for %s\n", dpi_attr.path);
8183 exit(1);
8284 }
83 a_Misc_close_fd(STDIN_FILENO);
84 a_Misc_close_fd(STDOUT_FILENO);
85 dClose(STDIN_FILENO);
86 dClose(STDOUT_FILENO);
8587 dup2(old_stdin, STDIN_FILENO);
8688 dup2(old_stdout, STDOUT_FILENO);
8789 return pid;
9496 MSG_ERR("ERROR in child proc for %s\n", dpi_attr.path);
9597 exit(1);
9698 }
97 if (a_Misc_close_fd(dpi_attr.sock_fd) == -1) {
99 if (dClose(dpi_attr.sock_fd) == -1) {
98100 ERRMSG("start_plugin", "close", errno);
99101 MSG_ERR("ERROR in child proc for %s\n", dpi_attr.path);
100102 exit(1);
223225 /* close inherited file descriptors */
224226 open_max = get_open_max();
225227 for (i = 3; i < open_max; i++)
226 a_Misc_close_fd(i);
228 dClose(i);
227229
228230 /* this sleep used to unmask a race condition */
229231 // sleep(2);
1818 #include "dpid_common.h"
1919 #include "misc_new.h" /* for function prototypes */
2020
21
22 /*
23 * Close a FD handling EINTR.
24 */
25 int a_Misc_close_fd(int fd)
26 {
27 int st;
28
29 do {
30 st = close(fd);
31 } while (st < 0 && errno == EINTR);
32 return st;
33 }
34
3521 /*! Reads a dpi tag from a socket
3622 * \li Continues after a signal interrupt
3723 * \Return
00 #ifndef MISC_NEW_H
11 #define MISC_NEW_H
22
3
4 int a_Misc_close_fd(int fd);
53 Dstr *a_Misc_rdtag(int socket);
64 char *a_Misc_readtag(int sock);
75 char *a_Misc_mkdtemp(char *template);
0 # Makefile.in generated by automake 1.11.1 from Makefile.am.
0 # Makefile.in generated by automake 1.11.6 from Makefile.am.
11 # @configure_input@
22
33 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
4 # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
5 # Inc.
4 # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
5 # Foundation, Inc.
66 # This Makefile.in is free software; the Free Software Foundation
77 # gives unlimited permission to copy and/or distribute it,
88 # with or without modifications, as long as this notice is preserved.
1515 @SET_MAKE@
1616
1717 VPATH = @srcdir@
18 am__make_dryrun = \
19 { \
20 am__dry=no; \
21 case $$MAKEFLAGS in \
22 *\\[\ \ ]*) \
23 echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
24 | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
25 *) \
26 for am__flg in $$MAKEFLAGS; do \
27 case $$am__flg in \
28 *=*|--*) ;; \
29 *n*) am__dry=yes; break;; \
30 esac; \
31 done;; \
32 esac; \
33 test $$am__dry = yes; \
34 }
1835 pkgdatadir = $(datadir)/@PACKAGE@
1936 pkgincludedir = $(includedir)/@PACKAGE@
2037 pkglibdir = $(libdir)/@PACKAGE@
3754 subdir = dpip
3855 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
3956 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
40 am__aclocal_m4_deps = $(top_srcdir)/configure.in
57 am__aclocal_m4_deps = $(top_srcdir)/configure.ac
4158 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
4259 $(ACLOCAL_M4)
4360 mkinstalldirs = $(install_sh) -d
6178 LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
6279 SOURCES = $(libDpip_a_SOURCES)
6380 DIST_SOURCES = $(libDpip_a_SOURCES)
81 am__can_run_installinfo = \
82 case $$AM_UPDATE_INFO_DIR in \
83 n|no|NO) false;; \
84 *) (install-info --version) >/dev/null 2>&1;; \
85 esac
6486 ETAGS = etags
6587 CTAGS = ctags
6688 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
225247
226248 clean-noinstLIBRARIES:
227249 -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
228 libDpip.a: $(libDpip_a_OBJECTS) $(libDpip_a_DEPENDENCIES)
250 libDpip.a: $(libDpip_a_OBJECTS) $(libDpip_a_DEPENDENCIES) $(EXTRA_libDpip_a_DEPENDENCIES)
229251 -rm -f libDpip.a
230252 $(libDpip_a_AR) libDpip.a $(libDpip_a_OBJECTS) $(libDpip_a_LIBADD)
231253 $(RANLIB) libDpip.a
348370
349371 installcheck: installcheck-am
350372 install-strip:
351 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
352 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
353 `test -z '$(STRIP)' || \
354 echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
373 if test -z '$(STRIP)'; then \
374 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
375 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
376 install; \
377 else \
378 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
379 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
380 "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
381 fi
355382 mostlyclean-generic:
356383
357384 clean-generic:
450450 }
451451
452452 } else if (dsh->mode & DPIP_RAW) {
453 /* Wait for data when the buffer is empty and there's no EOF yet */
454 while (dsh->rdbuf->len == 0 && dsh->status != DPIP_EOF)
453 /* Wait for data when the buffer is empty and there's no ERR/EOF */
454 while (dsh->rdbuf->len == 0 &&
455 dsh->status != DPIP_ERROR && dsh->status != DPIP_EOF)
455456 Dpip_dsh_read(dsh, 1);
456457 }
457458 }
487488 a_Dpip_dsh_write(dsh, 1, "", 0);
488489
489490 /* close fds */
490 while((st = close(dsh->fd_in)) < 0 && errno == EINTR) ;
491 st = dClose(dsh->fd_in);
491492 if (st < 0)
492493 MSG_ERR("[a_Dpip_dsh_close] close: %s\n", dStrerror(errno));
493494 if (dsh->fd_out != dsh->fd_in) {
494 while((st = close(dsh->fd_out)) < 0 && errno == EINTR) ;
495 st = dClose(dsh->fd_out);
495496 if (st < 0)
496497 MSG_ERR("[a_Dpip_dsh_close] close: %s\n", dStrerror(errno));
497498 }
2727 /*
2828 * Dpip socket handler type.
2929 */
30 typedef struct _DpipSocketHandler Dsh;
31 struct _DpipSocketHandler {
30 typedef struct {
3231 int fd_in;
3332 int fd_out;
3433 /* FILE *in; --Unused. The stream functions block when reading. */
4039
4140 int mode; /* mode flags: DPIP_TAG | DPIP_LAST_TAG | DPIP_RAW */
4241 int status; /* status code: DPIP_EAGAIN | DPIP_ERROR | DPIP_EOF */
43 };
42 } Dsh;
4443
4544
4645 /*
00 AM_CPPFLAGS = \
1 -I$(top_srcdir)
1 -I$(top_srcdir) \
2 -DDILLO_LIBDIR='"$(pkglibdir)/"'
3
24
35 noinst_LIBRARIES = \
46 libDw-core.a \
5658 alignedtextblock.hh \
5759 bullet.cc \
5860 bullet.hh \
61 hyphenator.cc \
62 hyphenator.hh \
5963 image.cc \
6064 image.hh \
6165 listitem.cc \
6771 tablecell.cc \
6872 tablecell.hh \
6973 textblock.cc \
74 textblock_iterator.cc \
75 textblock_linebreaking.cc \
7076 textblock.hh
7177
7278 EXTRA_DIST = preview.xbm
0 # Makefile.in generated by automake 1.11.1 from Makefile.am.
0 # Makefile.in generated by automake 1.11.6 from Makefile.am.
11 # @configure_input@
22
33 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
4 # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
5 # Inc.
4 # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
5 # Foundation, Inc.
66 # This Makefile.in is free software; the Free Software Foundation
77 # gives unlimited permission to copy and/or distribute it,
88 # with or without modifications, as long as this notice is preserved.
1515 @SET_MAKE@
1616
1717 VPATH = @srcdir@
18 am__make_dryrun = \
19 { \
20 am__dry=no; \
21 case $$MAKEFLAGS in \
22 *\\[\ \ ]*) \
23 echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
24 | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
25 *) \
26 for am__flg in $$MAKEFLAGS; do \
27 case $$am__flg in \
28 *=*|--*) ;; \
29 *n*) am__dry=yes; break;; \
30 esac; \
31 done;; \
32 esac; \
33 test $$am__dry = yes; \
34 }
1835 pkgdatadir = $(datadir)/@PACKAGE@
1936 pkgincludedir = $(includedir)/@PACKAGE@
2037 pkglibdir = $(libdir)/@PACKAGE@
3754 subdir = dw
3855 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
3956 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
40 am__aclocal_m4_deps = $(top_srcdir)/configure.in
57 am__aclocal_m4_deps = $(top_srcdir)/configure.ac
4158 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
4259 $(ACLOCAL_M4)
4360 mkinstalldirs = $(install_sh) -d
6885 libDw_widgets_a_AR = $(AR) $(ARFLAGS)
6986 libDw_widgets_a_LIBADD =
7087 am_libDw_widgets_a_OBJECTS = alignedtextblock.$(OBJEXT) \
71 bullet.$(OBJEXT) image.$(OBJEXT) listitem.$(OBJEXT) \
72 ruler.$(OBJEXT) table.$(OBJEXT) tablecell.$(OBJEXT) \
73 textblock.$(OBJEXT)
88 bullet.$(OBJEXT) hyphenator.$(OBJEXT) image.$(OBJEXT) \
89 listitem.$(OBJEXT) ruler.$(OBJEXT) table.$(OBJEXT) \
90 tablecell.$(OBJEXT) textblock.$(OBJEXT) \
91 textblock_iterator.$(OBJEXT) textblock_linebreaking.$(OBJEXT)
7492 libDw_widgets_a_OBJECTS = $(am_libDw_widgets_a_OBJECTS)
7593 DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
7694 depcomp = $(SHELL) $(top_srcdir)/depcomp
89107 $(libDw_widgets_a_SOURCES)
90108 DIST_SOURCES = $(libDw_core_a_SOURCES) $(libDw_fltk_a_SOURCES) \
91109 $(libDw_widgets_a_SOURCES)
110 am__can_run_installinfo = \
111 case $$AM_UPDATE_INFO_DIR in \
112 n|no|NO) false;; \
113 *) (install-info --version) >/dev/null 2>&1;; \
114 esac
92115 ETAGS = etags
93116 CTAGS = ctags
94117 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
209232 top_builddir = @top_builddir@
210233 top_srcdir = @top_srcdir@
211234 AM_CPPFLAGS = \
212 -I$(top_srcdir)
235 -I$(top_srcdir) \
236 -DDILLO_LIBDIR='"$(pkglibdir)/"'
213237
214238 noinst_LIBRARIES = \
215239 libDw-core.a \
266290 alignedtextblock.hh \
267291 bullet.cc \
268292 bullet.hh \
293 hyphenator.cc \
294 hyphenator.hh \
269295 image.cc \
270296 image.hh \
271297 listitem.cc \
277303 tablecell.cc \
278304 tablecell.hh \
279305 textblock.cc \
306 textblock_iterator.cc \
307 textblock_linebreaking.cc \
280308 textblock.hh
281309
282310 EXTRA_DIST = preview.xbm
317345
318346 clean-noinstLIBRARIES:
319347 -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
320 libDw-core.a: $(libDw_core_a_OBJECTS) $(libDw_core_a_DEPENDENCIES)
348 libDw-core.a: $(libDw_core_a_OBJECTS) $(libDw_core_a_DEPENDENCIES) $(EXTRA_libDw_core_a_DEPENDENCIES)
321349 -rm -f libDw-core.a
322350 $(libDw_core_a_AR) libDw-core.a $(libDw_core_a_OBJECTS) $(libDw_core_a_LIBADD)
323351 $(RANLIB) libDw-core.a
324 libDw-fltk.a: $(libDw_fltk_a_OBJECTS) $(libDw_fltk_a_DEPENDENCIES)
352 libDw-fltk.a: $(libDw_fltk_a_OBJECTS) $(libDw_fltk_a_DEPENDENCIES) $(EXTRA_libDw_fltk_a_DEPENDENCIES)
325353 -rm -f libDw-fltk.a
326354 $(libDw_fltk_a_AR) libDw-fltk.a $(libDw_fltk_a_OBJECTS) $(libDw_fltk_a_LIBADD)
327355 $(RANLIB) libDw-fltk.a
328 libDw-widgets.a: $(libDw_widgets_a_OBJECTS) $(libDw_widgets_a_DEPENDENCIES)
356 libDw-widgets.a: $(libDw_widgets_a_OBJECTS) $(libDw_widgets_a_DEPENDENCIES) $(EXTRA_libDw_widgets_a_DEPENDENCIES)
329357 -rm -f libDw-widgets.a
330358 $(libDw_widgets_a_AR) libDw-widgets.a $(libDw_widgets_a_OBJECTS) $(libDw_widgets_a_LIBADD)
331359 $(RANLIB) libDw-widgets.a
339367 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alignedtextblock.Po@am__quote@
340368 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bullet.Po@am__quote@
341369 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findtext.Po@am__quote@
370 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hyphenator.Po@am__quote@
342371 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/image.Po@am__quote@
343372 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iterator.Po@am__quote@
344373 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/layout.Po@am__quote@
358387 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/table.Po@am__quote@
359388 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tablecell.Po@am__quote@
360389 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/textblock.Po@am__quote@
390 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/textblock_iterator.Po@am__quote@
391 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/textblock_linebreaking.Po@am__quote@
361392 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/types.Po@am__quote@
362393 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ui.Po@am__quote@
363394 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/widget.Po@am__quote@
598629
599630 installcheck: installcheck-am
600631 install-strip:
601 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
602 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
603 `test -z '$(STRIP)' || \
604 echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
632 if test -z '$(STRIP)'; then \
633 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
634 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
635 install; \
636 else \
637 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
638 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
639 "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
640 fi
605641 mostlyclean-generic:
606642
607643 clean-generic:
3030 class ResourceFactory;
3131
3232 } // namespace ui
33
34
33 } // namespace core
3534 } // namespace dw
36 } // namespace core
3735
3836 #include "../lout/object.hh"
3937 #include "../lout/container.hh"
7676 Widget *lastWidget, *currentWidget;
7777 };
7878
79 } // namespace core
7980 } // namespace dw
80 } // namespace core
8181
8282 #endif // __DW_EVENTS_HH__
287287 return ret;
288288 }
289289
290 } // namespace core
290291 } // namespace dw
291 } // namespace core
7777 void resetSearch ();
7878 };
7979
80 } // namespace core
8081 } // namespace dw
81 } // namespace core
8282
8383 #endif // __DW_FINDTEXT_STATE_H__
1717 */
1818
1919 #include <FL/Fl.H>
20 #include <FL/Fl_Button.H>
21 #include <FL/Fl_Group.H>
2220 #include <FL/Fl_Window.H>
2321
2422 #include "fltkcomplexbutton.hh"
4644 void ComplexButton::draw() {
4745 Fl_Color col = value() ? selection_color() : color();
4846 draw_box(value() ? (down_box()?down_box():fl_down(box())) : box(), col);
49 if (Fl::focus() == this) draw_focus();
5047
5148 // ComplexButton is a Group; draw its children
5249 for (int i = children () - 1; i >= 0; i--) {
5451 child (i)->position(x()+(w()-child(i)->w())/2,y()+(h()-child(i)->h())/2);
5552 draw_child (*child (i));
5653 }
54 if (Fl::focus() == this) draw_focus();
5755 }
5856
5957 int ComplexButton::handle(int event) {
7674 value_ = newval;
7775 set_changed();
7876 redraw();
79 if (when() & FL_WHEN_CHANGED) do_callback();
8077 }
8178 return 1;
8279 case FL_RELEASE:
8380 if (value_ == oldval) {
84 if (when() & FL_WHEN_NOT_CHANGED) do_callback();
8581 return 1;
8682 }
8783 set_changed();
8884 value(oldval);
8985 set_changed();
90 if (when() & FL_WHEN_CHANGED) {
91 Fl_Widget_Tracker wp(this);
92 do_callback();
93 if (wp.deleted()) return 1;
94 }
9586 if (when() & FL_WHEN_RELEASE) do_callback();
9687 return 1;
9788 case FL_FOCUS : /* FALLTHROUGH */
9889 case FL_UNFOCUS :
9990 if (Fl::visible_focus()) {
100 if (box() == FL_NO_BOX) {
101 // Widgets with the FL_NO_BOX boxtype need a parent to
102 // redraw, since it is responsible for redrawing the
103 // background...
104 int X = x() > 0 ? x() - 1 : 0;
105 int Y = y() > 0 ? y() - 1 : 0;
106 if (window()) window()->damage(FL_DAMAGE_ALL, X, Y, w() + 2, h() + 2);
107 } else redraw();
91 redraw();
10892 return 1;
10993 } else return 0;
11094 case FL_KEYBOARD :
11195 if (Fl::focus() == this &&
11296 (Fl::event_key() == ' ' || Fl::event_key() == FL_Enter) &&
11397 !(Fl::event_state() & (FL_SHIFT | FL_CTRL | FL_ALT | FL_META))) {
98 value(1);
11499 set_changed();
115 Fl_Widget_Tracker wp(this);
116 if (wp.deleted()) return 1;
117100 if (when() & FL_WHEN_RELEASE) do_callback();
101 return 1;
102 } else return 0;
103 case FL_KEYUP:
104 if (Fl::focus() == this &&
105 (Fl::event_key() == ' ' || Fl::event_key() == FL_Enter)) {
106 value(0);
118107 return 1;
119108 }
120109 default:
2222
2323 #include <FL/Fl_Group.H>
2424
25 extern FL_EXPORT Fl_Shortcut fl_old_shortcut(const char*);
26
2725 namespace dw {
2826 namespace fltk {
2927 namespace ui {
3028
31 class FL_EXPORT ComplexButton : public Fl_Group {
32
33 int shortcut_;
29 class ComplexButton : public Fl_Group {
3430 char value_;
3531 char oldval;
3632 uchar down_box_;
1010
1111 } // namespace ui
1212 } // namespace fltk
13 } // namespace core
13 } // namespace dw
1414
1515 #include <FL/Fl_Widget.H>
1616
227227 }
228228 }
229229
230 int FltkImgbuf::getRootWidth ()
230 int FltkImgbuf::getRootWidth ()
231231 {
232232 return root ? root->width : width;
233233 }
234234
235 int FltkImgbuf::getRootHeight ()
235 int FltkImgbuf::getRootHeight ()
236236 {
237237 return root ? root->height : height;
238238 }
325325
326326 }
327327
328 } // namespace fltk
328329 } // namespace dw
329 } // namespace fltk
5858 int x, int y, int width, int height);
5959 };
6060
61 } // namespace fltk
6162 } // namespace dw
62 } // namespace fltk
6363
6464 #endif // __DW_FLTK_IMGBUF_HH__
122122 font = family->get (fa);
123123
124124 fl_font(font, size);
125 /* WORKAROUND: fl_width(uint_t) is not working on non-xft X.
126 * Reported to FLTK as STR #2688 */
125 // WORKAROUND: A bug with fl_width(uint_t) on non-xft X was present in
126 // 1.3.0 (STR #2688).
127127 spaceWidth = misc::max(0, (int)fl_width(" ") + letterSpacing);
128128 int xx, xy, xw, xh;
129129 fl_text_extents("x", xx, xy, xw, xh);
418418 }
419419
420420 core::ui::EntryResource *
421 FltkPlatform::FltkResourceFactory::createEntryResource (int maxLength,
421 FltkPlatform::FltkResourceFactory::createEntryResource (int size,
422422 bool password,
423423 const char *label)
424424 {
425 return new ui::FltkEntryResource (platform, maxLength, password, label);
425 return new ui::FltkEntryResource (platform, size, password, label);
426426 }
427427
428428 core::ui::MultiLineTextResource *
492492 }
493493
494494
495 void FltkPlatform::detachView (core::View *view)
495 void FltkPlatform::detachView (core::View *view)
496496 {
497497 if (this->view != view)
498498 MSG_ERR("FltkPlatform::detachView: this->view: %p view: %p\n",
108108 createListResource (core::ui::ListResource::SelectionMode selectionMode,
109109 int rows);
110110 core::ui::OptionMenuResource *createOptionMenuResource ();
111 core::ui::EntryResource *createEntryResource (int maxLength,
112 bool password,
111 core::ui::EntryResource *createEntryResource (int size, bool password,
113112 const char *label);
114113 core::ui::MultiLineTextResource *createMultiLineTextResource (int cols,
115114 int rows);
5959 // We're only interested in some flags
6060 unsigned modifier = Fl::event_state() & (FL_SHIFT | FL_CTRL | FL_ALT);
6161
62 if (e == FL_KEYBOARD && modifier == FL_CTRL) {
63 if (k == 'a' || k == 'e') {
64 position(k == 'a' ? 0 : size());
65 return 1;
66 } else if (k == 'k') {
67 cut(position(), size());
68 return 1;
69 } else if (k == 'd') {
70 cut(position(), position()+1);
71 return 1;
62 if (e == FL_KEYBOARD) {
63 if (k == FL_Page_Down || k == FL_Page_Up || k == FL_Up || k == FL_Down) {
64 // Let them through for key commands and viewport motion.
65 return 0;
7266 }
67 if (modifier == FL_CTRL) {
68 if (k == 'a' || k == 'e') {
69 position(k == 'a' ? 0 : size());
70 return 1;
71 } else if (k == 'k') {
72 cut(position(), size());
73 return 1;
74 } else if (k == 'd') {
75 cut(position(), position()+1);
76 return 1;
77 } else if (k == 'h' || k == 'i' || k == 'j' || k == 'l' || k == 'm') {
78 // Fl_Input wants to use ^H as backspace, and also "insert a few
79 // selected control characters literally", but this gets in the way
80 // of key commands.
81 return 0;
82 }
83 }
7384 }
7485 return Fl_Input::handle(e);
86 }
87
88
89 /*
90 * Used to handle some keystrokes as shortcuts to option menuitems
91 * (i.e. jump to the next menuitem whose label starts with the pressed key)
92 */
93 class CustChoice : public Fl_Choice {
94 public:
95 CustChoice (int x, int y, int w, int h, const char* l=0) :
96 Fl_Choice(x,y,w,h,l) {};
97 int handle(int e);
98 };
99
100 int CustChoice::handle(int e)
101 {
102 int k = Fl::event_key();
103 unsigned modifier = Fl::event_state() & (FL_SHIFT|FL_CTRL|FL_ALT|FL_META);
104
105 _MSG("CustChoice::handle %p e=%d active=%d focus=%d\n",
106 this, e, active(), (Fl::focus() == this));
107 if (Fl::focus() != this) {
108 ; // Not Focused, let FLTK handle it
109 } else if (e == FL_KEYDOWN && modifier == 0) {
110 if (k == FL_Enter || k == FL_Down) {
111 return Fl_Choice::handle(FL_PUSH); // activate menu
112
113 } else if (isalnum(k)) { // try key as shortcut to menuitem
114 int t = value()+1 >= size() ? 0 : value()+1;
115 while (t != value()) {
116 const Fl_Menu_Item *mi = &(menu()[t]);
117 if (mi->submenu()) // submenu?
118 ;
119 else if (mi->label() && mi->active()) { // menu item?
120 if (k == tolower(mi->label()[0])) {
121 value(mi);
122 return 1; // Let FLTK know we used this key
123 }
124 }
125 if (++t == size())
126 t = 0;
127 }
128 }
129 }
130
131 return Fl_Choice::handle(e);
75132 }
76133
77134 //----------------------------------------------------------------------------
401458 {
402459 FltkComplexButtonResource *res = (FltkComplexButtonResource*)data;
403460
404 if (!Fl::event_button3()) {
405 res->click_x = Fl::event_x();
406 res->click_y = Fl::event_y();
461 if (Fl::event() == FL_RELEASE && Fl::event_button() != FL_RIGHT_MOUSE) {
462 int w = widget->w(), h = widget->h();
463
464 res->click_x = Fl::event_x() - widget->x();
465 res->click_y = Fl::event_y() - widget->y();
466 if (res->style) {
467 res->click_x -= res->style->boxOffsetX();
468 res->click_y -= res->style->boxOffsetY();
469 w -= res->style->boxDiffWidth();
470 h -= res->style->boxDiffHeight();
471 }
472 if (res->click_x >= 0 && res->click_y >= 0 &&
473 res->click_x < w && res->click_y < h) {
474 dw::core::EventButton event;
475 setButtonEvent(&event);
476 res->emitClicked(&event);
477 }
478 } else if (Fl::event() == FL_KEYBOARD) {
479 // Simulate a click.
407480 dw::core::EventButton event;
408 setButtonEvent(&event);
481
482 res->click_x = res->click_y = 0;
483 event.xCanvas = widget->x() + res->style->boxOffsetX();
484 event.yCanvas = widget->y() + res->style->boxOffsetY();
485 // ButtonState doesn't have mouse button values on a release.
486 event.state = (core::ButtonState) 0;
487 event.button = 1;
488 event.numPressed = 1;
409489 res->emitClicked(&event);
410490 }
411491 }
465545 button->callback (widgetCallback, this);
466546 button->when (FL_WHEN_RELEASE);
467547 if (!relief)
468 button->box(FL_FLAT_BOX);
548 button->box(FL_NO_BOX);
469549
470550 flatView = new FltkFlatView (allocation->x + reliefXThickness (),
471551 allocation->y + reliefYThickness (),
481561
482562 // ----------------------------------------------------------------------
483563
484 FltkEntryResource::FltkEntryResource (FltkPlatform *platform, int maxLength,
564 FltkEntryResource::FltkEntryResource (FltkPlatform *platform, int size,
485565 bool password, const char *label):
486566 FltkSpecificResource <dw::core::ui::EntryResource> (platform)
487567 {
488 this->maxLength = maxLength;
568 this->size = size;
489569 this->password = password;
490570 this->label = label ? strdup(label) : NULL;
491571 this->label_w = 0;
556636 if (displayed() && style) {
557637 FltkFont *font = (FltkFont*)style->font;
558638 fl_font(font->font,font->size);
559 /* WORKAROUND: fl_width(uint_t) is not working on non-xft X.
560 * Reported to FLTK as STR #2688 */
639 // WORKAROUND: A bug with fl_width(uint_t) on non-xft X was present in
640 // 1.3.0 (STR #2688).
561641 requisition->width =
562642 (int)fl_width ("n")
563 * (maxLength == UNLIMITED_MAX_LENGTH ? 10 : maxLength)
643 * (size == UNLIMITED_SIZE ? 10 : size)
564644 + label_w + (2 * RELIEF_X_THICKNESS);
565645 requisition->ascent = font->ascent + RELIEF_Y_THICKNESS;
566646 requisition->descent = font->descent + RELIEF_Y_THICKNESS;
615695 this->editable = editable;
616696 }
617697
698 void FltkEntryResource::setMaxLength (int maxlen)
699 {
700 ((Fl_Input *)widget)->maximum_size(maxlen);
701 }
702
618703 // ----------------------------------------------------------------------
704
705 static int kf_backspace_word (int c, Fl_Text_Editor *e)
706 {
707 int p1, p2 = e->insert_position();
708
709 e->previous_word();
710 p1 = e->insert_position();
711 e->buffer()->remove(p1, p2);
712 e->show_insert_position();
713 e->set_changed();
714 if (e->when() & FL_WHEN_CHANGED)
715 e->do_callback();
716 return 0;
717 }
619718
620719 FltkMultiLineTextResource::FltkMultiLineTextResource (FltkPlatform *platform,
621720 int cols, int rows):
658757 allocation->ascent + allocation->descent);
659758 text->wrap_mode(Fl_Text_Display::WRAP_AT_BOUNDS, 0);
660759 text->buffer (buffer);
760 text->remove_key_binding(FL_BackSpace, FL_TEXT_EDITOR_ANY_STATE);
761 text->add_key_binding(FL_BackSpace, 0, Fl_Text_Editor::kf_backspace);
762 text->add_key_binding(FL_BackSpace, FL_CTRL, kf_backspace_word);
661763 return text;
662764 }
663765
679781 if (style) {
680782 FltkFont *font = (FltkFont*)style->font;
681783 fl_font(font->font,font->size);
682 /* WORKAROUND: fl_width(uint_t) is not working on non-xft X.
683 * Reported to FLTK as STR #2688 */
784 // WORKAROUND: A bug with fl_width(uint_t) on non-xft X was present in
785 // 1.3.0 (STR #2688).
684786 requisition->width =
685787 (int)fl_width ("n") * numCols + 2 * RELIEF_X_THICKNESS;
686788 requisition->ascent =
9831085 *allocation)
9841086 {
9851087 Fl_Choice *choice =
986 new Fl_Choice (allocation->x, allocation->y,
987 allocation->width,
988 allocation->ascent + allocation->descent);
1088 new CustChoice (allocation->x, allocation->y,
1089 allocation->width,
1090 allocation->ascent + allocation->descent);
9891091 choice->menu(menu);
9901092 return choice;
9911093 }
10761178 queueResize (true);
10771179 }
10781180
1181 void FltkOptionMenuResource::setItem (int index, bool selected)
1182 {
1183 if (selected)
1184 ((Fl_Choice *)widget)->value(menu+index);
1185 }
1186
10791187 void FltkOptionMenuResource::pushGroup (const char *name, bool enabled)
10801188 {
10811189 Fl_Menu_Item *item = newItem();
11361244 : FL_TREE_SELECT_SINGLE);
11371245 tree->showroot(0);
11381246 tree->connectorstyle(FL_TREE_CONNECTOR_NONE);
1247 tree->margintop(0);
11391248 tree->marginleft(-14);
11401249 tree->callback(widgetCallback,this);
11411250 tree->when(FL_WHEN_CHANGED);
11611270 {
11621271 Fl_Tree_Item *fltkItem = ((Fl_Tree *) widget)->callback_item ();
11631272 int index = -1;
1273
11641274 if (fltkItem)
11651275 index = (long) (fltkItem->user_data ());
11661276 if (index > -1) {
1167 FltkListResource *res = (FltkListResource *) data;
11681277 bool selected = fltkItem->is_selected ();
1169 res->itemsSelected.set (index, selected);
1278
1279 if (selected && fltkItem->has_children()) {
1280 /* Don't permit a group to be selected. */
1281 fltkItem->deselect();
1282 } else {
1283 FltkListResource *res = (FltkListResource *) data;
1284 res->itemsSelected.set (index, selected);
1285 }
11701286 }
11711287 }
11721288
12021318 queueResize (true);
12031319 }
12041320
1321 void FltkListResource::setItem (int index, bool selected)
1322 {
1323 Fl_Tree *tree = (Fl_Tree *) widget;
1324 Fl_Tree_Item *item = tree->root()->next();
1325
1326 for (int i = 0; item && i < index; i++)
1327 item = item->next();
1328
1329 if (item) {
1330 bool do_callback = false;
1331 itemsSelected.set (index, selected);
1332 if (selected) {
1333 if (mode == SELECTION_MULTIPLE) {
1334 tree->select(item, do_callback);
1335 } else {
1336 /* callback to deselect other selected item */
1337 do_callback = true;
1338 tree->select_only(item, do_callback);
1339 }
1340 } else {
1341 tree->deselect(item, do_callback);
1342 }
1343 }
1344 }
1345
12051346 void FltkListResource::pushGroup (const char *name, bool enabled)
12061347 {
12071348 bool selected = false;
12081349
1209 /* TODO: make it impossible to select a group */
12101350 currParent = (Fl_Tree_Item *) newItem(name, enabled, selected);
12111351 queueResize (true);
12121352 }
12511391 if (showRows < rows) {
12521392 rows = showRows;
12531393 }
1254 requisition->width = getMaxItemWidth() + 5 + Fl::scrollbar_size();;
1255 requisition->ascent = font->ascent + 5 +
1256 (rows - 1) * (font->ascent + font->descent + 1);
1257 requisition->descent = font->descent + 3;
1394 requisition->width = getMaxItemWidth() + 5 + Fl::scrollbar_size();
1395 requisition->descent = font->descent + 2;
1396 requisition->ascent = (rows * (font->size + font->descent + 1)) + 4 -
1397 requisition->descent;
12581398 } else {
12591399 requisition->width = 1;
12601400 requisition->ascent = 1;
1414 /**
1515 * \brief FLTK implementation of dw::core::ui.
1616 *
17 * <div style="border: 2px solid #ff0000; margin-top: 0.5em;
18 * margin-bottom: 0.5em; padding: 0.5em 1em;
19 * background-color: #ffefe0"><b>Update:</b> The complicated design
20 * results from my insufficient knowledge of C++ some years ago; since
21 * then, I've learned how to deal with "diamond inheritance", as the
22 * (ideal, not actually implemented) design in the first diagram
23 * shows. It should be possible to implement this ideal design in a
24 * straightforward way, and so get rid of templates. --SG</div>
25 *
1726 * The design should be like this:
1827 *
1928 * \dot
2029 * digraph G {
2130 * node [shape=record, fontname=Helvetica, fontsize=10];
22 * edge [arrowhead="none", arrowtail="empty", labelfontname=Helvetica,
23 * labelfontsize=10, color="#404040", labelfontcolor="#000080"];
31 * edge [arrowhead="none", arrowtail="empty", dir="both",
32 * labelfontname=Helvetica, labelfontsize=10, color="#404040",
33 * labelfontcolor="#000080"];
2434 * fontname=Helvetica; fontsize=10;
2535 *
2636 * subgraph cluster_core {
7181 * \dot
7282 * digraph G {
7383 * node [shape=record, fontname=Helvetica, fontsize=10];
74 * edge [arrowhead="none", arrowtail="empty", labelfontname=Helvetica,
75 * labelfontsize=10, color="#404040", labelfontcolor="#000080"];
84 * edge [arrowhead="none", arrowtail="empty", dir="both",
85 * labelfontname=Helvetica, labelfontsize=10, color="#404040",
86 * labelfontcolor="#000080"];
7687 * fontname=Helvetica; fontsize=10;
7788 *
7889 * subgraph cluster_core {
112123 * \dot
113124 * digraph G {
114125 * node [shape=record, fontname=Helvetica, fontsize=10];
115 * edge [arrowhead="none", arrowtail="empty", labelfontname=Helvetica,
116 * labelfontsize=10, color="#404040", labelfontcolor="#000080"];
126 * edge [arrowhead="none", arrowtail="empty", dir="both",
127 * labelfontname=Helvetica, labelfontsize=10, color="#404040",
128 * labelfontcolor="#000080"];
117129 * fontname=Helvetica; fontsize=10;
118130 *
119131 * subgraph cluster_core {
149161 * FltkResource -> FltkSpecificResource;
150162 * FltkSpecificResource -> FltkSpecificResource_button [arrowhead="open",
151163 * arrowtail="none",
164 * dir="both",
152165 * style="dashed",
153166 * color="#808000"];
154167 * FltkSpecificResource -> FltkSpecificResource_entry [arrowhead="open",
155168 * arrowtail="none",
169 * dir="both",
156170 * style="dashed",
157171 * color="#808000"];
158172 * LabelButtonResource -> FltkSpecificResource_button;
281295 public FltkSpecificResource <dw::core::ui::EntryResource>
282296 {
283297 private:
284 int maxLength;
298 int size;
285299 bool password;
286300 const char *initText;
287301 char *label;
296310 void setWidgetStyle (Fl_Widget *widget, core::style::Style *style);
297311
298312 public:
299 FltkEntryResource (FltkPlatform *platform, int maxLength, bool password,
313 FltkEntryResource (FltkPlatform *platform, int size, bool password,
300314 const char *label);
301315 ~FltkEntryResource ();
302316
307321 void setText (const char *text);
308322 bool isEditable ();
309323 void setEditable (bool editable);
324 void setMaxLength (int maxlen);
310325 };
311326
312327
444459 protected:
445460 virtual bool setSelectedItems() { return false; }
446461 virtual void addItem (const char *str, bool enabled, bool selected) = 0;
462 virtual void setItem (int index, bool selected) = 0;
447463 virtual void pushGroup (const char *name, bool enabled) = 0;
448464 virtual void popGroup () = 0;
449465 public:
474490 ~FltkOptionMenuResource ();
475491
476492 void addItem (const char *str, bool enabled, bool selected);
493 void setItem (int index, bool selected);
477494 void pushGroup (const char *name, bool enabled);
478495 void popGroup ();
479496
505522 ~FltkListResource ();
506523
507524 void addItem (const char *str, bool enabled, bool selected);
525 void setItem (int index, bool selected);
508526 void pushGroup (const char *name, bool enabled);
509527 void popGroup ();
510528
215215 return (core::ButtonState)s2;
216216 }
217217
218 /*
219 * We handle Tab to determine which FLTK widget should get focus.
220 *
221 * Presumably a proper solution that allows focusing links, etc., would live
222 * in Textblock and use iterators.
223 */
224 int FltkViewBase::manageTabToFocus()
225 {
226 int i, ret = 0;
227 Fl_Widget *old_child = NULL;
228
229 if (this == Fl::focus()) {
230 // if we have focus, give it to a child. Go forward typically,
231 // or backward with Shift pressed.
232 if (!(Fl::event_state() & FL_SHIFT)) {
233 for (i = 0; i < children(); i++) {
234 if (child(i)->take_focus()) {
235 ret = 1;
236 break;
237 }
238 }
239 } else {
240 for (i = children() - 1; i >= 0; i--) {
241 if (child(i)->take_focus()) {
242 ret = 1;
243 break;
244 }
245 }
246 }
247 } else {
248 // tabbing between children
249 old_child = Fl::focus();
250
251 if (!(ret = Fl_Group::handle (FL_KEYBOARD))) {
252 // group didn't have any more children to focus.
253 Fl::focus(this);
254 return 1;
255 } else {
256 // which one did it focus? (Note i == children() if not found)
257 i = find(Fl::focus());
258 }
259 }
260 if (ret) {
261 if (i >= 0 && i < children()) {
262 Fl_Widget *c = child(i);
263 int canvasX = translateViewXToCanvasX(c->x()),
264 canvasY = translateViewYToCanvasY(c->y());
265
266 theLayout->scrollTo(core::HPOS_INTO_VIEW, core::VPOS_INTO_VIEW,
267 canvasX, canvasY, c->w(), c->h());
268
269 // Draw the children who gained and lost focus. Otherwise a
270 // widget that had been only partly visible still shows its old
271 // appearance in the previously-visible portion.
272 core::Rectangle r(canvasX, canvasY, c->w(), c->h());
273
274 queueDraw(&r);
275
276 if (old_child) {
277 r.x = translateViewXToCanvasX(old_child->x());
278 r.y = translateViewYToCanvasY(old_child->y());
279 r.width = old_child->w();
280 r.height = old_child->h();
281 queueDraw(&r);
282 }
283 }
284 }
285 return ret;
286 }
287
218288 int FltkViewBase::handle (int event)
219289 {
220290 bool processed;
237307 _MSG("PUSH => %s\n", processed ? "true" : "false");
238308 if (processed) {
239309 /* pressed dw content; give focus to the view */
240 Fl::focus(this);
310 if (Fl::event_button() != FL_RIGHT_MOUSE)
311 Fl::focus(this);
241312 return true;
242313 }
243314 break;
294365 case FL_UNFOCUS:
295366 focused_child = fl_oldfocus;
296367 return 0;
368 case FL_KEYBOARD:
369 if (Fl::event_key() == FL_Tab)
370 return manageTabToFocus();
371 break;
297372 default:
298373 break;
299374 }
356431 void FltkViewBase::queueDraw (core::Rectangle *area)
357432 {
358433 drawRegion.addRectangle (area);
359 /** DAMAGE_VALUE is just an arbitrary value other than DAMAGE_EXPOSE here */
360434 damage (FL_DAMAGE_USER1);
361435 }
362436
471545 int y = translateCanvasYToViewY (centerY) - height / 2;
472546
473547 fl_arc(x, y, width, height, angle1, angle2);
474 if (filled)
548 if (filled) {
549 // WORKAROUND: We call both fl_arc and fl_pie due to a FLTK bug
550 // (STR #2703) that was present in 1.3.0.
475551 fl_pie(x, y, width, height, angle1, angle2);
552 }
476553 }
477554
478555 void FltkViewBase::drawPolygon (core::style::Color *color,
530607 }
531608
532609 void FltkWidgetView::drawText (core::style::Font *font,
533 core::style::Color *color,
534 core::style::Color::Shading shading,
535 int X, int Y, const char *text, int len)
536 {
610 core::style::Color *color,
611 core::style::Color::Shading shading,
612 int X, int Y, const char *text, int len)
613 {
614 //printf ("drawText (..., %d, %d, '", X, Y);
615 //for (int i = 0; i < len; i++)
616 // putchar (text[i]);
617 //printf ("'\n");
618
537619 FltkFont *ff = (FltkFont*)font;
538620 fl_font(ff->font, ff->size);
539621 fl_color(((FltkColor*)color)->colors[shading]);
3838
3939 void draw (const core::Rectangle *rect, DrawType type);
4040 void drawChildWidgets ();
41 int manageTabToFocus();
4142 inline void clipPoint (int *x, int *y, int border) {
4243 if (exposeArea) {
4344 if (*x < exposeArea->x - border)
207207 if (d) {
208208 draw_area(this, x(), y(), w () - hdiff, h () - vdiff);
209209
210 if (d == FL_DAMAGE_CHILD) {
211 if (hscrollbar->damage ())
212 draw_child (*hscrollbar);
213 if (vscrollbar->damage ())
214 draw_child (*vscrollbar);
215 } else {
210 if (d == FL_DAMAGE_ALL || hscrollbar->damage ())
216211 draw_child (*hscrollbar);
212 if (d == FL_DAMAGE_ALL || vscrollbar->damage ())
217213 draw_child (*vscrollbar);
214
215 if (d == FL_DAMAGE_ALL && hdiff && vdiff) {
216 fl_color(FL_BACKGROUND_COLOR);
217 fl_rectf(x()+w()-hdiff, y()+h()-vdiff, hdiff, vdiff);
218218 }
219219 }
220220
232232 * sends the event here. Returning zero tells FLTK to resend the
233233 * event as SHORTCUT, which we finally route to the parent. */
234234
235 /* As we don't know the exact keybindings set by the user, we ask
236 * for all of them (except Tab to keep form navigation). */
237 if (Fl::event_key() != FL_Tab)
235 /* As we don't know the exact keybindings set by the user, we ask for
236 * all of them (except for the minimum needed to keep form navigation).*/
237 if (Fl::event_key() != FL_Tab || Fl::event_ctrl())
238238 return 0;
239239 break;
240240
274274 break;
275275
276276 case FL_DRAG:
277 if (dragScrolling && Fl::event_button() == FL_MIDDLE_MOUSE) {
277 if (Fl::event_inside(this))
278 Fl::remove_timeout(selectionScroll);
279 if (dragScrolling) {
278280 scroll(dragX - Fl::event_x(), dragY - Fl::event_y());
279281 dragX = Fl::event_x();
280282 dragY = Fl::event_y();
285287 } else if (horScrolling) {
286288 hscrollbar->handle(event);
287289 return 1;
290 } else if (!Fl::event_inside(this)) {
291 mouse_x = Fl::event_x();
292 mouse_y = Fl::event_y();
293 if (!Fl::has_timeout(selectionScroll, this))
294 Fl::add_timeout(0.025, selectionScroll, this);
288295 }
289296 break;
290297
293300 break;
294301
295302 case FL_RELEASE:
303 Fl::remove_timeout(selectionScroll);
296304 if (Fl::event_button() == FL_MIDDLE_MOUSE) {
297305 setCursor (core::style::CURSOR_DEFAULT);
298306 } else if (verScrolling) {
331339 */
332340 void FltkViewport::positionChanged ()
333341 {
334 if (mouse_x != -1 && dragScrolling == false)
342 if (!dragScrolling && mouse_x >= x() && mouse_x < x()+w() && mouse_y >= y()
343 && mouse_y < y()+h())
335344 (void)theLayout->motionNotify (this,
336345 translateViewXToCanvasX (mouse_x),
337346 translateViewYToCanvasY (mouse_y),
424433 }
425434 }
426435
436 /*
437 * Scrolling in response to selection where the cursor is outside the view.
438 */
439 void FltkViewport::selectionScroll ()
440 {
441 int distance;
442 int dx = 0, dy = 0;
443
444 if ((distance = x() - mouse_x) > 0)
445 dx = -distance * hscrollbar->linesize () / 48 - 1;
446 else if ((distance = mouse_x - (x() + w())) > 0)
447 dx = distance * hscrollbar->linesize () / 48 + 1;
448 if ((distance = y() - mouse_y) > 0)
449 dy = -distance * vscrollbar->linesize () / 48 - 1;
450 else if ((distance = mouse_y - (y() + h())) > 0)
451 dy = distance * vscrollbar->linesize () / 48 + 1;
452
453 scroll (dx, dy);
454 }
455
456 void FltkViewport::selectionScroll (void *data)
457 {
458 ((FltkViewport *)data)->selectionScroll ();
459 Fl::repeat_timeout(0.025, selectionScroll, data);
460 }
461
427462 void FltkViewport::setViewportSize (int width, int height,
428463 int hScrollbarThickness,
429464 int vScrollbarThickness)
3838 static void hscrollbarCallback (Fl_Widget *hscrollbar, void *viewportPtr);
3939 static void vscrollbarCallback (Fl_Widget *vscrollbar, void *viewportPtr);
4040
41 void selectionScroll();
42 static void selectionScroll(void *vport);
43
4144 void updateCanvasWidgets (int oldScrollX, int oldScrollY);
4245 static void draw_area (void *data, int x, int y, int w, int h);
4346
0 /*
1 * Dillo Widget
2 *
3 * Copyright 2012-2013 Sebastian Geerken <sgeerken@dillo.org>,
4 * Johannes Hofmann <Johannes.Hofmann@gmx.de>
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
21 #include "hyphenator.hh"
22
23 #include "../lout/misc.hh"
24 #include "../lout/unicode.hh"
25 #include <limits.h>
26 #include <stdio.h>
27 #include <string.h>
28
29 #define LEN 1000
30
31 /*
32 * This is (or at least began as) a direct translation of Ned Batchelder's
33 * public-domain Python implementation at
34 * http://nedbatchelder.com/code/modules/hyphenate.py
35 */
36
37 using namespace lout::object;
38 using namespace lout::container::typed;
39 using namespace lout::misc;
40 using namespace lout::unicode;
41
42 namespace dw {
43
44 HashTable <String, Hyphenator> *Hyphenator::hyphenators =
45 new HashTable <String, Hyphenator> (true, true);
46
47 Hyphenator::Hyphenator (const char *patFile, const char *excFile, int pack)
48 {
49 trie = NULL; // As long we are not sure whether a pattern file can be read.
50
51 char buf[PATH_MAX + 1];
52 snprintf(buf, sizeof (buf), "%s.trie", patFile);
53 FILE *trieF = fopen (buf, "r");
54
55 if (trieF) {
56 trie = new Trie ();
57 if (trie->load (trieF) != 0) {
58 delete trie;
59 trie = NULL;
60 }
61 fclose (trieF);
62 }
63
64 if (trie == NULL) {
65 TrieBuilder trieBuilder(pack);
66 FILE *patF = fopen (patFile, "r");
67 if (patF) {
68
69 while (!feof (patF)) {
70 char buf[LEN + 1];
71 char *s = fgets (buf, LEN, patF);
72 if (s && s[0] != '%') { // ignore lines starting with '%' as comment
73 // TODO Better exit with an error, when the line is too long.
74 int l = strlen (s);
75 if (s[l - 1] == '\n')
76 s[l - 1] = 0;
77 insertPattern (&trieBuilder, s);
78 }
79 }
80
81 trie = trieBuilder.createTrie ();
82 fclose (patF);
83 }
84 }
85
86 exceptions = NULL; // Again, only instantiated when needed.
87
88 FILE *excF = fopen (excFile, "r");
89 if (excF) {
90 exceptions = new HashTable <ConstString, Vector <Integer> > (true, true);
91 while (!feof (excF)) {
92 char buf[LEN + 1];
93 char *s = fgets (buf, LEN, excF);
94 if (s && s[0] != '%') { // ignore lines starting with '%' as comment
95 // TODO Better exit with an error, when the line is too long.
96 int l = strlen (s);
97 if (s[l - 1] == '\n')
98 s[l - 1] = 0;
99 insertException (s);
100 }
101 }
102 fclose (excF);
103 }
104 }
105
106 Hyphenator::~Hyphenator ()
107 {
108 delete trie;
109 delete exceptions;
110 }
111
112 Hyphenator *Hyphenator::getHyphenator (const char *lang)
113 {
114 String *langString = new String (lang);
115
116 Hyphenator *hyphenator = hyphenators->get (langString);
117 if (hyphenator)
118 delete langString;
119 else {
120 char patFile [PATH_MAX];
121 snprintf (patFile, sizeof (patFile), "%s/hyphenation/%s.pat",
122 DILLO_LIBDIR, lang);
123 char excFile [PATH_MAX];
124 snprintf (excFile, sizeof(excFile), "%s/hyphenation/%s.exc",
125 DILLO_LIBDIR, lang);
126
127 //printf ("Loading hyphenation patterns for language '%s' from '%s' and "
128 // "exceptions from '%s' ...\n", lang, patFile, excFile);
129
130 hyphenator = new Hyphenator (patFile, excFile);
131 hyphenators->put (langString, hyphenator);
132 }
133
134 //lout::misc::StringBuffer sb;
135 //hyphenators->intoStringBuffer (&sb);
136 //printf ("%s\n", sb.getChars ());
137
138 return hyphenator;
139 }
140
141 void Hyphenator::insertPattern (TrieBuilder *trieBuilder, char *s)
142 {
143 // Convert the a pattern like 'a1bc3d4' into a string of chars 'abcd'
144 // and a list of points [ 0, 1, 0, 3, 4 ].
145 int l = strlen (s);
146 char chars [l + 1];
147 SimpleVector<char> points (1);
148
149 // TODO numbers consisting of multiple digits?
150 // TODO Encoding: This implementation works exactly like the Python
151 // implementation, based on UTF-8. Does this always work?
152 int numChars = 0;
153 for (int i = 0; s[i]; i++) {
154 if (s[i] >= '0' && s[i] <= '9') {
155 points.setSize(numChars + 1, '0');
156 points.set(numChars, s[i]);
157 } else {
158 chars[numChars++] = s[i];
159 }
160 }
161 chars[numChars] = 0;
162
163 points.setSize(numChars + 2, '0');
164 points.set(numChars + 1, '\0');
165
166 // Insert the pattern into the tree. Each character finds a dict
167 // another level down in the tree, and leaf nodes have the list of
168 // points.
169
170 //printf("insertPattern %s\n", chars);
171
172 trieBuilder->insert (chars, points.getArray ());
173 }
174
175 void Hyphenator::insertException (char *s)
176 {
177 Vector<Integer> *breaks = new Vector<Integer> (1, true);
178
179 int len = strlen (s);
180 for (int i = 0; i < len - 1; i++)
181 if((unsigned char)s[i] == 0xc2 && (unsigned char)s[i + 1] == 0xad)
182 breaks->put (new Integer (i - 2 * breaks->size()));
183
184 char noHyphens[len - 2 * breaks->size() + 1];
185 int j = 0;
186 for (int i = 0; i < len; ) {
187 if(i < len - 1 &&
188 (unsigned char)s[i] == 0xc2 && (unsigned char)s[i + 1] == 0xad)
189 i += 2;
190 else
191 noHyphens[j++] = s[i++];
192 }
193 noHyphens[j] = 0;
194
195 exceptions->put (new String (noHyphens), breaks);
196 }
197
198 /**
199 * Simple test to avoid much costs. Passing it does not mean that the word
200 * can be hyphenated.
201 */
202 bool Hyphenator::isHyphenationCandidate (const char *word)
203 {
204 // Short words aren't hyphenated.
205 return (strlen (word) > 4); // TODO UTF-8?
206 }
207
208 /**
209 * Test whether the character on which "s" points (UTF-8) is an actual
210 * part of the word. Other characters at the beginning and end are
211 * ignored.
212 *
213 * TODO Currently only suitable for English and German.
214 * TODO Only lowercase. (Uppercase not needed.)
215 */
216 bool Hyphenator::isCharPartOfActualWord (char *s)
217 {
218 #if 0
219 // Return true when "s" points to a letter.
220 return (s[0] >= 'a' && s[0] <= 'z') ||
221 // UTF-8: starts with 0xc3
222 ((unsigned char)s[0] == 0xc3 &&
223 ((unsigned char)s[1] == 0xa4 /* ä */ ||
224 (unsigned char)s[1] == 0xb6 /* ö */ ||
225 (unsigned char)s[1] == 0xbc /* ü */ ||
226 (unsigned char)s[1] == 0x9f /* ß */ ));
227 #endif
228
229 return isAlpha (decodeUtf8 (s));
230 }
231
232 /**
233 * Given a word, returns a list of the possible hyphenation points.
234 */
235 int *Hyphenator::hyphenateWord(core::Platform *platform,
236 const char *word, int *numBreaks)
237 {
238 if ((trie == NULL && exceptions ==NULL) || !isHyphenationCandidate (word)) {
239 *numBreaks = 0;
240 return NULL;
241 }
242
243 char *wordLc = platform->textToLower (word, strlen (word));
244
245 int start = 0;
246 SimpleVector <int> breakPos (1);
247
248 // Split the original word up, ignore anything but characters, and
249 // collect all break points, so that they fit to the original
250 // word. (The latter is what the offset in the call of
251 // hyphenateSingleWord() is for.)
252 while (true) {
253 while (wordLc[start] && !isCharPartOfActualWord (wordLc + start))
254 start = platform->nextGlyph (wordLc, start);
255
256 if (wordLc[start] == 0)
257 break;
258
259 int end = start, i = end;
260 while (wordLc[i]) {
261 if (!isCharPartOfActualWord (wordLc + i))
262 break;
263 else
264 end = i;
265 i = platform->nextGlyph (wordLc, i);
266 }
267 end = platform->nextGlyph (wordLc, end);
268
269 int nextStart;
270 if (wordLc[end]) {
271 nextStart = platform->nextGlyph (wordLc, end);
272 wordLc[end] = 0;
273 } else
274 nextStart = end;
275
276 hyphenateSingleWord (platform, wordLc + start, start, &breakPos);
277 start = nextStart;
278 }
279
280 free (wordLc);
281
282 *numBreaks = breakPos.size ();
283 if (*numBreaks == 0)
284 return NULL;
285 else {
286 return breakPos.detachArray ();
287 }
288 }
289
290 /**
291 * Hyphenate a single word, which only consists of lowercase
292 * characters. Store break positions + "offset" in "breakPos".
293 */
294 void Hyphenator::hyphenateSingleWord(core::Platform *platform,
295 char *wordLc, int offset,
296 SimpleVector <int> *breakPos)
297 {
298 // If the word is an exception, get the stored points.
299 Vector <Integer> *exceptionalBreaks;
300 ConstString key (wordLc);
301 if (exceptions != NULL && (exceptionalBreaks = exceptions->get (&key))) {
302 for (int i = 0; i < exceptionalBreaks->size(); i++) {
303 breakPos->increase ();
304 breakPos->set (breakPos->size() - 1,
305 exceptionalBreaks->get(i)->getValue() + offset);
306 }
307 return;
308 }
309
310
311 // trie == NULL means that there is no pattern file.
312 if (trie == NULL)
313 return;
314
315 char work[strlen (wordLc) + 3];
316 strcpy (work, ".");
317 strcat (work, wordLc);
318 strcat (work, ".");
319
320 int l = strlen (work);
321 SimpleVector <int> points (l + 1);
322 points.setSize (l + 1, 0);
323
324 for (int i = 0; i < l; i++) {
325 int state = trie->root;
326
327 for (int j = i; j < l && trie->validState (state); j++) {
328 const char *p = trie->getData((unsigned char) work[j], &state);
329
330 if (p) {
331 for (int k = 0; p[k]; k++)
332 points.set(i + k,
333 lout::misc::max (points.get (i + k), p[k] - '0'));
334 }
335 }
336 }
337
338 // No hyphens in the first two chars or the last two.
339 // Characters are not bytes, so UTF-8 characters must be counted.
340 const char *s = nextUtf8Char (wordLc);
341 if (s != NULL && (s = nextUtf8Char (s)) != NULL) {
342 // First two characters.
343 int bytesStart = s - wordLc;
344 for (int i = 0; i < bytesStart; i++)
345 points.set (i + 1, 0);
346
347 // Last two characters: instead of iterating back from the end,
348 // we simply iterate from the start to the end and count the
349 // characters.
350
351 int lenBytes = strlen (wordLc);
352 int lenUtf8 = numUtf8Chars (wordLc);
353 int bytesEnd = 0;
354
355 s = wordLc;
356 for (int i = 0; s; s = nextUtf8Char (s), i++) {
357 if (i == lenUtf8 - 2)
358 bytesEnd = lenBytes - (s - wordLc);
359 }
360
361 for (int i = 0; i < bytesEnd; i++)
362 points.set (points.size() - 2 - i, 0);
363 }
364
365 // Examine the points to build the break point list.
366 int n = lout::misc::min ((int)strlen (wordLc), points.size () - 2);
367 for (int i = 0; i < n; i++) {
368 if (points.get(i + 2) % 2) {
369 breakPos->increase ();
370 breakPos->set (breakPos->size() - 1, i + 1 + offset);
371 }
372 }
373 }
374
375 Trie::TrieNode TrieBuilder::trieNodeNull = {'\0', 0, NULL};
376
377 TrieBuilder::TrieBuilder (int pack)
378 {
379 this->pack = pack;
380 dataList = new SimpleVector <DataEntry> (10000);
381 stateStack = new SimpleVector <StackEntry> (10);
382 tree = new SimpleVector <Trie::TrieNode> (20000);
383 dataZone = new ZoneAllocator (1024);
384 stateStackPush(0);
385 }
386
387 TrieBuilder::~TrieBuilder ()
388 {
389 delete dataList;
390 delete stateStack;
391 delete tree;
392 delete dataZone;
393 }
394
395 void TrieBuilder::insert (const char *key, const char *value)
396 {
397 dataList->increase ();
398 dataList->getLastRef ()->key = (unsigned char *) strdup(key);
399 dataList->getLastRef ()->value = dataZone->strdup (value);
400 }
401
402 int TrieBuilder::keyCompare (const void *p1, const void *p2)
403 {
404 DataEntry *pd1 = (DataEntry *) p1;
405 DataEntry *pd2 = (DataEntry *) p2;
406
407 return strcmp ((char *) pd1->key, (char *) pd2->key);
408 }
409
410 int TrieBuilder::insertState (StackEntry *state, bool root)
411 {
412 int i, j;
413
414 if (state->count == 0)
415 return 0;
416
417 if (root) {
418 i = 0; // we reseve slot 0 for the root state
419 } else {
420 /* The bigger pack is the more slots we check and the smaller
421 * the trie will be, but CPU consumption also increases.
422 * Reasonable values for pack seemt to be between 256 and 1024.
423 */
424 i = tree->size () - pack + 2 * state->count;
425
426 if (i < 256) // reserve first 256 entries for the root state
427 i = 256;
428 }
429
430 for (;; i++) {
431 if (i + 256 > tree->size ())
432 tree->setSize (i + 256, trieNodeNull);
433
434 for (j = 1; j < 256; j++) {
435 Trie::TrieNode *tn = tree->getRef(i + j);
436
437 if (tn->c == j || ((state->next[j] || state->data[j]) && tn->c != 0))
438 break;
439 }
440
441 if (j == 256) // found a suitable slot
442 break;
443 }
444
445 for (int j = 1; j < 256; j++) {
446 Trie::TrieNode *tn = tree->getRef(i + j);
447
448 if (state->next[j] || state->data[j]) {
449 tn->c = j;
450 tn->next = state->next[j];
451 tn->data = state->data[j];
452 }
453 }
454
455 assert (root || i >= 256);
456 assert (!root || i == 0);
457 return i;
458 }
459
460 void TrieBuilder::stateStackPush (unsigned char c)
461 {
462 stateStack->increase ();
463 StackEntry *e = stateStack->getLastRef ();
464 memset (e, 0, sizeof (StackEntry));
465 e->c = c;
466 }
467
468 int TrieBuilder::stateStackPop ()
469 {
470 int next = insertState (stateStack->getLastRef (), stateStack->size () == 1);
471 unsigned char c = stateStack->getLastRef ()->c;
472 const char *data = stateStack->getLastRef ()->data1;
473
474 stateStack->setSize (stateStack->size () - 1);
475
476 if (stateStack->size () > 0) {
477 assert (stateStack->getLastRef ()->next[c] == 0);
478 assert (stateStack->getLastRef ()->data[c] == NULL);
479 stateStack->getLastRef ()->next[c] = next;
480 stateStack->getLastRef ()->data[c] = data;
481 stateStack->getLastRef ()->count++;
482 }
483
484 return next;
485 }
486
487 Trie *TrieBuilder::createTrie ()
488 {
489 // we need to sort the patterns as byte strings not as unicode
490 qsort (dataList->getArray (), dataList->size (),
491 sizeof (DataEntry), keyCompare);
492
493 for (int i = 0; i < dataList->size (); i++) {
494 insertSorted (dataList->getRef (i)->key, dataList->getRef (i)->value);
495 free (dataList->getRef (i)->key);
496 }
497
498 while (stateStack->size ())
499 stateStackPop ();
500
501 int size = tree->size ();
502 Trie *trie = new Trie(tree->detachArray(), size, true, dataZone);
503 dataZone = NULL;
504 return trie;
505 }
506
507 void TrieBuilder::insertSorted (unsigned char *s, const char *data)
508 {
509 int len = strlen((char*)s);
510
511 for (int i = 0; i < len; i++) {
512 if (stateStack->size () > i + 1 &&
513 stateStack->getRef (i + 1)->c != s[i]) {
514 for (int j = stateStack->size () - 1; j >= i + 1; j--)
515 stateStackPop();
516 }
517
518 if (i + 1 >= stateStack->size ())
519 stateStackPush(s[i]);
520 }
521
522 while (stateStack->size () > len + 1)
523 stateStackPop();
524
525 assert (stateStack->size () == len + 1);
526 stateStack->getLastRef ()->data1 = data;
527 }
528
529 Trie::Trie (TrieNode *array, int size, bool freeArray, ZoneAllocator *dataZone)
530 {
531 this->array = array;
532 this->size = size;
533 this->freeArray = freeArray;
534 this->dataZone = dataZone;
535 }
536
537 Trie::~Trie ()
538 {
539 delete dataZone;
540 if (freeArray)
541 free(array);
542 }
543
544 void Trie::save (FILE *file)
545 {
546 for (int i = 0; i < size; i++) {
547 Trie::TrieNode *tn = &array[i];
548
549 if (tn->data)
550 fprintf(file, "%u, %u, %s\n", tn->c, tn->next, tn->data);
551 else
552 fprintf(file, "%u, %u\n", tn->c, tn->next);
553 }
554 }
555
556 int Trie::load (FILE *file)
557 {
558 int next, c, maxNext = 0;
559 SimpleVector <TrieNode> tree (100);
560 dataZone = new ZoneAllocator (1024);
561
562 while (!feof (file)) {
563 char buf[LEN + 1];
564 char *s = fgets (buf, LEN, file);
565
566 if (!s)
567 continue;
568
569 char data[LEN + 1];
570 int n = sscanf (s, "%u, %u, %s", &c, &next, data);
571
572 if (n >= 2 && c >= 0 && c < 256 && next >= 0) {
573 tree.increase ();
574 tree.getLastRef ()->c = c;
575 tree.getLastRef ()->next = next;
576 if (n >= 3)
577 tree.getLastRef ()->data = dataZone->strdup (data);
578 else
579 tree.getLastRef ()->data = NULL;
580
581 if (next > maxNext)
582 maxNext = next;
583 } else {
584 goto error;
585 }
586 }
587
588 if (maxNext >= tree.size ())
589 goto error;
590
591 size = tree.size ();
592 array = tree.detachArray ();
593 freeArray = true;
594 return 0;
595
596 error:
597 delete dataZone;
598 dataZone = NULL;
599 return 1;
600 }
601
602 } // namespace dw
0 #ifndef __DW_HYPHENATOR_HH__
1 #define __DW_HYPHENATOR_HH__
2
3 #include "../lout/object.hh"
4 #include "../lout/container.hh"
5 #include "../dw/core.hh"
6
7 namespace dw {
8
9 class Trie {
10 public:
11 struct TrieNode {
12 unsigned char c;
13 uint16_t next;
14 const char *data;
15 };
16
17 private:
18 TrieNode *array;
19 int size;
20 bool freeArray;
21 lout::misc::ZoneAllocator *dataZone;
22
23 public:
24 Trie (TrieNode *array = NULL, int size = 0, bool freeArray = false,
25 lout::misc::ZoneAllocator *dataZone = NULL);
26 ~Trie ();
27
28 static const int root = 0;
29 inline bool validState (int state) { return state >= 0 && state < size; };
30 inline const char *getData (unsigned char c, int *state)
31 {
32 if (!validState (*state))
33 return NULL;
34
35 TrieNode *tn = array + *state + c;
36
37 if (tn->c == c) {
38 *state = tn->next > 0 ? tn->next : -1;
39 return tn->data;
40 } else {
41 *state = -1;
42 return NULL;
43 }
44 };
45 void save (FILE *file);
46 int load (FILE *file);
47 };
48
49 class TrieBuilder {
50 private:
51 struct StackEntry {
52 unsigned char c;
53 int count;
54 int next[256];
55 const char *data[256];
56 const char *data1;
57 };
58
59 struct DataEntry {
60 unsigned char *key;
61 const char *value;
62 };
63
64 int pack;
65 static Trie::TrieNode trieNodeNull;
66 lout::misc::SimpleVector <Trie::TrieNode> *tree;
67 lout::misc::SimpleVector <DataEntry> *dataList;
68 lout::misc::SimpleVector <StackEntry> *stateStack;
69 lout::misc::ZoneAllocator *dataZone;
70
71 static int keyCompare (const void *p1, const void *p2);
72 void stateStackPush (unsigned char c);
73 int stateStackPop ();
74 int insertState (StackEntry *state, bool root);
75 void insertSorted (unsigned char *key, const char *value);
76
77 public:
78 TrieBuilder (int pack);
79 ~TrieBuilder ();
80
81 void insert (const char *key, const char *value);
82 Trie *createTrie();
83 };
84
85 class Hyphenator: public lout::object::Object
86 {
87 static lout::container::typed::HashTable
88 <lout::object::String, Hyphenator> *hyphenators;
89 Trie *trie;
90
91 lout::container::typed::HashTable <lout::object::ConstString,
92 lout::container::typed::Vector
93 <lout::object::Integer> > *exceptions;
94
95 void insertPattern (TrieBuilder *trieBuilder, char *s);
96 void insertException (char *s);
97
98 void hyphenateSingleWord(core::Platform *platform, char *wordLc, int offset,
99 lout::misc::SimpleVector <int> *breakPos);
100 bool isCharPartOfActualWord (char *s);
101
102 public:
103 Hyphenator (const char *patFile, const char *excFile, int pack = 256);
104 ~Hyphenator();
105
106 static Hyphenator *getHyphenator (const char *language);
107 static bool isHyphenationCandidate (const char *word);
108 int *hyphenateWord(core::Platform *platform, const char *word, int *numBreaks);
109 void saveTrie (FILE *fp) { trie->save (fp); };
110 };
111
112 } // namespace dw
113
114 #endif // __DW_HYPHENATOR_HH__
174174
175175 virtual Imgbuf* getScaledBuf (int width, int height) = 0;
176176 virtual void getRowArea (int row, dw::core::Rectangle *area) = 0;
177 virtual int getRootWidth () = 0;
178 virtual int getRootHeight () = 0;
177 virtual int getRootWidth () = 0;
178 virtual int getRootHeight () = 0;
179179
180180 /*
181181 * Reference counting.
201201 virtual bool isReferred () = 0;
202202 };
203203
204 } // namespace core
204205 } // namespace dw
205 } // namespace core
206206
207207 #endif // __DW_IMGBUF_HH__
3636 this->mask = mask;
3737 }
3838
39 Iterator::Iterator(Iterator &it): object::Object (), misc::Comparable ()
39 Iterator::Iterator(Iterator &it): object::Comparable ()
4040 {
4141 widget = it.widget;
4242 content = it.content;
204204 return new EmptyIterator (*this);
205205 }
206206
207 int EmptyIterator::compareTo (misc::Comparable *other)
207 int EmptyIterator::compareTo (object::Comparable *other)
208208 {
209209 EmptyIterator *otherIt = (EmptyIterator*)other;
210210
256256 text = it.text;
257257 }
258258
259 int TextIterator::compareTo (misc::Comparable *other)
259 int TextIterator::compareTo (object::Comparable *other)
260260 {
261261 TextIterator *otherIt = (TextIterator*)other;
262262
534534 return it;
535535 }
536536
537 int DeepIterator::compareTo (misc::Comparable *other)
537 int DeepIterator::compareTo (object::Comparable *other)
538538 {
539539 DeepIterator *otherDeepIterator = (DeepIterator*)other;
540540
664664 return cloned;
665665 }
666666
667 int CharIterator::compareTo(misc::Comparable *other)
667 int CharIterator::compareTo(object::Comparable *other)
668668 {
669669 CharIterator *otherIt = (CharIterator*)other;
670670 int c = it->compareTo(otherIt->it);
793793 }
794794 }
795795
796 } // namespace core
796797 } // namespace dw
797 } // namespace core
1515 *
1616 * \sa dw::core::Widget::iterator
1717 */
18 class Iterator: public lout::object::Object, public lout::misc::Comparable
18 class Iterator: public lout::object::Comparable
1919 {
2020 protected:
2121 Iterator(Widget *widget, Content::Type mask, bool atEnd);
100100 EmptyIterator (Widget *widget, Content::Type mask, bool atEnd);
101101
102102 lout::object::Object *clone();
103 int compareTo(lout::misc::Comparable *other);
103 int compareTo(lout::object::Comparable *other);
104104 bool next ();
105105 bool prev ();
106106 void highlight (int start, int end, HighlightLayer layer);
125125 TextIterator (Widget *widget, Content::Type mask, bool atEnd,
126126 const char *text);
127127
128 int compareTo(lout::misc::Comparable *other);
128 int compareTo(lout::object::Comparable *other);
129129
130130 bool next ();
131131 bool prev ();
141141 * iterators do not have the limitation, that iteration is only done within
142142 * a widget, instead, child widgets are iterated through recursively.
143143 */
144 class DeepIterator: public lout::object::Object, public lout::misc::Comparable
144 class DeepIterator: public lout::object::Comparable
145145 {
146146 private:
147147 class Stack: public lout::container::typed::Vector<Iterator>
182182 bool next ();
183183 bool prev ();
184184 inline DeepIterator *cloneDeepIterator() { return (DeepIterator*)clone(); }
185 int compareTo(lout::misc::Comparable *other);
185 int compareTo(lout::object::Comparable *other);
186186
187187 /**
188188 * \brief Highlight a part of the current content.
215215 start, end, hpos, vpos); }
216216 };
217217
218 class CharIterator: public lout::object::Object, public lout::misc::Comparable
218 class CharIterator: public lout::object::Comparable
219219 {
220220 public:
221221 // START and END must not clash with any char value
233233 ~CharIterator ();
234234
235235 lout::object::Object *clone();
236 int compareTo(lout::misc::Comparable *other);
236 int compareTo(lout::object::Comparable *other);
237237
238238 bool next ();
239239 bool prev ();
251251 hpos, vpos); }
252252 };
253253
254 } // namespace core
254255 } // namespace dw
255 } // namespace core
256256
257257 #endif // __ITERATOR_HH__
413413 case HPOS_CENTER:
414414 scrollX =
415415 scrollTargetX
416 - (viewportWidth - vScrollbarThickness - scrollTargetWidth) / 2;
416 - (viewportWidth - currVScrollbarThickness() - scrollTargetWidth) / 2;
417417 break;
418418 case HPOS_RIGHT:
419419 scrollX =
420420 scrollTargetX
421 - (viewportWidth - vScrollbarThickness - scrollTargetWidth);
421 - (viewportWidth - currVScrollbarThickness() - scrollTargetWidth);
422422 break;
423423 case HPOS_INTO_VIEW:
424424 xChanged = calcScrollInto (scrollTargetX, scrollTargetWidth, &scrollX,
425 viewportWidth - vScrollbarThickness);
425 viewportWidth - currVScrollbarThickness());
426426 break;
427427 case HPOS_NO_CHANGE:
428428 xChanged = false;
437437 case VPOS_CENTER:
438438 scrollY =
439439 scrollTargetY
440 - (viewportHeight - hScrollbarThickness - scrollTargetHeight) / 2;
440 - (viewportHeight - currHScrollbarThickness() - scrollTargetHeight)/2;
441441 break;
442442 case VPOS_BOTTOM:
443443 scrollY =
444444 scrollTargetY
445 - (viewportHeight - hScrollbarThickness - scrollTargetHeight);
445 - (viewportHeight - currHScrollbarThickness() - scrollTargetHeight);
446446 break;
447447 case VPOS_INTO_VIEW:
448448 yChanged = calcScrollInto (scrollTargetY, scrollTargetHeight, &scrollY,
449 viewportHeight - hScrollbarThickness);
449 viewportHeight - currHScrollbarThickness());
450450 break;
451451 case VPOS_NO_CHANGE:
452452 yChanged = false;
534534 }
535535 }
536536
537 int Layout::currHScrollbarThickness()
538 {
539 return (canvasWidth > viewportWidth) ? hScrollbarThickness : 0;
540 }
541
542 int Layout::currVScrollbarThickness()
543 {
544 return (canvasAscent + canvasDescent > viewportHeight) ?
545 vScrollbarThickness : 0;
546 }
547
537548 /**
538549 * Sets the anchor to scroll to.
539550 */
672683 // view->queueDrawTotal (false);
673684
674685 if (usesViewport) {
675 int actualHScrollbarThickness =
676 (canvasWidth > viewportWidth) ? hScrollbarThickness : 0;
677 int actualVScrollbarThickness =
678 (canvasAscent + canvasDescent > viewportHeight) ?
679 vScrollbarThickness : 0;
686 int currHThickness = currHScrollbarThickness();
687 int currVThickness = currVScrollbarThickness();
680688
681689 if (!canvasHeightGreater &&
682690 canvasAscent + canvasDescent
683 > viewportHeight - actualHScrollbarThickness) {
691 > viewportHeight - currHThickness) {
684692 canvasHeightGreater = true;
685693 setSizeHints ();
686694 /* May queue a new resize. */
688696
689697 // Set viewport sizes.
690698 view->setViewportSize (viewportWidth, viewportHeight,
691 actualHScrollbarThickness,
692 actualVScrollbarThickness);
699 currHThickness, currVThickness);
693700 }
694701 }
695702
772779 event.button = button;
773780 event.numPressed = numPressed;
774781
775 return processMouseEvent (&event, type, true);
782 return processMouseEvent (&event, type);
776783 }
777784
778785 /**
791798 event.yCanvas = y;
792799 event.state = state;
793800
794 return processMouseEvent (&event, MOTION_NOTIFY, true);
801 return processMouseEvent (&event, MOTION_NOTIFY);
795802 }
796803
797804 /**
944951 * has been called before.
945952 */
946953 bool Layout::processMouseEvent (MousePositionEvent *event,
947 ButtonEventType type, bool mayBeSuppressed)
954 ButtonEventType type)
948955 {
949956 Widget *widget;
950957
951 for (widget = widgetAtPoint; widget; widget = widget->getParent ()) {
952 if (!mayBeSuppressed || widget->isButtonSensitive ()) {
958 /*
959 * If the event is outside of the visible region of the canvas, treat it
960 * as occurring at the region's edge. Notably, this helps when selecting
961 * text.
962 */
963 if (event->xCanvas < scrollX)
964 event->xCanvas = scrollX;
965 else {
966 int maxX = scrollX + viewportWidth - currVScrollbarThickness() - 1;
967
968 if (event->xCanvas > maxX)
969 event->xCanvas = maxX;
970 }
971 if (event->yCanvas < scrollY)
972 event->yCanvas = scrollY;
973 else {
974 int maxY = misc::min(scrollY + viewportHeight -currHScrollbarThickness(),
975 canvasAscent + canvasDescent) - 1;
976
977 if (event->yCanvas > maxY)
978 event->yCanvas = maxY;
979 }
980
981 widget = getWidgetAtPoint(event->xCanvas, event->yCanvas);
982
983 for (; widget; widget = widget->getParent ()) {
984 if (widget->isButtonSensitive ()) {
953985 event->xWidget = event->xCanvas - widget->getAllocation()->x;
954986 event->yWidget = event->yCanvas - widget->getAllocation()->y;
955987
10171049 setSizeHints ();
10181050 }
10191051
1052 } // namespace core
10201053 } // namespace dw
1021 } // namespace core
1022
175175 */
176176 void moveOutOfView (ButtonState state) { moveToWidget (NULL, state); }
177177
178 bool processMouseEvent (MousePositionEvent *event, ButtonEventType type,
179 bool mayBeSuppressed);
178 bool processMouseEvent (MousePositionEvent *event, ButtonEventType type);
180179 bool buttonEvent (ButtonEventType type, View *view,
181180 int numPressed, int x, int y, ButtonState state,
182181 int button);
191190 void adjustScrollPos ();
192191 static bool calcScrollInto (int targetValue, int requestedSize,
193192 int *value, int viewportSize);
193 int currHScrollbarThickness();
194 int currVScrollbarThickness();
194195
195196 void updateAnchor ();
196197
289290 void scrollPosChanged (View *view, int x, int y);
290291 void viewportSizeChanged (View *view, int width, int height);
291292
293 inline Platform *getPlatform ()
294 {
295 return platform;
296 }
297
292298 /* delegated */
293299
294300 inline int textWidth (style::Font *font, const char *text, int len)
328334
329335 inline style::Font *createFont (style::FontAttrs *attrs, bool tryEverything)
330336 {
331 return platform->createFont (attrs, tryEverything);
337 return platform->createFont (attrs, tryEverything);
332338 }
333339
334340 inline bool fontExists (const char *name)
382388 inline style::Color* getBgColor () { return bgColor; }
383389 };
384390
391 } // namespace core
385392 } // namespace dw
386 } // namespace core
387393
388394 #endif // __DW_LAYOUT_HH__
389395
4343 * \brief This methods notifies the platform, that a view has been detached
4444 * from the related layout.
4545 */
46 virtual void detachView (View *view) = 0;
46 virtual void detachView (View *view) = 0;
4747
4848 /*
4949 * -----------------------------------
163163 virtual ui::ResourceFactory *getResourceFactory () = 0;
164164 };
165165
166 } // namespace core
166167 } // namespace dw
167 } // namespace core
168168
169169 #endif // __DW_PLATFORM_HH__
343343 return misc::min(charPos, len);
344344 }
345345
346 void SelectionState::highlight0 (bool fl, DeepIterator *from, int fromChar,
347 DeepIterator *to, int toChar, int dir)
346 void SelectionState::highlight0 (bool fl, DeepIterator *from, int fromChar,
347 DeepIterator *to, int toChar, int dir)
348348 {
349349 DeepIterator *a, *b, *i;
350350 int cmp, aChar, bChar;
475475 }
476476 }
477477
478 } // namespace core
478479 } // namespace dw
479 } // namespace core
234234 int linkNo, MousePositionEvent *event);
235235 };
236236
237 } // namespace core
237238 } // namespace dw
238 } // namespace core
239239
240240 #endif // __DW_SELECTION_H__
3636 void StyleAttrs::initValues ()
3737 {
3838 x_link = -1;
39 x_lang[0] = x_lang[1] = 0;
3940 x_img = -1;
4041 x_tooltip = NULL;
4142 textDecoration = TEXT_DECORATION_NONE;
143144 listStyleType == otherAttrs->listStyleType &&
144145 cursor == otherAttrs->cursor &&
145146 x_link == otherAttrs->x_link &&
147 x_lang[0] == otherAttrs->x_lang[0] &&
148 x_lang[1] == otherAttrs->x_lang[1] &&
146149 x_img == otherAttrs->x_img &&
147150 x_tooltip == otherAttrs->x_tooltip);
148151 }
169172 borderCollapse +
170173 (intptr_t) borderColor.top +
171174 (intptr_t) borderColor.right +
172 (intptr_t) borderColor.bottom +
173 (intptr_t) borderColor.left +
175 (intptr_t) borderColor.bottom +
176 (intptr_t) borderColor.left +
174177 borderStyle.top +
175178 borderStyle.right +
176179 borderStyle.bottom +
181184 listStyleType +
182185 cursor +
183186 x_link +
187 x_lang[0] + x_lang[1] +
184188 x_img +
185189 (intptr_t) x_tooltip;
186190 }
266270 listStyleType = attrs->listStyleType;
267271 cursor = attrs->cursor;
268272 x_link = attrs->x_link;
273 x_lang[0] = attrs->x_lang[0];
274 x_lang[1] = attrs->x_lang[1];
269275 x_img = attrs->x_img;
270276 x_tooltip = attrs->x_tooltip;
271277 }
951957 }
952958
953959 } // namespace style
960 } // namespace core
954961 } // namespace dw
955 } // namespace core
259259 enum DisplayType {
260260 DISPLAY_BLOCK,
261261 DISPLAY_INLINE,
262 DISPLAY_INLINE_BLOCK,
262263 DISPLAY_LIST_ITEM,
263264 DISPLAY_NONE,
264265 DISPLAY_TABLE,
466467 int x_link;
467468 int x_img;
468469 Tooltip *x_tooltip;
470 char x_lang[2]; /* Either x_lang[0] == x_lang[1] == 0 (no language
471 set), or x_lang contains the RFC 1766 country
472 code in lower case letters. (Only two letters
473 allowed, currently.) */
469474
470475 void initValues ();
471476 void resetValues ();
523528 void copyAttrs (StyleAttrs *attrs);
524529
525530 public:
526 inline static Style *create (Layout *layout, StyleAttrs *attrs)
531 inline static Style *create (StyleAttrs *attrs)
527532 {
528533 Style *style = styleTable->get (attrs);
529534 if (style) {
680685 void numtostr (int num, char *buf, int buflen, ListStyleType listStyleType);
681686
682687 } // namespace style
688 } // namespace core
683689 } // namespace dw
684 } // namespace core
685690
686691 #endif // __DW_STYLE_HH__
687692
876876 int curNewWidth = minAutoWidth;
877877 for (int col = 0; col < numCols; col++) {
878878 _MSG("app2, col %d, minWidth=%d maxWidth=%d\n",
879 col,extremes->get(col).minWidth, colExtremes->get(col).maxWidth);
879 col, colExtremes->getRef(col)->minWidth,
880 colExtremes->get(col).maxWidth);
880881
881882 if (colPercents->get(col) != LEN_AUTO)
882883 continue;
11121113 return new TableIterator ((Table*)getWidget(), getMask(), index);
11131114 }
11141115
1115 int Table::TableIterator::compareTo(misc::Comparable *other)
1116 int Table::TableIterator::compareTo(object::Comparable *other)
11161117 {
11171118 return index - ((TableIterator*)other)->index;
11181119 }
117117 *
118118 * <ol>
119119 * <li> First, only cells with colspan = 1 are regarded:
120 *
121120 * \f[ e_{\hbox{base},i,\min} = \max \{ e_{\hbox{cell},i,j,\min} \} \f]
122121 * \f[ e_{\hbox{base},i,\max} = \max \{ e_{\hbox{cell},i,j,\max} \} \f]
123 *
124122 * only for cells \f$(i, j)\f$ with colspan = 1.
125123 *
126124 * <li> Then,
129127 * the cell at \f$(i_1, j)\f$ always span from \f$i_1\f$ to \f$i_2\f$.)
130128 * If the minimal width of the column exceeds the sum of the column minima
131129 * calculated in the last step:
132 *
133130 * \f[e_{\hbox{cell},i_1,j,\min} >
134131 * \sum_{i=i_1}^{i=i_2} e_{\hbox{base},i,\min}\f]
135 *
136132 * then the minimal width of this cell is apportioned to the columns:
137133 *
138134 * <ul>
139135 * <li> If the minimal width of this cell also exceeds the sum of the
140136 * column maxima:
141 *
142137 * \f[e_{\hbox{cell},i_1,j,\min} >
143138 * \sum_{i=i_1}^{i=i_2} e_{\hbox{base},i,\max}\f]
144 *
145139 * then \f$e_{\hbox{cell},i_1,j,\min}\f$ is apportioned in a simple
146140 * way:
147 *
148141 * \f[e_{\hbox{span},i,j,\min} =
149142 * e_{\hbox{base},i,\max}
150143 * {e_{\hbox{span},i,j,\min} \over
151144 * \sum_{i=i_1}^{i=i_2} e_{\hbox{base},i,\max}}\f]
152 *
153145 * <li> Otherwise, the apportionment function is used:
154 *
155146 * \f[e_{\hbox{span},i,j,\min} =
156147 * a_i (e_{\hbox{cell},i_1,j,\min},
157148 * (e_{\hbox{cell},i_1,j,\min} \ldots
171162 * For the maxima, there is no \f$e_{\hbox{span},i,\max}\f$, but it has to
172163 * be assured, that the maximum is always greater than or equal to the
173164 * minimum.
165 *
174166 * </ol>
175167 *
176168 * Generally, if absolute widths are specified, they are, instead of the
222214 * no percentage width has been specified. The difference to the total
223215 * width is at max available to the columns with percentage width
224216 * specifications:
225 *
226217 * \f[W_{\hbox{columns}_\%,\hbox{available}} = W - \sum e_{i,\min}\f]
227 *
228218 * with only those columns \f$i\f$ with no percentage width specification.
229219 *
230220 * <li> Then, calculate the sum of the widths, which the columns with
231221 * percentage width specification would allocate, when fully adhering to
232222 * them:
233 *
234223 * \f[W_{\hbox{columns}_\%,\hbox{best}} = W \sum w_{i,\%}\f]
235 *
236224 * with only those columns \f$i\f$ with a percentage width specification.
237225 *
238226 * <li> Two cases are distinguished:
242230 * W_{\hbox{columns}_\%,\hbox{best}}\f$: In this case, the
243231 * percentage widths can be used without any modification, by
244232 * setting the extremes:
245 *
246233 * \f[e_{i,\min} = e_{i,\max} = W w_{i,\%}\f]
247 *
248234 * for only those columns \f$i\f$ with a percentage width
249235 * specification.
250236 *
251237 * <li> \f$W_{\hbox{columns}_\%,\hbox{available}} <
252238 * W_{\hbox{columns}_\%,\hbox{best}}\f$: In this case, the widths
253239 * for these columns must be cut down:
254 *
255240 * \f[e_{i,\min} = e_{i,\max} =
256241 * w_{i,\%}
257242 * {W_{\hbox{columns}_\%,\hbox{available}} \over
258243 * w_{\hbox{total},\%}}\f]
259 *
260244 * with
261 *
262245 * \f[w_{\hbox{total},\%} = \sum w_{i,\%}\f]
263 *
264246 * in both cases for only those columns \f$i\f$ with a percentage
265247 * width specification.
266248 * </ul>
361343 TableIterator (Table *table, core::Content::Type mask, int index);
362344
363345 lout::object::Object *clone();
364 int compareTo(lout::misc::Comparable *other);
346 int compareTo(lout::object::Comparable *other);
365347
366348 bool next ();
367349 bool prev ();
4141 {
4242 }
4343
44 void TableCell::wordWrap(int wordIndex)
44 void TableCell::wordWrap(int wordIndex, bool wrapAll)
4545 {
4646 Textblock::Word *word;
4747 const char *p;
4848
49 Textblock::wordWrap (wordIndex);
49 Textblock::wordWrap (wordIndex, wrapAll);
5050
5151 if (charWordIndex == -1) {
5252 word = words->getRef (wordIndex);
1111 int charWordIndex, charWordPos;
1212
1313 protected:
14 void wordWrap(int wordIndex);
14 void wordWrap (int wordIndex, bool wrapAll);
1515
1616 int getValue ();
1717 void setMaxValue (int maxValue, int value);
00 /*
11 * Dillo Widget
22 *
3 * Copyright 2005-2007 Sebastian Geerken <sgeerken@dillo.org>
3 * Copyright 2005-2007, 2012-2013 Sebastian Geerken <sgeerken@dillo.org>
44 *
55 * This program is free software; you can redistribute it and/or modify
66 * it under the terms of the GNU General Public License as published by
1717 */
1818
1919
20
2120 #include "textblock.hh"
2221 #include "../lout/msg.h"
2322 #include "../lout/misc.hh"
23 #include "../lout/unicode.hh"
2424
2525 #include <stdio.h>
26 #include <limits.h>
26 #include <math.h>
2727
2828 /*
2929 * Local variables
3333 static dw::core::style::Tooltip *hoverTooltip = NULL;
3434
3535
36
3736 using namespace lout;
37 using namespace lout::unicode;
3838
3939 namespace dw {
4040
4141 int Textblock::CLASS_ID = -1;
42
43 Textblock::DivChar Textblock::divChars[NUM_DIV_CHARS] = {
44 // soft hyphen (U+00AD)
45 { "\xc2\xad", true, false, true, PENALTY_HYPHEN, -1 },
46 // simple hyphen-minus: same penalties like automatic or soft hyphens
47 { "-", false, true, true, -1, PENALTY_HYPHEN },
48 // (unconditional) hyphen (U+2010): handled exactly like minus-hyphen.
49 { "\xe2\x80\x90", false, true, true, -1, PENALTY_HYPHEN },
50 // em dash (U+2014): breaks on both sides are allowed (but see below).
51 { "\xe2\x80\x94", false, true, false,
52 PENALTY_EM_DASH_LEFT, PENALTY_EM_DASH_RIGHT }
53 };
54
55 // Standard values are defined here. The values are already multiplied
56 // with 100.
57 //
58 // Some examples (details are described in doc/dw-line-breaking.doc):
59 //
60 // 0 = Perfect line; as penalty used for normal spaces.
61
62 // 1 (100 here) = A justified line with spaces having 150% or 67% of
63 // the ideal space width has this as badness.
64 //
65 // 8 (800 here) = A justified line with spaces twice as wide as
66 // ideally has this as badness.
67 //
68 // The second value is used when the line before ends with a hyphen,
69 // dash etc.
70
71 int Textblock::penalties[PENALTY_NUM][2] = {
72 // Penalties for all hyphens.
73 { 100, 800 },
74 // Penalties for a break point *left* of an em-dash: rather large,
75 // so that a break on the *right* side is preferred.
76 { 800, 800 },
77 // Penalties for a break point *right* of an em-dash: like hyphens.
78 { 100, 800 }
79 };
80
81 /**
82 * The character which is used to draw a hyphen at the end of a line,
83 * either caused by automatic hyphenation, or by soft hyphens.
84 *
85 * Initially, soft hyphens were used, but they are not drawn on some
86 * platforms. Also, unconditional hyphens (U+2010) are not available
87 * in many fonts; so, a simple hyphen-minus is used.
88 */
89 const char *Textblock::hyphenDrawChar = "-";
90
91 void Textblock::setPenaltyHyphen (int penaltyHyphen)
92 {
93 penalties[PENALTY_HYPHEN][0] = penaltyHyphen;
94 }
95
96 void Textblock::setPenaltyHyphen2 (int penaltyHyphen2)
97 {
98 penalties[PENALTY_HYPHEN][1] = penaltyHyphen2;
99 }
100
101 void Textblock::setPenaltyEmDashLeft (int penaltyLeftEmDash)
102 {
103 penalties[PENALTY_EM_DASH_LEFT][0] = penaltyLeftEmDash;
104 penalties[PENALTY_EM_DASH_LEFT][1] = penaltyLeftEmDash;
105 }
106
107 void Textblock::setPenaltyEmDashRight (int penaltyRightEmDash)
108 {
109 penalties[PENALTY_EM_DASH_RIGHT][0] = penaltyRightEmDash;
110 }
111
112 void Textblock::setPenaltyEmDashRight2 (int penaltyRightEmDash2)
113 {
114 penalties[PENALTY_EM_DASH_RIGHT][1] = penaltyRightEmDash2;
115 }
42116
43117 Textblock::Textblock (bool limitTextWidth)
44118 {
50124 hasListitemValue = false;
51125 innerPadding = 0;
52126 line1Offset = 0;
53 line1OffsetEff = 0;
54127 ignoreLine1OffsetSometimes = false;
55128 mustQueueResize = false;
56129 redrawY = 0;
65138 * is that high values decrease speed due to memory handling overhead!)
66139 * TODO: Some tests would be useful.
67140 */
141 paragraphs = new misc::SimpleVector <Paragraph> (1);
68142 lines = new misc::SimpleVector <Line> (1);
69 words = new misc::SimpleVector <Word> (1);
143 nonTemporaryLines = 0;
144 words = new misc::NotSoSimpleVector <Word> (1);
70145 anchors = new misc::SimpleVector <Anchor> (1);
71146
72147 //DBG_OBJ_SET_NUM(this, "num_lines", num_lines);
73148
74 lastLineWidth = 0;
75 lastLineParMax = 0;
76 wrapRef = -1;
149 wrapRefLines = wrapRefParagraphs = -1;
77150
78151 //DBG_OBJ_SET_NUM(this, "last_line_width", last_line_width);
79152 //DBG_OBJ_SET_NUM(this, "last_line_par_min", last_line_par_min);
119192 removeAnchor(anchor->name);
120193 }
121194
195 delete paragraphs;
122196 delete lines;
123197 delete words;
124198 delete anchors;
137211 */
138212 void Textblock::sizeRequestImpl (core::Requisition *requisition)
139213 {
214 PRINTF ("[%p] SIZE_REQUEST: ...\n", this);
215
140216 rewrap ();
217 showMissingLines ();
141218
142219 if (lines->size () > 0) {
143220 Line *lastLine = lines->getRef (lines->size () - 1);
144 requisition->width =
145 misc::max (lastLine->maxLineWidth, lastLineWidth);
221 requisition->width = lastLine->maxLineWidth;
222
223 PRINTF ("[%p] SIZE_REQUEST: lastLine->maxLineWidth = %d\n",
224 this, lastLine->maxLineWidth);
225
226 PRINTF ("[%p] SIZE_REQUEST: lines[0]->boxAscent = %d\n",
227 this, lines->getRef(0)->boxAscent);
228 PRINTF ("[%p] SIZE_REQUEST: lines[%d]->top = %d\n",
229 this, lines->size () - 1, lastLine->top);
230 PRINTF ("[%p] SIZE_REQUEST: lines[%d]->boxAscent = %d\n",
231 this, lines->size () - 1, lastLine->boxAscent);
232 PRINTF ("[%p] SIZE_REQUEST: lines[%d]->boxDescent = %d\n",
233 this, lines->size () - 1, lastLine->boxDescent);
234
146235 /* Note: the breakSpace of the last line is ignored, so breaks
147236 at the end of a textblock are not visible. */
148237 requisition->ascent = lines->getRef(0)->boxAscent;
150239 + lastLine->boxAscent + lastLine->boxDescent -
151240 lines->getRef(0)->boxAscent;
152241 } else {
153 requisition->width = lastLineWidth;
242 requisition->width = 0; // before: lastLineWidth;
154243 requisition->ascent = 0;
155244 requisition->descent = 0;
156245 }
246
247 PRINTF ("[%p] SIZE_REQUEST: inner padding = %d, boxDiffWidth = %d\n",
248 this, innerPadding, getStyle()->boxDiffWidth ());
157249
158250 requisition->width += innerPadding + getStyle()->boxDiffWidth ();
159251 requisition->ascent += getStyle()->boxOffsetY ();
161253
162254 if (requisition->width < availWidth)
163255 requisition->width = availWidth;
256
257 PRINTF ("[%p] SIZE_REQUEST: %d x %d + %d\n", this, requisition->width,
258 requisition->ascent, requisition->descent);
164259 }
165260
166261 /**
198293
199294 void Textblock::getExtremesImpl (core::Extremes *extremes)
200295 {
201 core::Extremes wordExtremes;
202 Line *line;
203 Word *word, *prevWord = NULL;
204 int wordIndex, lineIndex;
205 int parMax;
206
207 //DBG_MSG (widget, "extremes", 0, "getExtremesImpl");
208 //DBG_MSG_START (widget);
209
210 if (lines->size () == 0) {
296 PRINTF ("[%p] GET_EXTREMES ...\n", this);
297
298 fillParagraphs ();
299
300 if (paragraphs->size () == 0) {
211301 /* empty page */
212302 extremes->minWidth = 0;
213303 extremes->maxWidth = 0;
214 } else if (wrapRef == -1) {
215 /* no rewrap necessary -> values in lines are up to date */
216 line = lines->getRef (lines->size () - 1);
217 extremes->minWidth = line->maxParMin;
218 extremes->maxWidth = misc::max (line->maxParMax, lastLineParMax);
219 //DBG_MSG (widget, "extremes", 0, "simple case");
220 } else {
221 /* Calculate the extremes, based on the values in the line from
222 where a rewrap is necessary. */
223 //DBG_MSG (widget, "extremes", 0, "complex case");
224
225 if (wrapRef == 0) {
226 extremes->minWidth = 0;
227 extremes->maxWidth = 0;
228 parMax = 0;
229 } else {
230 line = lines->getRef (wrapRef);
231 extremes->minWidth = line->maxParMin;
232 extremes->maxWidth = line->maxParMax;
233 parMax = line->parMax;
234
235 //DBG_MSGF (widget, "extremes", 0, "parMin = %d", parMin);
236 }
237
238 //_MSG ("*** parMin = %d\n", parMin);
239
240 int prevWordSpace = 0;
241 for (lineIndex = wrapRef; lineIndex < lines->size (); lineIndex++) {
242 //DBG_MSGF (widget, "extremes", 0, "line %d", lineIndex);
243 //DBG_MSG_START (widget);
244 int parMin = 0;
245
246 line = lines->getRef (lineIndex);
247
248 for (wordIndex = line->firstWord; wordIndex <= line->lastWord;
249 wordIndex++) {
250 word = words->getRef (wordIndex);
251 getWordExtremes (word, &wordExtremes);
252
253 if (wordIndex == 0) {
254 wordExtremes.minWidth += line1OffsetEff;
255 wordExtremes.maxWidth += line1OffsetEff;
256 //DEBUG_MSG (DEBUG_SIZE_LEVEL + 1,
257 // " (next plus %d)\n", line1OffsetEff);
258 }
259
260
261 if (extremes->minWidth < wordExtremes.minWidth)
262 extremes->minWidth = wordExtremes.minWidth;
263
264 _MSG("parMax = %d, wordMaxWidth=%d, prevWordSpace=%d\n",
265 parMax, wordExtremes.maxWidth, prevWordSpace);
266 if (word->content.type != core::Content::BREAK)
267 parMax += prevWordSpace;
268 parMax += wordExtremes.maxWidth;
269
270 if (prevWord && !canBreakAfter(prevWord)) {
271 parMin += prevWordSpace + wordExtremes.minWidth;
272 } else {
273 parMin = wordExtremes.minWidth;
274 }
275
276 if (extremes->minWidth < parMin) {
277 extremes->minWidth = parMin;
278 }
279
280 prevWordSpace = word->origSpace;
281 prevWord = word;
282
283 //DEBUG_MSG (DEBUG_SIZE_LEVEL + 1,
284 // " word %s: maxWidth = %d\n",
285 // word->content.text,
286 // word_extremes.maxWidth);
287 }
288
289 if ((words->getRef(line->lastWord)->content.type
290 == core::Content::BREAK ) ||
291 lineIndex == lines->size () - 1 ) {
292
293 //DEBUG_MSG (DEBUG_SIZE_LEVEL + 2,
294 // " parMax = %d, after word %d (%s)\n",
295 // parMax, line->last_word - 1,
296 // word->content.text);
297
298 if (extremes->maxWidth < parMax)
299 extremes->maxWidth = parMax;
300
301 prevWordSpace = 0;
302 parMax = 0;
303 }
304
305 //DBG_MSG_END (widget);
306 }
307
308 //DEBUG_MSG (DEBUG_SIZE_LEVEL + 3, " Result: %d, %d\n",
309 // extremes->minWidth, extremes->maxWidth);
310 }
311
312 //DBG_MSGF (widget, "extremes", 0, "width difference: %d + %d",
313 // innerPadding, getStyle()->boxDiffWidth ());
304 } else {
305 Paragraph *lastPar = paragraphs->getLastRef ();
306 extremes->minWidth = lastPar->maxParMin;
307 extremes->maxWidth = lastPar->maxParMax;
308 }
314309
315310 int diff = innerPadding + getStyle()->boxDiffWidth ();
316311 extremes->minWidth += diff;
317312 extremes->maxWidth += diff;
318313
319 //DBG_MSG_END (widget);
314 PRINTF ("[%p] GET_EXTREMES => %d / %d\n",
315 this, extremes->minWidth, extremes->maxWidth);
320316 }
321317
322318
323319 void Textblock::sizeAllocateImpl (core::Allocation *allocation)
324320 {
321 PRINTF ("[%p] SIZE_ALLOCATE: %d, %d, %d x %d + %d\n",
322 this, allocation->x, allocation->y, allocation->width,
323 allocation->ascent, allocation->descent);
324
325 showMissingLines ();
326
325327 int lineIndex, wordIndex;
326328 Line *line;
327329 Word *word;
447449
448450 void Textblock::markSizeChange (int ref)
449451 {
450 markChange (ref);
452 PRINTF ("[%p] MARK_SIZE_CHANGE (%d): %d => ...\n", this, ref, wrapRefLines);
453
454 /* By the way: ref == -1 may have two different causes: (i) flush()
455 calls "queueResize (-1, true)", when no rewrapping is necessary;
456 and (ii) a word may have parentRef == -1 , when it is not yet
457 added to a line. In the latter case, nothing has to be done
458 now, but addLine(...) will do everything necessary. */
459 if (ref != -1) {
460 if (wrapRefLines == -1)
461 wrapRefLines = ref;
462 else
463 wrapRefLines = misc::min (wrapRefLines, ref);
464 }
465
466 PRINTF (" ... => %d\n", wrapRefLine);
467
468 // It seems that sometimes the lines structure is changed, so that
469 // wrapRefLines may refers to a line which does not exist
470 // anymore. Should be examined again. Until then, setting
471 // wrapRefLines to the same value is a workaround.
472 markExtremesChange (ref);
451473 }
452474
453475 void Textblock::markExtremesChange (int ref)
454476 {
455 markChange (ref);
456 }
457
458 /*
459 * Implementation for both mark_size_change and mark_extremes_change.
460 */
461 void Textblock::markChange (int ref)
462 {
477 PRINTF ("[%p] MARK_EXTREMES_CHANGE (%d): %d => ...\n",
478 this, ref, wrapRefParagraphs);
479
480 /* By the way: ref == -1 may have two different causes: (i) flush()
481 calls "queueResize (-1, true)", when no rewrapping is necessary;
482 and (ii) a word may have parentRef == -1 , when it is not yet
483 added to a line. In the latter case, nothing has to be done
484 now, but addLine(...) will do everything necessary. */
463485 if (ref != -1) {
464 //DBG_MSGF (page, "wrap", 0, "markChange (ref = %d)", ref);
465
466 if (wrapRef == -1)
467 wrapRef = ref;
486 if (wrapRefParagraphs == -1)
487 wrapRefParagraphs = ref;
468488 else
469 wrapRef = misc::min (wrapRef, ref);
470
471 //DBG_OBJ_SET_NUM (this, "wrap_ref", wrapRef);
472 }
489 wrapRefParagraphs = misc::min (wrapRefParagraphs, ref);
490 }
491
492 PRINTF (" ... => %d\n", wrapRefParagraphs);
473493 }
474494
475495 void Textblock::setWidth (int width)
666686 }
667687 if (word->content.type == core::Content::TEXT) {
668688 int glyphX = wordStartX;
689 int isStartWord = word->flags & Word::WORD_START;
690 int isEndWord = word->flags & Word::WORD_END;
669691
670692 while (1) {
671693 int nextCharPos =
672694 layout->nextGlyph (word->content.text, charPos);
695 // TODO The width of a text is not the sum
696 // of the widths of the glyphs, because of
697 // ligatures, kerning etc., so textWidth
698 // should be applied to the text from 0 to
699 // nextCharPos. (Or not? See comment below.)
700
673701 int glyphWidth =
674702 textWidth (word->content.text, charPos,
675 nextCharPos - charPos, word->style);
703 nextCharPos - charPos, word->style,
704 isStartWord && charPos == 0,
705 isEndWord &&
706 word->content.text[nextCharPos] == 0);
676707 if (event->xWidget > glyphX + glyphWidth) {
677708 glyphX += glyphWidth;
678709 charPos = nextCharPos;
687718 charPos);
688719 if (textWidth (word->content.text, charPos,
689720 nextCharPos - charPos,
690 word->style))
721 word->style,
722 isStartWord && charPos == 0,
723 isEndWord &&
724 word->content.text[nextCharPos]
725 == 0))
691726 break;
692727 charPos = nextCharPos;
693728 }
730765 return new TextblockIterator (this, mask, atEnd);
731766 }
732767
733 /*
734 * ...
735 *
736 * availWidth is passed from wordWrap, to avoid calculating it twice.
737 */
738 void Textblock::justifyLine (Line *line, int availWidth)
739 {
740 /* To avoid rounding errors, the calculation is based on accumulated
741 * values (*_cum). */
742 int i;
743 int origSpaceSum, origSpaceCum;
744 int effSpaceDiffCum, lastEffSpaceDiffCum;
745 int diff;
746
747 diff = availWidth - lastLineWidth;
748 if (diff > 0) {
749 origSpaceSum = 0;
750 for (i = line->firstWord; i < line->lastWord; i++)
751 origSpaceSum += words->getRef(i)->origSpace;
752
753 origSpaceCum = 0;
754 lastEffSpaceDiffCum = 0;
755 for (i = line->firstWord; i < line->lastWord; i++) {
756 origSpaceCum += words->getRef(i)->origSpace;
757
758 if (origSpaceCum == 0)
759 effSpaceDiffCum = lastEffSpaceDiffCum;
760 else
761 effSpaceDiffCum = diff * origSpaceCum / origSpaceSum;
762
763 words->getRef(i)->effSpace = words->getRef(i)->origSpace +
764 (effSpaceDiffCum - lastEffSpaceDiffCum);
765 //DBG_OBJ_ARRSET_NUM (this, "words.%d.effSpace", i,
766 // words->getRef(i)->effSpace);
767
768 lastEffSpaceDiffCum = effSpaceDiffCum;
769 }
770 }
771 }
772
773
774 Textblock::Line *Textblock::addLine (int wordIndex, bool newPar)
775 {
776 Line *lastLine;
777
778 //DBG_MSG (page, "wrap", 0, "addLine");
779 //DBG_MSG_START (page);
780
781 lines->increase ();
782 //DBG_OBJ_SET_NUM(this, "num_lines", lines->size ());
783
784 //DEBUG_MSG (DEBUG_REWRAP_LEVEL, "--- new line %d in %p, with word %d of %d"
785 // "\n", lines->size () - 1, page, word_ind, words->size());
786
787 lastLine = lines->getRef (lines->size () - 1);
788
789 if (lines->size () == 1) {
790 lastLine->top = 0;
791 lastLine->maxLineWidth = line1OffsetEff;
792 lastLine->maxParMin = 0;
793 lastLine->maxParMax = 0;
794 } else {
795 Line *prevLine = lines->getRef (lines->size () - 2);
796
797 lastLine->top = prevLine->top + prevLine->boxAscent +
798 prevLine->boxDescent + prevLine->breakSpace;
799 lastLine->maxLineWidth = prevLine->maxLineWidth;
800 lastLine->maxParMin = prevLine->maxParMin;
801 lastLine->maxParMax = prevLine->maxParMax;
802 }
803
804 //DBG_OBJ_ARRSET_NUM (this, "lines.%d.top", lines->size () - 1,
805 // lastLine->top);
806 //DBG_OBJ_ARRSET_NUM (this, "lines.%d.maxLineWidth", lines->size () - 1,
807 // lastLine->maxLineWidth);
808 //DBG_OBJ_ARRSET_NUM (this, "lines.%d.maxParMin", lines->size () - 1,
809 // lastLine->maxParMin);
810 //DBG_OBJ_ARRSET_NUM (this, "lines.%d.maxParMax", lines->size () - 1,
811 // lastLine->maxParMax);
812 //DBG_OBJ_ARRSET_NUM (this, "lines.%d.parMin", lines->size () - 1,
813 // lastLine->parMin);
814 //DBG_OBJ_ARRSET_NUM (this, "lines.%d.parMax", lines->size () - 1,
815 // lastLine->parMax);
816
817 lastLine->firstWord = wordIndex;
818 lastLine->boxAscent = lastLine->contentAscent = 0;
819 lastLine->boxDescent = lastLine->contentDescent = 0;
820 lastLine->marginDescent = 0;
821 lastLine->breakSpace = 0;
822 lastLine->leftOffset = 0;
823
824 //DBG_OBJ_ARRSET_NUM (this, "lines.%d.ascent", lines->size () - 1,
825 // lastLine->boxAscent);
826 //DBG_OBJ_ARRSET_NUM (this, "lines.%d.descent", lines->size () - 1,
827 // lastLine->boxDescent);
828
829 /* update values in line */
830 lastLine->maxLineWidth = misc::max (lastLine->maxLineWidth, lastLineWidth);
831
832 if (lines->size () > 1)
833 lastLineWidth = 0;
834 else
835 lastLineWidth = line1OffsetEff;
836
837 if (newPar) {
838 lastLine->maxParMax = misc::max (lastLine->maxParMax, lastLineParMax);
839 //DBG_OBJ_ARRSET_NUM (this, "lines.%d.maxParMax", lines->size () - 1,
840 // lastLine->maxParMax);
841
842 if (lines->size () > 1) {
843 lastLineParMax = 0;
844 } else {
845 lastLineParMax = line1OffsetEff;
846 }
847
848 //DBG_OBJ_SET_NUM(this, "lastLineParMax", lastLineParMax);
849 }
850
851 lastLine->parMax = lastLineParMax;
852
853 //DBG_OBJ_ARRSET_NUM (this, "lines.%d.parMin", lines->size () - 1,
854 // lastLine->parMin);
855 //DBG_OBJ_ARRSET_NUM (this, "lines.%d.parMax", lines->size () - 1,
856 // lastLine->parMax);
857
858 //DBG_MSG_END (page);
859 return lastLine;
860 }
861
862 /*
863 * This method is called in two cases: (i) when a word is added
864 * (ii) when a page has to be (partially) rewrapped. It does word wrap,
865 * and adds new lines if necessary.
866 */
867 void Textblock::wordWrap(int wordIndex)
868 {
869 Line *lastLine;
870 Word *word;
871 int availWidth, lastSpace, leftOffset, len;
872 bool newLine = false, newPar = false, canBreakBefore = true;
873 core::Extremes wordExtremes;
874
875 //DBG_MSGF (page, "wrap", 0, "wordWrap (%d): %s, width = %d",
876 // wordIndex, words->getRef(wordIndex)->content.text),
877 // words->getRef(wordIndex)->size.width);
878 //DBG_MSG_START (page);
879
880 availWidth = this->availWidth - getStyle()->boxDiffWidth() - innerPadding;
881 if (limitTextWidth &&
882 layout->getUsesViewport () &&
883 availWidth > layout->getWidthViewport () - 10)
884 availWidth = layout->getWidthViewport () - 10;
885
886 word = words->getRef (wordIndex);
887 word->effSpace = word->origSpace;
888
889 /* Test whether line1Offset can be used. */
890 if (wordIndex == 0) {
891 if (ignoreLine1OffsetSometimes &&
892 line1Offset + word->size.width > availWidth) {
893 line1OffsetEff = 0;
894 } else {
895 int indent = 0;
896
897 if (word->content.type == core::Content::WIDGET &&
898 word->content.widget->blockLevel() == true) {
899 /* don't use text-indent when nesting blocks */
900 } else {
901 if (core::style::isPerLength(getStyle()->textIndent)) {
902 indent = misc::roundInt(this->availWidth *
903 core::style::perLengthVal (getStyle()->textIndent));
904 } else {
905 indent = core::style::absLengthVal (getStyle()->textIndent);
906 }
907 }
908 line1OffsetEff = line1Offset + indent;
909 }
910 }
911
912 if (lines->size () == 0) {
913 //DBG_MSG (page, "wrap", 0, "first line");
914 newLine = true;
915 newPar = true;
916 lastLine = NULL;
917 } else {
918 Word *prevWord = words->getRef (wordIndex - 1);
919
920 lastLine = lines->getRef (lines->size () - 1);
921
922 if (prevWord->content.type == core::Content::BREAK) {
923 //DBG_MSG (page, "wrap", 0, "after a break");
924 /* previous word is a break */
925 newLine = true;
926 newPar = true;
927 } else if (!canBreakAfter (prevWord)) {
928 canBreakBefore = false;
929 // no break within nowrap
930 newLine = false;
931 newPar = false;
932 if (lastLineWidth + prevWord->origSpace + word->size.width >
933 availWidth)
934 markChange (lines->size () - 1);
935 } else if (lastLine->firstWord != wordIndex) {
936 // check if we need to break because nowrap sequence is following
937 newLine = false;
938 int lineWidthNeeded = lastLineWidth + prevWord->origSpace;
939 for (int i = wordIndex; i < words->size (); i++) {
940 Word *w = words->getRef (i);
941
942 if (w->content.type == core::Content::BREAK ||
943 (word->content.type == core::Content::WIDGET &&
944 word->content.widget->blockLevel()))
945 break;
946
947 lineWidthNeeded += w->size.width;
948
949 if (lineWidthNeeded > availWidth) {
950 newLine = true;
951 break;
952 } else if (canBreakAfter (w)) {
953 break;
954 }
955
956 lineWidthNeeded += w->origSpace;
957 }
958 }
959 }
960
961 if (newLine) {
962 if (word->style->textAlign == core::style::TEXT_ALIGN_JUSTIFY &&
963 lastLine != NULL && !newPar) {
964 justifyLine (lastLine, availWidth);
965 }
966 lastLine = addLine (wordIndex, newPar);
967 }
968
969 lastLine->lastWord = wordIndex;
970 lastLine->boxAscent = misc::max (lastLine->boxAscent, word->size.ascent);
971 lastLine->boxDescent = misc::max (lastLine->boxDescent, word->size.descent);
972
973 len = word->style->font->ascent;
974 if (word->style->valign == core::style::VALIGN_SUPER)
975 len += len / 2;
976 lastLine->contentAscent = misc::max (lastLine->contentAscent, len);
977
978 len = word->style->font->descent;
979 if (word->style->valign == core::style::VALIGN_SUB)
980 len += word->style->font->ascent / 3;
981 lastLine->contentDescent = misc::max (lastLine->contentDescent, len);
982
983 //DBG_OBJ_ARRSET_NUM (this, "lines.%d.ascent", lines->size () - 1,
984 // lastLine->boxAscent);
985 //DBG_OBJ_ARRSET_NUM (this, "lines.%d.descent", lines->size () - 1,
986 // lastLine->boxDescent);
987
988 if (word->content.type == core::Content::WIDGET) {
989 int collapseMarginTop = 0;
990
991 lastLine->marginDescent =
992 misc::max (lastLine->marginDescent,
993 word->size.descent +
994 word->content.widget->getStyle()->margin.bottom);
995
996 if (lines->size () == 1 &&
997 word->content.widget->blockLevel () &&
998 getStyle ()->borderWidth.top == 0 &&
999 getStyle ()->padding.top == 0) {
1000 // collapse top margins of parent element and its first child
1001 // see: http://www.w3.org/TR/CSS21/box.html#collapsing-margins
1002 collapseMarginTop = getStyle ()->margin.top;
1003 }
1004
1005 lastLine->boxAscent =
1006 misc::max (lastLine->boxAscent,
1007 word->size.ascent,
1008 word->size.ascent
1009 + word->content.widget->getStyle()->margin.top
1010 - collapseMarginTop);
1011
1012 } else {
1013 lastLine->marginDescent =
1014 misc::max (lastLine->marginDescent, lastLine->boxDescent);
1015
1016 if (word->content.type == core::Content::BREAK)
1017 lastLine->breakSpace =
1018 misc::max (word->content.breakSpace,
1019 lastLine->marginDescent - lastLine->boxDescent,
1020 lastLine->breakSpace);
1021 }
1022
1023 lastSpace = (wordIndex > 0) ? words->getRef(wordIndex - 1)->origSpace : 0;
1024
1025 if (!newLine)
1026 lastLineWidth += lastSpace;
1027 if (!newPar) {
1028 lastLineParMax += lastSpace;
1029 }
1030
1031 lastLineWidth += word->size.width;
1032
1033 getWordExtremes (word, &wordExtremes);
1034 lastLineParMax += wordExtremes.maxWidth;
1035
1036 if (!canBreakBefore) {
1037 lastLineParMin += wordExtremes.minWidth + lastSpace;
1038 /* This may also increase the accumulated minimum word width. */
1039 lastLine->maxParMin = misc::max (lastLine->maxParMin, lastLineParMin);
1040 } else {
1041 lastLineParMin = wordExtremes.minWidth;
1042 lastLine->maxParMin =
1043 misc::max (lastLine->maxParMin, wordExtremes.minWidth);
1044 }
1045
1046 //DBG_OBJ_SET_NUM(this, "lastLine_par_min", lastLineParMin);
1047 //DBG_OBJ_SET_NUM(this, "lastLine_par_max", lastLineParMax);
1048 //DBG_OBJ_ARRSET_NUM (this, "lines.%d.par_min", lines->size () - 1,
1049 // lastLine->par_min);
1050 //DBG_OBJ_ARRSET_NUM (this, "lines.%d.par_max", lines->size () - 1,
1051 // lastLine->par_max);
1052 //DBG_OBJ_ARRSET_NUM (this, "lines.%d.max_word_min", lines->size () - 1,
1053 // lastLine->max_word_min);
1054
1055 /* Align the line.
1056 * \todo Use block's style instead once paragraphs become proper blocks.
1057 */
1058 if (word->content.type != core::Content::BREAK) {
1059 switch (word->style->textAlign) {
1060 case core::style::TEXT_ALIGN_LEFT:
1061 case core::style::TEXT_ALIGN_JUSTIFY: /* see some lines above */
1062 case core::style::TEXT_ALIGN_STRING: /* handled elsewhere (in the
1063 * future) */
1064 leftOffset = 0;
1065 break;
1066 case core::style::TEXT_ALIGN_RIGHT:
1067 leftOffset = availWidth - lastLineWidth;
1068 break;
1069 case core::style::TEXT_ALIGN_CENTER:
1070 leftOffset = (availWidth - lastLineWidth) / 2;
1071 break;
1072 default:
1073 /* compiler happiness */
1074 leftOffset = 0;
1075 }
1076
1077 /* For large lines (images etc), which do not fit into the viewport: */
1078 if (leftOffset < 0)
1079 leftOffset = 0;
1080
1081 lastLine->leftOffset = leftOffset;
1082 }
1083 mustQueueResize = true;
1084
1085 //DBG_MSG_END (page);
1086 }
1087
1088768
1089769 /**
1090770 * Calculate the size of a widget within the page.
1143823 size->descent -= wstyle->margin.bottom;
1144824 }
1145825
1146 /**
1147 * Rewrap the page from the line from which this is necessary.
1148 * There are basically two times we'll want to do this:
1149 * either when the viewport is resized, or when the size changes on one
1150 * of the child widgets.
1151 */
1152 void Textblock::rewrap ()
1153 {
1154 int i, wordIndex;
1155 Word *word;
1156 Line *lastLine;
1157
1158 if (wrapRef == -1)
1159 /* page does not have to be rewrapped */
1160 return;
1161
1162 //DBG_MSGF (page, "wrap", 0,
1163 // "rewrap: wrapRef = %d, in page with %d word(s)",
1164 // wrapRef, words->size());
1165 //DBG_MSG_START (page);
1166
1167 /* All lines up from wrapRef will be rebuild from the word list,
1168 * the line list up from this position is rebuild. */
1169 lines->setSize (wrapRef);
1170 lastLineWidth = 0;
1171 lastLineParMin = 0;
1172 //DBG_OBJ_SET_NUM(this, "num_lines", lines->size ());
1173 //DBG_OBJ_SET_NUM(this, "lastLine_width", lastLineWidth);
1174
1175 /* In the word list, start at the last word plus one in the line before. */
1176 if (wrapRef > 0) {
1177 /* Note: In this case, wordWrap() will immediately find the need
1178 * to rewrap the line, since we start with the last one (plus one).
1179 * This is also the reason, why lastLineWidth is set
1180 * to the length of the line. */
1181 lastLine = lines->getRef (lines->size () - 1);
1182
1183 lastLineParMax = lastLine->parMax;
1184
1185 wordIndex = lastLine->lastWord + 1;
1186 for (i = lastLine->firstWord; i < lastLine->lastWord; i++)
1187 lastLineWidth += (words->getRef(i)->size.width +
1188 words->getRef(i)->origSpace);
1189 lastLineWidth += words->getRef(lastLine->lastWord)->size.width;
1190 } else {
1191 lastLineParMax = 0;
1192
1193 wordIndex = 0;
1194 }
1195
1196 for (; wordIndex < words->size (); wordIndex++) {
1197 word = words->getRef (wordIndex);
1198
1199 if (word->content.type == core::Content::WIDGET)
1200 calcWidgetSize (word->content.widget, &word->size);
1201 wordWrap (wordIndex);
1202
1203 if (word->content.type == core::Content::WIDGET) {
1204 word->content.widget->parentRef = lines->size () - 1;
1205 //DBG_OBJ_SET_NUM (word->content.widget, "parent_ref",
1206 // word->content.widget->parent_ref);
1207 }
1208
1209 //DEBUG_MSG(DEBUG_REWRAP_LEVEL,
1210 // "Assigning parent_ref = %d to rewrapped word %d, "
1211 // "in page with %d word(s)\n",
1212 // lines->size () - 1, wordIndex, words->size());
1213
1214 /* todo_refactoring:
1215 if (word->content.type == DW_CONTENT_ANCHOR)
1216 p_Dw_gtk_viewport_change_anchor
1217 (widget, word->content.anchor,
1218 Dw_page_line_total_y_offset (page,
1219 &page->lines[lines->size () - 1]));
1220 */
1221 }
1222
1223 /* Next time, the page will not have to be rewrapped. */
1224 wrapRef = -1;
1225
1226 //DBG_MSG_END (page);
1227 }
1228
1229826 /*
1230827 * Draw the decorations on a word.
1231828 */
1253850
1254851 /*
1255852 * Draw a string of text
853 *
854 * Arguments: ... "isStart" and "isEnd" are true, when the text
855 * start/end represents the start/end of a "real" text word (before
856 * hyphenation). This has an effect on text transformation. ("isEnd"
857 * is not used yet, but here for symmetry.)
1256858 */
1257859 void Textblock::drawText(core::View *view, core::style::Style *style,
1258860 core::style::Color::Shading shading, int x, int y,
1259 const char *text, int start, int len)
861 const char *text, int start, int len, bool isStart,
862 bool isEnd)
1260863 {
1261864 if (len > 0) {
1262865 char *str = NULL;
1272875 str = layout->textToLower(text + start, len);
1273876 break;
1274877 case core::style::TEXT_TRANSFORM_CAPITALIZE:
1275 {
1276 /* \bug No way to know about non-ASCII punctuation. */
1277 bool initial_seen = false;
1278
1279 for (int i = 0; i < start; i++)
1280 if (!ispunct(text[i]))
1281 initial_seen = true;
1282 if (initial_seen)
1283 break;
1284
1285 int after = 0;
1286 text += start;
1287 while (ispunct(text[after]))
1288 after++;
1289 if (text[after])
1290 after = layout->nextGlyph(text, after);
1291 if (after > len)
1292 after = len;
1293
1294 char *initial = layout->textToUpper(text, after);
1295 int newlen = strlen(initial) + len-after;
1296 str = (char *)malloc(newlen + 1);
1297 strcpy(str, initial);
1298 strncpy(str + strlen(str), text+after, len-after);
1299 str[newlen] = '\0';
1300 free(initial);
878 // If "isStart" is false, the first letter of "text" is
879 // not the first letter of the "real" text word, so no
880 // transformation is necessary.
881 if (isStart) {
882 /* \bug No way to know about non-ASCII punctuation. */
883 bool initial_seen = false;
884
885 for (int i = 0; i < start; i++)
886 if (!ispunct(text[i]))
887 initial_seen = true;
888 if (initial_seen)
889 break;
890
891 int after = 0;
892 text += start;
893 while (ispunct(text[after]))
894 after++;
895 if (text[after])
896 after = layout->nextGlyph(text, after);
897 if (after > len)
898 after = len;
899
900 char *initial = layout->textToUpper(text, after);
901 int newlen = strlen(initial) + len-after;
902 str = (char *)malloc(newlen + 1);
903 strcpy(str, initial);
904 strncpy(str + strlen(str), text+after, len-after);
905 str[newlen] = '\0';
906 free(initial);
907 }
1301908 break;
1302 }
1303 }
909 }
910
1304911 view->drawText(style->font, style->color, shading, x, y,
1305912 str ? str : text + start, str ? strlen(str) : len);
1306913 if (str)
1308915 }
1309916 }
1310917
1311 /*
918 /**
1312919 * Draw a word of text.
1313 */
1314 void Textblock::drawWord(int wordIndex, core::View *view,core::Rectangle *area,
1315 int xWidget, int yWidgetBase)
1316 {
1317 Word *word = words->getRef(wordIndex);
920 *
921 * Since hyphenated words consist of multiple instance of
922 * dw::Textblock::Word, which should be drawn as a whole (to preserve
923 * kerning etc.; see \ref dw-line-breaking), two indices are
924 * passed. See also drawLine(), where drawWord() is called.
925 */
926 void Textblock::drawWord (Line *line, int wordIndex1, int wordIndex2,
927 core::View *view, core::Rectangle *area,
928 int xWidget, int yWidgetBase)
929 {
930 core::style::Style *style = words->getRef(wordIndex1)->style;
931 bool drawHyphen = wordIndex2 == line->lastWord
932 && (words->getRef(wordIndex2)->flags & Word::DIV_CHAR_AT_EOL);
933
934 if (style->hasBackground ()) {
935 int w = 0;
936 for (int i = wordIndex1; i <= wordIndex2; i++)
937 w += words->getRef(i)->size.width;
938 w += words->getRef(wordIndex2)->hyphenWidth;
939 drawBox (view, style, area, xWidget, yWidgetBase - line->boxAscent,
940 w, line->boxAscent + line->boxDescent, false);
941 }
942
943 if (wordIndex1 == wordIndex2 && !drawHyphen) {
944 // Simple case, where copying in one buffer is not needed.
945 Word *word = words->getRef (wordIndex1);
946 drawWord0 (wordIndex1, wordIndex2, word->content.text, word->size.width,
947 false, style, view, area, xWidget, yWidgetBase);
948 } else {
949 // Concatenate all words in a new buffer.
950 int l = 0, totalWidth = 0;
951 for (int i = wordIndex1; i <= wordIndex2; i++) {
952 Word *w = words->getRef (i);
953 l += strlen (w->content.text);
954 totalWidth += w->size.width;
955 }
956
957 char text[l + (drawHyphen ? strlen (hyphenDrawChar) : 0) + 1];
958 int p = 0;
959 for (int i = wordIndex1; i <= wordIndex2; i++) {
960 const char * t = words->getRef(i)->content.text;
961 strcpy (text + p, t);
962 p += strlen (t);
963 }
964
965 if(drawHyphen) {
966 for (int i = 0; hyphenDrawChar[i]; i++)
967 text[p++] = hyphenDrawChar[i];
968 text[p++] = 0;
969 }
970
971 drawWord0 (wordIndex1, wordIndex2, text, totalWidth, drawHyphen,
972 style, view, area, xWidget, yWidgetBase);
973 }
974 }
975
976 /**
977 * TODO Comment
978 */
979 void Textblock::drawWord0 (int wordIndex1, int wordIndex2,
980 const char *text, int totalWidth, bool drawHyphen,
981 core::style::Style *style, core::View *view,
982 core::Rectangle *area, int xWidget, int yWidgetBase)
983 {
1318984 int xWorld = allocation.x + xWidget;
1319 core::style::Style *style = word->style;
1320985 int yWorldBase;
1321986
1322987 /* Adjust the text baseline if the word is <SUP>-ed or <SUB>-ed. */
1327992 }
1328993 yWorldBase = yWidgetBase + allocation.y;
1329994
995 bool isStartTotal = words->getRef(wordIndex1)->flags & Word::WORD_START;
996 bool isEndTotal = words->getRef(wordIndex2)->flags & Word::WORD_START;
1330997 drawText (view, style, core::style::Color::SHADING_NORMAL, xWorld,
1331 yWorldBase, word->content.text, 0, strlen (word->content.text));
998 yWorldBase, text, 0, strlen (text), isStartTotal, isEndTotal);
1332999
13331000 if (style->textDecoration)
13341001 decorateText(view, style, core::style::Color::SHADING_NORMAL, xWorld,
1335 yWorldBase, word->size.width);
1002 yWorldBase, totalWidth);
13361003
13371004 for (int layer = 0; layer < core::HIGHLIGHT_NUM_LAYERS; layer++) {
1338 if (hlStart[layer].index <= wordIndex &&
1339 hlEnd[layer].index >= wordIndex) {
1340 const int wordLen = strlen (word->content.text);
1005 if (wordIndex1 <= hlEnd[layer].index &&
1006 wordIndex2 >= hlStart[layer].index) {
1007 const int wordLen = strlen (text);
13411008 int xStart, width;
1342 int firstCharIdx = 0;
1343 int lastCharIdx = wordLen;
1344
1345 if (wordIndex == hlStart[layer].index)
1346 firstCharIdx = misc::min (hlStart[layer].nChar, wordLen);
1347
1348 if (wordIndex == hlEnd[layer].index)
1349 lastCharIdx = misc::min (hlEnd[layer].nChar, wordLen);
1009 int firstCharIdx;
1010 int lastCharIdx;
1011
1012 if (hlStart[layer].index < wordIndex1)
1013 firstCharIdx = 0;
1014 else {
1015 firstCharIdx =
1016 misc::min (hlStart[layer].nChar,
1017 (int)strlen (words->getRef(hlStart[layer].index)
1018 ->content.text));
1019 for (int i = wordIndex1; i < hlStart[layer].index; i++)
1020 // It can be assumed that all words from wordIndex1 to
1021 // wordIndex2 have content type TEXT.
1022 firstCharIdx += strlen (words->getRef(i)->content.text);
1023 }
1024
1025 if (hlEnd[layer].index > wordIndex2)
1026 lastCharIdx = wordLen;
1027 else {
1028 lastCharIdx =
1029 misc::min (hlEnd[layer].nChar,
1030 (int)strlen (words->getRef(hlEnd[layer].index)
1031 ->content.text));
1032 for (int i = wordIndex1; i < hlEnd[layer].index; i++)
1033 // It can be assumed that all words from wordIndex1 to
1034 // wordIndex2 have content type TEXT.
1035 lastCharIdx += strlen (words->getRef(i)->content.text);
1036 }
13501037
13511038 xStart = xWorld;
13521039 if (firstCharIdx)
1353 xStart += textWidth (word->content.text, 0, firstCharIdx, style);
1354 if (firstCharIdx == 0 && lastCharIdx == wordLen)
1355 width = word->size.width;
1040 xStart += textWidth (text, 0, firstCharIdx, style,
1041 isStartTotal,
1042 isEndTotal && text[firstCharIdx] == 0);
1043 // With a hyphen, the width is a bit longer than totalWidth,
1044 // and so, the optimization to use totalWidth is not correct.
1045 if (!drawHyphen && firstCharIdx == 0 && lastCharIdx == wordLen)
1046 width = totalWidth;
13561047 else
1357 width = textWidth (word->content.text, firstCharIdx,
1358 lastCharIdx - firstCharIdx, style);
1048 width = textWidth (text, firstCharIdx,
1049 lastCharIdx - firstCharIdx, style,
1050 isStartTotal && firstCharIdx == 0,
1051 isEndTotal && text[lastCharIdx] == 0);
13591052 if (width > 0) {
13601053 /* Highlight text */
13611054 core::style::Color *wordBgColor;
13711064
13721065 /* Highlight the text. */
13731066 drawText (view, style, core::style::Color::SHADING_INVERSE, xStart,
1374 yWorldBase, word->content.text, firstCharIdx,
1375 lastCharIdx - firstCharIdx);
1067 yWorldBase, text, firstCharIdx,
1068 lastCharIdx - firstCharIdx,
1069 isStartTotal && firstCharIdx == 0,
1070 isEndTotal && lastCharIdx == wordLen);
13761071
13771072 if (style->textDecoration)
13781073 decorateText(view, style, core::style::Color::SHADING_INVERSE,
14401135 int xWidget = lineXOffsetWidget(line);
14411136 int yWidgetBase = lineYOffsetWidget (line) + line->boxAscent;
14421137
1443 /* Here's an idea on how to optimize this routine to minimize the number
1444 * of drawing calls:
1445 *
1446 * Copy the text from the words into a buffer, adding a new word
1447 * only if: the attributes match, and the spacing is either zero or
1448 * equal to the width of ' '. In the latter case, copy a " " into
1449 * the buffer. Then draw the buffer. */
1450
14511138 for (int wordIndex = line->firstWord;
14521139 wordIndex <= line->lastWord && xWidget < area->x + area->width;
14531140 wordIndex++) {
14541141 Word *word = words->getRef(wordIndex);
1455
1456 if (xWidget + word->size.width + word->effSpace >= area->x) {
1142 int wordSize = word->size.width;
1143
1144 if (xWidget + wordSize + word->hyphenWidth + word->effSpace >= area->x) {
14571145 if (word->content.type == core::Content::TEXT ||
14581146 word->content.type == core::Content::WIDGET) {
14591147
14651153 if (child->intersects (area, &childArea))
14661154 child->draw (view, &childArea);
14671155 } else {
1468 if (word->style->hasBackground ()) {
1469 drawBox (view, word->style, area, xWidget,
1470 yWidgetBase - line->boxAscent, word->size.width,
1471 line->boxAscent + line->boxDescent, false);
1472 }
1473 drawWord(wordIndex, view, area, xWidget, yWidgetBase);
1156 int wordIndex2 = wordIndex;
1157 while (wordIndex2 < line->lastWord &&
1158 (words->getRef(wordIndex2)->flags
1159 & Word::DRAW_AS_ONE_TEXT) &&
1160 word->style == words->getRef(wordIndex2 + 1)->style)
1161 wordIndex2++;
1162
1163 drawWord(line, wordIndex, wordIndex2, view, area,
1164 xWidget, yWidgetBase);
1165 wordSize = 0;
1166 for (int i = wordIndex; i <= wordIndex2; i++)
1167 wordSize += words->getRef(i)->size.width;
1168
1169 wordIndex = wordIndex2;
1170 word = words->getRef(wordIndex);
14741171 }
14751172 }
1173
14761174 if (word->effSpace > 0 && wordIndex < line->lastWord &&
14771175 words->getRef(wordIndex + 1)->content.type !=
14781176 core::Content::BREAK) {
14791177 if (word->spaceStyle->hasBackground ())
14801178 drawBox (view, word->spaceStyle, area,
1481 xWidget + word->size.width,
1179 xWidget + wordSize,
14821180 yWidgetBase - line->boxAscent, word->effSpace,
14831181 line->boxAscent + line->boxDescent, false);
1484 drawSpace(wordIndex, view, area, xWidget + word->size.width,
1182 drawSpace(wordIndex, view, area, xWidget + wordSize,
14851183 yWidgetBase);
14861184 }
14871185
14881186 }
14891187 }
1490 xWidget += word->size.width + word->effSpace;
1188 xWidget += wordSize + word->effSpace;
14911189 }
14921190 }
14931191
15311229 {
15321230 int high = lines->size () - 1, index, low = 0;
15331231
1232 // TODO regard also not-yet-existing lines?
15341233 if (wordIndex < 0 || wordIndex >= words->size ())
15351234 return -1;
15361235
15381237 index = (low + high) / 2;
15391238 if (wordIndex >= lines->getRef(index)->firstWord) {
15401239 if (wordIndex <= lines->getRef(index)->lastWord)
1240 return index;
1241 else
1242 low = index + 1;
1243 } else
1244 high = index - 1;
1245 }
1246 }
1247
1248 /**
1249 * \brief Find the paragraph of word \em wordIndex.
1250 */
1251 int Textblock::findParagraphOfWord (int wordIndex)
1252 {
1253 int high = paragraphs->size () - 1, index, low = 0;
1254
1255 if (wordIndex < 0 || wordIndex >= words->size () ||
1256 // It may be that the paragraphs list is incomplete. But look
1257 // also at fillParagraphs, where this method is called.
1258 (paragraphs->size () > 0 &&
1259 wordIndex > paragraphs->getLastRef()->lastWord))
1260 return -1;
1261
1262 while (true) {
1263 index = (low + high) / 2;
1264 if (wordIndex >= paragraphs->getRef(index)->firstWord) {
1265 if (wordIndex <= paragraphs->getRef(index)->lastWord)
15411266 return index;
15421267 else
15431268 low = index + 1;
15941319
15951320 void Textblock::draw (core::View *view, core::Rectangle *area)
15961321 {
1322 PRINTF ("DRAW: %d, %d, %d x %d\n",
1323 area->x, area->y, area->width, area->height);
1324
15971325 int lineIndex;
15981326 Line *line;
15991327
16141342 * Add a new word (text, widget etc.) to a page.
16151343 */
16161344 Textblock::Word *Textblock::addWord (int width, int ascent, int descent,
1617 core::style::Style *style)
1618 {
1619 Word *word;
1620
1345 short flags, core::style::Style *style)
1346 {
16211347 words->increase ();
1622
1623 word = words->getRef (words->size() - 1);
1348 Word *word = words->getLastRef ();
1349 fillWord (word, width, ascent, descent, flags, style);
1350 return word;
1351 }
1352
1353 void Textblock::fillWord (Word *word, int width, int ascent, int descent,
1354 short flags, core::style::Style *style)
1355 {
16241356 word->size.width = width;
16251357 word->size.ascent = ascent;
16261358 word->size.descent = descent;
1627 word->origSpace = 0;
1628 word->effSpace = 0;
1359 word->origSpace = word->effSpace = 0;
1360 word->hyphenWidth = 0;
1361 word->badnessAndPenalty.setPenalty (PENALTY_PROHIBIT_BREAK);
16291362 word->content.space = false;
1630 word->content.breakType = core::Content::BREAK_NO;
1631
1632 //DBG_OBJ_ARRSET_NUM (this, "words.%d.size.width", words->size() - 1,
1633 // word->size.width);
1634 //DBG_OBJ_ARRSET_NUM (this, "words.%d.size.descent", words->size() - 1,
1635 // word->size.descent);
1636 //DBG_OBJ_ARRSET_NUM (this, "words.%d.size.ascent", words->size() - 1,
1637 // word->size.ascent);
1638 //DBG_OBJ_ARRSET_NUM (this, "words.%d.orig_space", words->size() - 1,
1639 // word->orig_space);
1640 //DBG_OBJ_ARRSET_NUM (this, "words.%d.effSpace", words->size() - 1,
1641 // word->eff_space);
1642 //DBG_OBJ_ARRSET_NUM (this, "words.%d.content.space", words->size() - 1,
1643 // word->content.space);
1363 word->flags = flags;
16441364
16451365 word->style = style;
16461366 word->spaceStyle = style;
16471367 style->ref ();
16481368 style->ref ();
1649
1650 return word;
16511369 }
16521370
16531371 /*
16541372 * Get the width of a string of text.
1373 *
1374 * For "isStart" and "isEnd" see drawText.
16551375 */
16561376 int Textblock::textWidth(const char *text, int start, int len,
1657 core::style::Style *style)
1377 core::style::Style *style, bool isStart, bool isEnd)
16581378 {
16591379 int ret = 0;
16601380
16751395 ret = layout->textWidth(style->font, str, strlen(str));
16761396 break;
16771397 case core::style::TEXT_TRANSFORM_CAPITALIZE:
1678 {
1679 /* \bug No way to know about non-ASCII punctuation. */
1680 bool initial_seen = false;
1681
1682 for (int i = 0; i < start; i++)
1683 if (!ispunct(text[i]))
1684 initial_seen = true;
1685 if (initial_seen) {
1398 if (isStart) {
1399 /* \bug No way to know about non-ASCII punctuation. */
1400 bool initial_seen = false;
1401
1402 for (int i = 0; i < start; i++)
1403 if (!ispunct(text[i]))
1404 initial_seen = true;
1405 if (initial_seen) {
1406 ret = layout->textWidth(style->font, text+start, len);
1407 } else {
1408 int after = 0;
1409
1410 text += start;
1411 while (ispunct(text[after]))
1412 after++;
1413 if (text[after])
1414 after = layout->nextGlyph(text, after);
1415 if (after > len)
1416 after = len;
1417 str = layout->textToUpper(text, after);
1418 ret = layout->textWidth(style->font, str, strlen(str)) +
1419 layout->textWidth(style->font, text+after, len-after);
1420 }
1421 } else
16861422 ret = layout->textWidth(style->font, text+start, len);
1687 } else {
1688 int after = 0;
1689
1690 text += start;
1691 while (ispunct(text[after]))
1692 after++;
1693 if (text[after])
1694 after = layout->nextGlyph(text, after);
1695 if (after > len)
1696 after = len;
1697 str = layout->textToUpper(text, after);
1698 ret = layout->textWidth(style->font, str, strlen(str)) +
1699 layout->textWidth(style->font, text+after, len-after);
1700 }
17011423 break;
1702 }
1703 }
1424 }
1425
17041426 if (str)
17051427 free(str);
17061428 }
1429
17071430 return ret;
17081431 }
17091432
17101433 /**
17111434 * Calculate the size of a text word.
1435 *
1436 * For "isStart" and "isEnd" see textWidth and drawText.
17121437 */
17131438 void Textblock::calcTextSize (const char *text, size_t len,
17141439 core::style::Style *style,
1715 core::Requisition *size)
1716 {
1717 size->width = textWidth (text, 0, len, style);
1440 core::Requisition *size, bool isStart, bool isEnd)
1441 {
1442 size->width = textWidth (text, 0, len, style, isStart, isEnd);
17181443 size->ascent = style->font->ascent;
17191444 size->descent = style->font->descent;
17201445
17581483 size->ascent += (style->font->ascent / 2);
17591484 }
17601485
1761
1762 /**
1763 * Add a word to the page structure.
1486 /**
1487 * Add a word to the page structure. If it contains dividing
1488 * characters (hard or soft hyphens, em-dashes, etc.), it is divided.
17641489 */
17651490 void Textblock::addText (const char *text, size_t len,
17661491 core::style::Style *style)
17671492 {
1768 Word *word;
1769 core::Requisition size;
1770
1771 calcTextSize (text, len, style, &size);
1772 word = addWord (size.width, size.ascent, size.descent, style);
1493 PRINTF ("[%p] ADD_TEXT (%d characters)\n", this, (int)len);
1494
1495 // Count dividing characters.
1496 int numParts = 1;
1497
1498 for (const char *s = text; s; s = nextUtf8Char (s, text + len - s)) {
1499 int foundDiv = -1;
1500 for (int j = 0; foundDiv == -1 && j < NUM_DIV_CHARS; j++) {
1501 int lDiv = strlen (divChars[j].s);
1502 if (s <= text + len - lDiv) {
1503 if (memcmp (s, divChars[j].s, lDiv * sizeof (char)) == 0)
1504 foundDiv = j;
1505 }
1506 }
1507
1508 if (foundDiv != -1) {
1509 if (divChars[foundDiv].penaltyIndexLeft != -1)
1510 numParts ++;
1511 if (divChars[foundDiv].penaltyIndexRight != -1)
1512 numParts ++;
1513 }
1514 }
1515
1516 if (numParts == 1) {
1517 // Simple (and common) case: no dividing characters. May still
1518 // be hyphenated automatically.
1519 core::Requisition size;
1520 calcTextSize (text, len, style, &size, true, true);
1521 addText0 (text, len,
1522 Word::CAN_BE_HYPHENATED | Word::WORD_START | Word::WORD_END,
1523 style, &size);
1524
1525 //printf ("[%p] %d: added simple word: ", this, words->size() - 1);
1526 //printWordWithFlags (words->getLastRef());
1527 //printf ("\n");
1528 } else {
1529 PRINTF ("HYPHENATION: '");
1530 for (size_t i = 0; i < len; i++)
1531 PUTCHAR(text[i]);
1532 PRINTF ("', with %d parts\n", numParts);
1533
1534 // Store hyphen positions.
1535 int n = 0, totalLenCharRemoved = 0;
1536 int partPenaltyIndex[numParts - 1];
1537 int partStart[numParts], partEnd[numParts];
1538 bool charRemoved[numParts - 1], canBeHyphenated[numParts + 1];
1539 bool permDivChar[numParts - 1], unbreakableForMinWidth[numParts - 1];
1540 canBeHyphenated[0] = canBeHyphenated[numParts] = true;
1541 partStart[0] = 0;
1542 partEnd[numParts - 1] = len;
1543
1544 for (const char *s = text; s; s = nextUtf8Char (s, text + len - s)) {
1545 int foundDiv = -1;
1546 for (int j = 0; foundDiv == -1 && j < NUM_DIV_CHARS; j++) {
1547 int lDiv = strlen (divChars[j].s);
1548 if (s <= text + len - lDiv) {
1549 if (memcmp (s, divChars[j].s, lDiv * sizeof (char)) == 0)
1550 foundDiv = j;
1551 }
1552 }
1553
1554 if (foundDiv != -1) {
1555 int lDiv = strlen (divChars[foundDiv].s);
1556
1557 if (divChars[foundDiv].charRemoved) {
1558 assert (divChars[foundDiv].penaltyIndexLeft != -1);
1559 assert (divChars[foundDiv].penaltyIndexRight == -1);
1560
1561 partPenaltyIndex[n] = divChars[foundDiv].penaltyIndexLeft;
1562 charRemoved[n] = true;
1563 permDivChar[n] = false;
1564 unbreakableForMinWidth[n] =
1565 divChars[foundDiv].unbreakableForMinWidth;
1566 canBeHyphenated[n + 1] = divChars[foundDiv].canBeHyphenated;
1567 partEnd[n] = s - text;
1568 partStart[n + 1] = s - text + lDiv;
1569 n++;
1570 totalLenCharRemoved += lDiv;
1571 } else {
1572 assert (divChars[foundDiv].penaltyIndexLeft != -1 ||
1573 divChars[foundDiv].penaltyIndexRight != -1);
1574
1575 if (divChars[foundDiv].penaltyIndexLeft != -1) {
1576 partPenaltyIndex[n] = divChars[foundDiv].penaltyIndexLeft;
1577 charRemoved[n] = false;
1578 permDivChar[n] = false;
1579 unbreakableForMinWidth[n] =
1580 divChars[foundDiv].unbreakableForMinWidth;
1581 canBeHyphenated[n + 1] = divChars[foundDiv].canBeHyphenated;
1582 partEnd[n] = s - text;
1583 partStart[n + 1] = s - text;
1584 n++;
1585 }
1586
1587 if (divChars[foundDiv].penaltyIndexRight != -1) {
1588 partPenaltyIndex[n] = divChars[foundDiv].penaltyIndexRight;
1589 charRemoved[n] = false;
1590 permDivChar[n] = true;
1591 unbreakableForMinWidth[n] =
1592 divChars[foundDiv].unbreakableForMinWidth;
1593 canBeHyphenated[n + 1] = divChars[foundDiv].canBeHyphenated;
1594 partEnd[n] = s - text + lDiv;
1595 partStart[n + 1] = s - text + lDiv;
1596 n++;
1597 }
1598 }
1599 }
1600 }
1601
1602 // Get text without removed characters, e. g. hyphens.
1603 const char *textWithoutHyphens;
1604 char textWithoutHyphensBuf[len - totalLenCharRemoved];
1605 int *breakPosWithoutHyphens, breakPosWithoutHyphensBuf[numParts - 1];
1606
1607 if (totalLenCharRemoved == 0) {
1608 // No removed characters: take original arrays.
1609 textWithoutHyphens = text;
1610 // Ends are also break positions, except the last end, which
1611 // is superfluous, but does not harm (since arrays in C/C++
1612 // does not have an implicit length).
1613 breakPosWithoutHyphens = partEnd;
1614 } else {
1615 // Copy into special buffers.
1616 textWithoutHyphens = textWithoutHyphensBuf;
1617 breakPosWithoutHyphens = breakPosWithoutHyphensBuf;
1618
1619 int n = 0;
1620 for (int i = 0; i < numParts; i++) {
1621 memmove (textWithoutHyphensBuf + n, text + partStart[i],
1622 partEnd[i] - partStart[i]);
1623 n += partEnd[i] - partStart[i];
1624 if (i < numParts - 1)
1625 breakPosWithoutHyphensBuf[i] = n;
1626 }
1627 }
1628
1629 PRINTF("H... without hyphens: '");
1630 for (size_t i = 0; i < len - totalLenCharRemoved; i++)
1631 PUTCHAR(textWithoutHyphens[i]);
1632 PRINTF("'\n");
1633
1634 core::Requisition wordSize[numParts];
1635 calcTextSizes (textWithoutHyphens, len - totalLenCharRemoved, style,
1636 numParts - 1, breakPosWithoutHyphens, wordSize);
1637
1638 // Finished!
1639 for (int i = 0; i < numParts; i++) {
1640 short flags = 0;
1641
1642 // If this parts adjoins at least one division characters,
1643 // for which canBeHyphenated is set to false (this is the
1644 // case for soft hyphens), do not hyphenate.
1645 if (canBeHyphenated[i] && canBeHyphenated[i + 1])
1646 flags |= Word::CAN_BE_HYPHENATED;
1647
1648 if(i < numParts - 1) {
1649 if (charRemoved[i])
1650 flags |= Word::DIV_CHAR_AT_EOL;
1651
1652 if (permDivChar[i])
1653 flags |= Word::PERM_DIV_CHAR;
1654 if (unbreakableForMinWidth[i])
1655 flags |= Word::UNBREAKABLE_FOR_MIN_WIDTH;
1656
1657 flags |= Word::DRAW_AS_ONE_TEXT;
1658 }
1659
1660 if (i == 0)
1661 flags |= Word::WORD_START;
1662 if (i == numParts - 1)
1663 flags |= Word::WORD_END;
1664
1665 addText0 (text + partStart[i], partEnd[i] - partStart[i],
1666 flags, style, &wordSize[i]);
1667
1668 //printf ("[%p] %d: added word part: ", this, words->size() - 1);
1669 //printWordWithFlags (words->getLastRef());
1670 //printf ("\n");
1671
1672 //PRINTF("H... [%d] '", i);
1673 //for (int j = partStart[i]; j < partEnd[i]; j++)
1674 // PUTCHAR(text[j]);
1675 //PRINTF("' added\n");
1676
1677 if(i < numParts - 1) {
1678 Word *word = words->getLastRef();
1679
1680 setBreakOption (word, style, penalties[partPenaltyIndex[i]][0],
1681 penalties[partPenaltyIndex[i]][1]);
1682
1683 if (charRemoved[i])
1684 // Currently, only unconditional hyphens (UTF-8:
1685 // "\xe2\x80\x90") can be used. See also drawWord, last
1686 // section "if (drawHyphen)".
1687 // Could be extended by adding respective members to
1688 // DivChar and Word.
1689 word->hyphenWidth =
1690 layout->textWidth (word->style->font, hyphenDrawChar,
1691 strlen (hyphenDrawChar));
1692
1693 accumulateWordData (words->size() - 1);
1694 correctLastWordExtremes ();
1695 }
1696 }
1697 }
1698 }
1699
1700 void Textblock::calcTextSizes (const char *text, size_t textLen,
1701 core::style::Style *style,
1702 int numBreaks, int *breakPos,
1703 core::Requisition *wordSize)
1704 {
1705 // The size of the last part is calculated in a simple way.
1706 int lastStart = breakPos[numBreaks - 1];
1707 calcTextSize (text + lastStart, textLen - lastStart, style,
1708 &wordSize[numBreaks], true, true);
1709
1710 PRINTF("H... [%d] '", numBreaks);
1711 for (size_t i = 0; i < textLen - lastStart; i++)
1712 PUTCHAR(text[i + lastStart]);
1713 PRINTF("' -> %d\n", wordSize[numBreaks].width);
1714
1715 // The rest is more complicated. See dw-line-breaking, section
1716 // "Hyphens".
1717 for (int i = numBreaks - 1; i >= 0; i--) {
1718 int start = (i == 0) ? 0 : breakPos[i - 1];
1719 calcTextSize (text + start, textLen - start, style, &wordSize[i],
1720 i == 0, i == numBreaks - 1);
1721
1722 PRINTF("H... [%d] '", i);
1723 for (size_t j = 0; j < textLen - start; j++)
1724 PUTCHAR(text[j + start]);
1725 PRINTF("' -> %d\n", wordSize[i].width);
1726
1727 for (int j = i + 1; j < numBreaks + 1; j++) {
1728 wordSize[i].width -= wordSize[j].width;
1729 PRINTF("H... - %d = %d\n", wordSize[j].width, wordSize[i].width);
1730 }
1731 }
1732 }
1733
1734 /**
1735 * Add a word (without hyphens) to the page structure.
1736 */
1737 void Textblock::addText0 (const char *text, size_t len, short flags,
1738 core::style::Style *style, core::Requisition *size)
1739 {
1740 //printf("[%p] addText0 ('", this);
1741 //for (size_t i = 0; i < len; i++)
1742 // putchar(text[i]);
1743 //printf("', ");
1744 //printWordFlags (flags);
1745 //printf (", ...)\n");
1746
1747 Word *word = addWord (size->width, size->ascent, size->descent,
1748 flags, style);
17731749 word->content.type = core::Content::TEXT;
17741750 word->content.text = layout->textZone->strndup(text, len);
17751751
1776 //DBG_OBJ_ARRSET_STR (page, "words.%d.content.text", words->size() - 1,
1777 // word->content.text);
1778
1779 wordWrap (words->size () - 1);
1752 processWord (words->size () - 1);
17801753 }
17811754
17821755 /**
17931766 * end of this function, the correct value is assigned. */
17941767 widget->parentRef = -1;
17951768
1769 PRINTF ("%p becomes child of %p\n", widget, this);
1770
17961771 widget->setParent (this);
17971772 widget->setStyle (style);
17981773
17991774 calcWidgetSize (widget, &size);
1800 word = addWord (size.width, size.ascent, size.descent, style);
1775 word = addWord (size.width, size.ascent, size.descent, 0, style);
18011776
18021777 word->content.type = core::Content::WIDGET;
18031778 word->content.widget = widget;
18051780 //DBG_OBJ_ARRSET_PTR (page, "words.%d.content.widget", words->size() - 1,
18061781 // word->content.widget);
18071782
1808 wordWrap (words->size () - 1);
1809 word->content.widget->parentRef = lines->size () - 1;
1783 processWord (words->size () - 1);
18101784 //DBG_OBJ_SET_NUM (word->content.widget, "parent_ref",
18111785 // word->content.widget->parent_ref);
18121786
18631837 void Textblock::addSpace (core::style::Style *style)
18641838 {
18651839 int wordIndex = words->size () - 1;
1866
18671840 if (wordIndex >= 0) {
1868 Word *word = words->getRef(wordIndex);
1869
1870 // According to http://www.w3.org/TR/CSS2/text.html#white-space-model:
1871 // "line breaking opportunities are determined based on the text prior
1872 // to the white space collapsing steps".
1873 // So we call addBreakOption () for each Textblock::addSpace () call.
1874 // This is important e.g. to be able to break between foo and bar in:
1875 // <span style="white-space:nowrap">foo </span> bar
1876 addBreakOption (style);
1877
1878 if (!word->content.space) {
1879 word->content.space = true;
1880 word->effSpace = word->origSpace = style->font->spaceWidth +
1881 style->wordSpacing;
1882
1883 //DBG_OBJ_ARRSET_NUM (this, "words.%d.origSpace", wordIndex,
1884 // word->origSpace);
1885 //DBG_OBJ_ARRSET_NUM (this, "words.%d.effSpace", wordIndex,
1886 // word->effSpace);
1887 //DBG_OBJ_ARRSET_NUM (this, "words.%d.content.space", wordIndex,
1888 // word->content.space);
1889 word->spaceStyle->unref ();
1890 word->spaceStyle = style;
1891 style->ref ();
1892 }
1893 }
1894 }
1841 fillSpace (words->getRef(wordIndex), style);
1842 accumulateWordData (wordIndex);
1843 correctLastWordExtremes ();
1844 }
1845 }
1846
1847 /**
1848 * Add a break option (see setBreakOption() for details). Used instead
1849 * of addStyle for ideographic characters.
1850 */
1851 void Textblock::addBreakOption (core::style::Style *style)
1852 {
1853 int wordIndex = words->size () - 1;
1854 if (wordIndex >= 0) {
1855 setBreakOption (words->getRef(wordIndex), style, 0, 0);
1856 // Call of accumulateWordData() is not needed here.
1857 correctLastWordExtremes ();
1858 }
1859 }
1860
1861 void Textblock::fillSpace (Word *word, core::style::Style *style)
1862 {
1863 // Old comment:
1864 //
1865 // According to
1866 // http://www.w3.org/TR/CSS2/text.html#white-space-model: "line
1867 // breaking opportunities are determined based on the text
1868 // prior to the white space collapsing steps".
1869 //
1870 // So we call addBreakOption () for each Textblock::addSpace ()
1871 // call. This is important e.g. to be able to break between
1872 // foo and bar in: <span style="white-space:nowrap">foo </span>
1873 // bar
1874 //
1875 // TODO: Re-evaluate again.
1876
1877 // TODO: This line does not work: addBreakOption (word, style);
1878
1879 // Do not override a previously set break penalty.
1880 if (!word->content.space) {
1881 setBreakOption (word, style, 0, 0);
1882
1883 word->content.space = true;
1884 word->effSpace = word->origSpace = style->font->spaceWidth +
1885 style->wordSpacing;
1886
1887 //DBG_OBJ_ARRSET_NUM (this, "words.%d.origSpace", wordIndex,
1888 // word->origSpace);
1889 //DBG_OBJ_ARRSET_NUM (this, "words.%d.effSpace", wordIndex,
1890 // word->effSpace);
1891 //DBG_OBJ_ARRSET_NUM (this, "words.%d.content.space", wordIndex,
1892 // word->content.space);
1893
1894 word->spaceStyle->unref ();
1895 word->spaceStyle = style;
1896 style->ref ();
1897 }
1898 }
1899
1900 /**
1901 * Set a break option, if allowed by the style. Called by fillSpace
1902 * (and so addSpace), but may be called, via addBreakOption(), as an
1903 * alternative, e. g. for ideographic characters.
1904 */
1905 void Textblock::setBreakOption (Word *word, core::style::Style *style,
1906 int breakPenalty1, int breakPenalty2)
1907 {
1908 // TODO: lineMustBeBroken should be independent of the penalty
1909 // index? Otherwise, examine the last line.
1910 if (!word->badnessAndPenalty.lineMustBeBroken(0)) {
1911 switch (style->whiteSpace) {
1912 case core::style::WHITE_SPACE_NORMAL:
1913 case core::style::WHITE_SPACE_PRE_LINE:
1914 case core::style::WHITE_SPACE_PRE_WRAP:
1915 word->badnessAndPenalty.setPenalties (breakPenalty1, breakPenalty2);
1916 break;
1917
1918 case core::style::WHITE_SPACE_PRE:
1919 case core::style::WHITE_SPACE_NOWRAP:
1920 word->badnessAndPenalty.setPenalty (PENALTY_PROHIBIT_BREAK);
1921 break;
1922 }
1923 }
1924 }
1925
18951926
18961927 /**
18971928 * Cause a paragraph break
19621993 return;
19631994 }
19641995
1965 word = addWord (0, 0, 0, style);
1996 word = addWord (0, 0, 0, 0, style);
19661997 word->content.type = core::Content::BREAK;
1998 word->badnessAndPenalty.setPenalty (PENALTY_FORCE_BREAK);
19671999 word->content.breakSpace = space;
1968 wordWrap (words->size () - 1);
2000 processWord (words->size () - 1);
19692001 }
19702002
19712003 /*
19792011 words->getRef(words->size () - 1)->content.type == core::Content::BREAK)
19802012 // An <BR> in an empty line gets the height of the current font
19812013 // (why would someone else place it here?), ...
1982 word = addWord (0, style->font->ascent, style->font->descent, style);
2014 word =
2015 addWord (0, style->font->ascent, style->font->descent, 0, style);
19832016 else
19842017 // ... otherwise, it has no size (and does not enlarge the line).
1985 word = addWord (0, 0, 0, style);
2018 word = addWord (0, 0, 0, 0, style);
19862019
19872020 word->content.type = core::Content::BREAK;
2021 word->badnessAndPenalty.setPenalty (PENALTY_FORCE_BREAK);
19882022 word->content.breakSpace = 0;
1989 wordWrap (words->size () - 1);
2023 processWord (words->size () - 1);
19902024 }
19912025
19922026
20592093 */
20602094 void Textblock::flush ()
20612095 {
2096 PRINTF ("[%p] FLUSH => %s (parentRef = %d)\n",
2097 this, mustQueueResize ? "true" : "false", parentRef);
2098
20622099 if (mustQueueResize) {
20632100 queueResize (-1, true);
20642101 mustQueueResize = false;
20872124 styleAttrs = *old_style;
20882125 styleAttrs.color = core::style::Color::create (layout,
20892126 newColor);
2090 word->style = core::style::Style::create (layout, &styleAttrs);
2127 word->style = core::style::Style::create (&styleAttrs);
20912128 old_style->unref();
20922129 old_style = word->spaceStyle;
20932130 styleAttrs = *old_style;
20942131 styleAttrs.color = core::style::Color::create (layout,
20952132 newColor);
2096 word->spaceStyle =
2097 core::style::Style::create(layout, &styleAttrs);
2133 word->spaceStyle = core::style::Style::create(&styleAttrs);
20982134 old_style->unref();
20992135 break;
21002136 }
21052141 newColor);
21062142 styleAttrs.setBorderColor(
21072143 core::style::Color::create (layout, newColor));
2108 widget->setStyle(
2109 core::style::Style::create (layout, &styleAttrs));
2144 widget->setStyle(core::style::Style::create (&styleAttrs));
21102145 break;
21112146 }
21122147 default:
21262161 {
21272162 }
21282163
2129 // ----------------------------------------------------------------------
2130
2131 Textblock::TextblockIterator::TextblockIterator (Textblock *textblock,
2132 core::Content::Type mask,
2133 bool atEnd):
2134 core::Iterator (textblock, mask, atEnd)
2135 {
2136 index = atEnd ? textblock->words->size () : -1;
2137 content.type = atEnd ? core::Content::END : core::Content::START;
2138 }
2139
2140 Textblock::TextblockIterator::TextblockIterator (Textblock *textblock,
2141 core::Content::Type mask,
2142 int index):
2143 core::Iterator (textblock, mask, false)
2144 {
2145 this->index = index;
2146
2147 if (index < 0)
2148 content.type = core::Content::START;
2149 else if (index >= textblock->words->size ())
2150 content.type = core::Content::END;
2151 else
2152 content = textblock->words->getRef(index)->content;
2153 }
2154
2155 object::Object *Textblock::TextblockIterator::clone()
2156 {
2157 return new TextblockIterator ((Textblock*)getWidget(), getMask(), index);
2158 }
2159
2160 int Textblock::TextblockIterator::compareTo(misc::Comparable *other)
2161 {
2162 return index - ((TextblockIterator*)other)->index;
2163 }
2164
2165 bool Textblock::TextblockIterator::next ()
2166 {
2167 Textblock *textblock = (Textblock*)getWidget();
2168
2169 if (content.type == core::Content::END)
2170 return false;
2171
2172 do {
2173 index++;
2174 if (index >= textblock->words->size ()) {
2175 content.type = core::Content::END;
2176 return false;
2177 }
2178 } while ((textblock->words->getRef(index)->content.type & getMask()) == 0);
2179
2180 content = textblock->words->getRef(index)->content;
2181 return true;
2182 }
2183
2184 bool Textblock::TextblockIterator::prev ()
2185 {
2186 Textblock *textblock = (Textblock*)getWidget();
2187
2188 if (content.type == core::Content::START)
2189 return false;
2190
2191 do {
2192 index--;
2193 if (index < 0) {
2194 content.type = core::Content::START;
2195 return false;
2196 }
2197 } while ((textblock->words->getRef(index)->content.type & getMask()) == 0);
2198
2199 content = textblock->words->getRef(index)->content;
2200 return true;
2201 }
2202
2203 void Textblock::TextblockIterator::highlight (int start, int end,
2204 core::HighlightLayer layer)
2205 {
2206 Textblock *textblock = (Textblock*)getWidget();
2207 int index1 = index, index2 = index;
2208
2209 if (textblock->hlStart[layer].index > textblock->hlEnd[layer].index) {
2210 /* nothing is highlighted */
2211 textblock->hlStart[layer].index = index;
2212 textblock->hlEnd[layer].index = index;
2213 }
2214
2215 if (textblock->hlStart[layer].index >= index) {
2216 index2 = textblock->hlStart[layer].index;
2217 textblock->hlStart[layer].index = index;
2218 textblock->hlStart[layer].nChar = start;
2219 }
2220
2221 if (textblock->hlEnd[layer].index <= index) {
2222 index2 = textblock->hlEnd[layer].index;
2223 textblock->hlEnd[layer].index = index;
2224 textblock->hlEnd[layer].nChar = end;
2225 }
2226
2227 textblock->queueDrawRange (index1, index2);
2228 }
2229
2230 void Textblock::TextblockIterator::unhighlight (int direction,
2231 core::HighlightLayer layer)
2232 {
2233 Textblock *textblock = (Textblock*)getWidget();
2234 int index1 = index, index2 = index;
2235
2236 if (textblock->hlStart[layer].index > textblock->hlEnd[layer].index)
2237 return;
2238
2239 if (direction == 0) {
2240 index1 = textblock->hlStart[layer].index;
2241 index2 = textblock->hlEnd[layer].index;
2242 textblock->hlStart[layer].index = 1;
2243 textblock->hlEnd[layer].index = 0;
2244 } else if (direction > 0 && textblock->hlStart[layer].index <= index) {
2245 index1 = textblock->hlStart[layer].index;
2246 textblock->hlStart[layer].index = index + 1;
2247 textblock->hlStart[layer].nChar = 0;
2248 } else if (direction < 0 && textblock->hlEnd[layer].index >= index) {
2249 index1 = textblock->hlEnd[layer].index;
2250 textblock->hlEnd[layer].index = index - 1;
2251 textblock->hlEnd[layer].nChar = INT_MAX;
2252 }
2253
2254 textblock->queueDrawRange (index1, index2);
2255 }
2256
22572164 void Textblock::queueDrawRange (int index1, int index2)
22582165 {
22592166 int from = misc::min (index1, index2);
22792186 }
22802187 }
22812188
2282 void Textblock::TextblockIterator::getAllocation (int start, int end,
2283 core::Allocation *allocation)
2284 {
2285 Textblock *textblock = (Textblock*)getWidget();
2286 int lineIndex = textblock->findLineOfWord (index);
2287 Line *line = textblock->lines->getRef (lineIndex);
2288 Word *word = textblock->words->getRef (index);
2289
2290 allocation->x =
2291 textblock->allocation.x + textblock->lineXOffsetWidget (line);
2292
2293 for (int i = line->firstWord; i < index; i++) {
2294 Word *w = textblock->words->getRef(i);
2295 allocation->x += w->size.width + w->effSpace;
2296 }
2297 if (start > 0 && word->content.type == core::Content::TEXT) {
2298 allocation->x += textblock->textWidth (word->content.text, 0, start,
2299 word->style);
2300 }
2301 allocation->y = textblock->lineYOffsetCanvas (line) + line->boxAscent -
2302 word->size.ascent;
2303
2304 allocation->width = word->size.width;
2305 if (word->content.type == core::Content::TEXT) {
2306 int wordEnd = strlen(word->content.text);
2307
2308 if (start > 0 || end < wordEnd) {
2309 end = misc::min(end, wordEnd); /* end could be INT_MAX */
2310 allocation->width =
2311 textblock->textWidth (word->content.text, start, end - start,
2312 word->style);
2313 }
2314 }
2315 allocation->ascent = word->size.ascent;
2316 allocation->descent = word->size.descent;
2317 }
2318
23192189 } // namespace dw
00 #ifndef __DW_TEXTBLOCK_HH__
11 #define __DW_TEXTBLOCK_HH__
22
3 #include <limits.h>
4
35 #include "core.hh"
46 #include "../lout/misc.hh"
7
8 // These were used when improved line breaking and hyphenation were
9 // implemented. Should be cleaned up; perhaps reactivate RTFL again.
10 #define PRINTF(fmt, ...)
11 #define PUTCHAR(ch)
512
613 namespace dw {
714
815 /**
916 * \brief A Widget for rendering text blocks, i.e. paragraphs or sequences
1017 * of paragraphs.
18 *
19 * <div style="border: 2px solid #ffff00; margin-top: 0.5em;
20 * margin-bottom: 0.5em; padding: 0.5em 1em;
21 * background-color: #ffffe0"><b>Info:</b> The recent changes (line
22 * breaking and hyphenation) have not yet been incorporated into this
23 * documentation. See \ref dw-line-breaking.</div>
1124 *
1225 * <h3>Signals</h3>
1326 *
8295 *
8396 * <h3>Some Internals</h3>
8497 *
85 * There are 3 lists, dw::Textblock::words, dw::Textblock::lines, and
86 * dw::Textblock::anchors. The word list is quite static; only new words
87 * may be added. A word is either text, a widget, or a break.
98 * There are 4 lists, dw::Textblock::words, dw::Textblock::paragraphs,
99 * dw::Textblock::lines, and dw::Textblock::anchors. The word list is
100 * quite static; only new words may be added. A word is either text, a
101 * widget, or a break.
88102 *
89103 * Lines refer to the word list (first and last). They are completely
90104 * redundant, i.e., they can be rebuilt from the words. Lines can be
92106 * below). For the latter purpose, several values are accumulated in the
93107 * lines. See dw::Textblock::Line for details.
94108 *
109 * A recent change was the introduction of the paragraphs list, which
110 * works quite similar, is also redundant, but is used to calculate
111 * the extremes, not the size.
112 *
95113 * Anchors associate the anchor name with the index of the next word at
96114 * the point of the anchor.
97115 *
129147 */
130148 class Textblock: public core::Widget
131149 {
150 private:
151 /**
152 * This class encapsulates the badness/penalty calculation, and so
153 * (i) makes changes (hopefully) simpler, and (ii) hides the
154 * integer arithmetic (floating point arithmetic avoided for
155 * performance reasons). Unfortunately, the value range of the
156 * badness is not well defined, so fiddling with the penalties is a
157 * bit difficult.
158 */
159
160 enum {
161 PENALTY_FORCE_BREAK = INT_MIN,
162 PENALTY_PROHIBIT_BREAK = INT_MAX
163 };
164
165 class BadnessAndPenalty
166 {
167 private:
168 enum { NOT_STRETCHABLE, QUITE_LOOSE, BADNESS_VALUE, TOO_TIGHT }
169 badnessState;
170 int ratio; // ratio is only defined when badness is defined
171 int badness, penalty[2];
172
173 // For debugging: define DEBUG for more informations in print().
174 #ifdef DEBUG
175 int totalWidth, idealWidth, totalStretchability, totalShrinkability;
176 #endif
177
178 // "Infinity levels" are used to represent very large numbers,
179 // including "quasi-infinite" numbers. A couple of infinity
180 // level and number can be mathematically represented as
181 //
182 // number * N ^ (infinity level)
183 //
184 // where N is a number which is large enough. Practically,
185 // infinity levels are used to circumvent limited ranges for
186 // integer numbers.
187
188 // Here, all infinity levels have got special meanings.
189 enum {
190 INF_VALUE = 0, /* simple values */
191 INF_LARGE, /* large values, like QUITE_LOOSE */
192 INF_NOT_STRETCHABLE, /* reserved for NOT_STRECTHABLE */
193 INF_TOO_TIGHT, /* used for lines, which are too tight */
194 INF_PENALTIES, /* used for penalties */
195 INF_MAX = INF_PENALTIES
196
197 // That INF_PENALTIES is the last value means that an
198 // infinite penalty (breaking is prohibited) makes a break
199 // not possible at all, so that pre-formatted text
200 // etc. works.
201 };
202
203 void setSinglePenalty (int index, int penalty);
204 int badnessValue (int infLevel);
205 int penaltyValue (int index, int infLevel);
206
207 public:
208 void calcBadness (int totalWidth, int idealWidth,
209 int totalStretchability, int totalShrinkability);
210 inline void setPenalty (int penalty) { setPenalties (penalty, penalty); }
211 void setPenalties (int penalty1, int penalty2);
212
213 bool lineLoose ();
214 bool lineTight ();
215 bool lineTooTight ();
216 bool lineMustBeBroken (int penaltyIndex);
217 bool lineCanBeBroken (int penaltyIndex);
218 int compareTo (int penaltyIndex, BadnessAndPenalty *other);
219
220 void print ();
221 };
222
223 enum { PENALTY_HYPHEN, PENALTY_EM_DASH_LEFT, PENALTY_EM_DASH_RIGHT,
224 PENALTY_NUM };
225 enum { NUM_DIV_CHARS = 4 };
226
227 typedef struct
228 {
229 const char *s;
230 bool charRemoved, canBeHyphenated, unbreakableForMinWidth;
231 int penaltyIndexLeft, penaltyIndexRight;
232 } DivChar;
233
234 static DivChar divChars[NUM_DIV_CHARS];
235
236 static const char *hyphenDrawChar;
237
132238 protected:
239 struct Paragraph
240 {
241 int firstWord; /* first word's index in word vector */
242 int lastWord; /* last word's index in word vector */
243
244 // TODO Adjust comments. Short note: maxParMin/maxParMax is
245 // is never smaller than parMin/parMax.
246
247 /*
248 * General remark: all values include the last hyphen width, but
249 * not the last space; these values are, however corrected, when
250 * another word is added.
251 *
252 * Also, as opposed to lines, paragraphs are created with the
253 * first, not the last word, so these values change when new
254 * words are added.
255 */
256
257 int parMin; /* The sum of all word minima (plus spaces,
258 hyphen width etc.) of the last c */
259 int parMax; /* The sum of all word maxima in this
260 * paragraph (plus spaces, hyphen width
261 * etc.). */
262
263 int maxParMin; /* Maximum of all paragraph minima, including
264 * this line. */
265 int maxParMax; /* Maximum of all paragraph maxima (value of "parMax"),
266 * including this one. */
267 };
268
133269 struct Line
134270 {
135271 int firstWord; /* first word's index in word vector */
144280 * widgets within this line. */
145281 int marginDescent;
146282
147 /* The following members contain accumulated values, from the top
148 * down to the line before. */
149 int maxLineWidth; /* maximum of all line widths */
150 int maxParMin; /* maximum of all paragraph minima */
151 int maxParMax; /* maximum of all paragraph maxima */
152 int parMax; /* the maximal total width down from the last
153 * paragraph start, to the *beginning* of the
154 * line */
283 /* Maximum of all line widths, including this line. Does not
284 * include the last space, but the last hyphen width. Please
285 * notice a change: until recently (before hyphenation and
286 * changed line breaking), the values were accumulated up to the
287 * last line, not this line.*/
288 int maxLineWidth;
155289 };
156290
157291 struct Word
158292 {
293 enum {
294 /** Can be hyphenated automatically. (Cleared after
295 * hyphenation.) */
296 CAN_BE_HYPHENATED = 1 << 0,
297 /** Must be drawn with a hyphen, when at the end of the line. */
298 DIV_CHAR_AT_EOL = 1 << 1,
299 /** Is or ends with a "division character", which is part of
300 * the word. */
301 PERM_DIV_CHAR = 1 << 2,
302 /** This word must be drawn, together with the following
303 * word(s), by only one call of View::drawText(), to get
304 * kerning, ligatures etc. right. The last of the words drawn
305 * as one text does *not* have this flag set. */
306 DRAW_AS_ONE_TEXT = 1 << 3,
307 /* When calculating the minimal width (as part of extremes),
308 * do not consider this word as breakable. This flag is
309 * ignored when the line is actually broken. */
310 UNBREAKABLE_FOR_MIN_WIDTH = 1 << 4,
311 /* If a word represents a "real" text word, or (after
312 * hyphenation) the first part of a "real" text word, this
313 * flag is set. Plays a role for text transformation. */
314 WORD_START = 1 << 5,
315 /* If a word represents a "real" text word, or (after
316 * hyphenation) the last part of a "real" text word, this
317 * flag is set. Analogue to WORD_START. */
318 WORD_END = 1 << 6
319 };
320
159321 /* TODO: perhaps add a xLeft? */
160322 core::Requisition size;
161323 /* Space after the word, only if it's not a break: */
162324 short origSpace; /* from font, set by addSpace */
163325 short effSpace; /* effective space, set by wordWrap,
164326 * used for drawing etc. */
327 short hyphenWidth; /* Additional width, when a word is part
328 * (except the last part) of a hyphenationed
329 * word. Has to be added to the width, when
330 * this is the last word of the line, and
331 * "hyphenWidth > 0" is also used to decide
332 * whether to draw a hyphen. */
333 short flags;
165334 core::Content content;
335
336 // accumulated values, relative to the beginning of the line
337 int totalWidth; /* The sum of all word widths; plus all
338 spaces, excluding the one of this
339 word; plus the hyphen width of this
340 word (but of course, no hyphen
341 widths of previous words. In other
342 words: the value compared to the
343 ideal width of the line, if the line
344 would be broken after this word. */
345 int totalStretchability; // includes all *before* current word
346 int totalShrinkability; // includes all *before* current word
347 BadnessAndPenalty badnessAndPenalty; /* when line is broken after this
348 * word */
166349
167350 core::style::Style *style;
168351 core::style::Style *spaceStyle; /* initially the same as of the word,
169352 later set by a_Dw_page_add_space */
170353 };
354
355 void printWordShort (Word *word);
356 void printWordFlags (short flags);
357 void printWordWithFlags (Word *word);
358 void printWord (Word *word);
171359
172360 struct Anchor
173361 {
187375 int index);
188376
189377 lout::object::Object *clone();
190 int compareTo(lout::misc::Comparable *other);
378 int compareTo(lout::object::Comparable *other);
191379
192380 bool next ();
193381 bool prev ();
227415
228416 bool mustQueueResize;
229417
418 /**
419 * The penalties for hyphens and other, multiplied by 100. So, 100
420 * means 1.0. INT_MAX and INT_MIN are also allowed. See
421 * dw::Textblock::BadnessAndPenalty::setPenalty for more
422 * details. Set from preferences.
423 */
424 static int penalties[PENALTY_NUM][2];
425
230426 bool limitTextWidth; /* from preferences */
231427
232428 int redrawY;
235431 /* These values are set by set_... */
236432 int availWidth, availAscent, availDescent;
237433
238 int lastLineWidth;
239 int lastLineParMin; /* width of the current non-breakable word sequence
240 * used by wordWrap () */
241 int lastLineParMax;
242 int wrapRef; /* [0 based] */
434 int wrapRefLines, wrapRefParagraphs; /* [0 based] */
243435
244436 lout::misc::SimpleVector <Line> *lines;
245 lout::misc::SimpleVector <Word> *words;
437 lout::misc::SimpleVector <Paragraph> *paragraphs;
438 int nonTemporaryLines;
439 lout::misc::NotSoSimpleVector <Word> *words;
246440 lout::misc::SimpleVector <Anchor> *anchors;
247441
248442 struct {int index, nChar;}
253447
254448 void queueDrawRange (int index1, int index2);
255449 void getWordExtremes (Word *word, core::Extremes *extremes);
256 inline bool canBreakAfter (Word *word)
257 {
258 return word->content.breakType == core::Content::BREAK_OK;
259 }
260 void markChange (int ref);
261 void justifyLine (Line *line, int availWidth);
262 Line *addLine (int wordInd, bool newPar);
450 void justifyLine (Line *line, int diff);
451 Line *addLine (int firstWord, int lastWord, bool temporary);
263452 void calcWidgetSize (core::Widget *widget, core::Requisition *size);
264453 void rewrap ();
265 void decorateText(core::View *view, core::style::Style *style,
266 core::style::Color::Shading shading,
267 int x, int yBase, int width);
268 void drawText(core::View *view, core::style::Style *style,
269 core::style::Color::Shading shading, int x, int y,
270 const char *text, int start, int len);
271 void drawWord(int wordIndex, core::View *view, core::Rectangle *area,
272 int xWidget, int yWidgetBase);
273 void drawSpace(int wordIndex, core::View *view, core::Rectangle *area,
274 int xWidget, int yWidgetBase);
454 void fillParagraphs ();
455 void showMissingLines ();
456 void removeTemporaryLines ();
457
458 void decorateText (core::View *view, core::style::Style *style,
459 core::style::Color::Shading shading,
460 int x, int yBase, int width);
461 void drawText (core::View *view, core::style::Style *style,
462 core::style::Color::Shading shading, int x, int y,
463 const char *text, int start, int len, bool isStart,
464 bool isEnd);
465 void drawWord (Line *line, int wordIndex1, int wordIndex2, core::View *view,
466 core::Rectangle *area, int xWidget, int yWidgetBase);
467 void drawWord0 (int wordIndex1, int wordIndex2,
468 const char *text, int totalWidth, bool drawHyphen,
469 core::style::Style *style, core::View *view,
470 core::Rectangle *area, int xWidget, int yWidgetBase);
471 void drawSpace (int wordIndex, core::View *view, core::Rectangle *area,
472 int xWidget, int yWidgetBase);
275473 void drawLine (Line *line, core::View *view, core::Rectangle *area);
276474 int findLineIndex (int y);
277475 int findLineOfWord (int wordIndex);
476 int findParagraphOfWord (int wordIndex);
278477 Word *findWord (int x, int y, bool *inSpace);
279478
280 Word *addWord (int width, int ascent, int descent,
479 Word *addWord (int width, int ascent, int descent, short flags,
281480 core::style::Style *style);
481 void fillWord (Word *word, int width, int ascent, int descent,
482 short flags, core::style::Style *style);
483 void fillSpace (Word *word, core::style::Style *style);
484 void setBreakOption (Word *word, core::style::Style *style,
485 int breakPenalty1, int breakPenalty2);
282486 int textWidth (const char *text, int start, int len,
283 core::style::Style *style);
487 core::style::Style *style, bool isStart, bool isEnd);
284488 void calcTextSize (const char *text, size_t len, core::style::Style *style,
285 core::Requisition *size);
489 core::Requisition *size, bool isStart, bool isEnd);
286490
287491 /**
288492 * \brief Returns the x offset (the indentation plus any offset needed for
294498 inline int lineXOffsetContents (Line *line)
295499 {
296500 return innerPadding + line->leftOffset +
297 (line == lines->getRef (0) ? line1OffsetEff : 0);
501 (line == lines->getFirstRef() ? line1OffsetEff : 0);
298502 }
299503
300504 /**
343547 {
344548 return lineYOffsetCanvas (lines->getRef (lineIndex));
345549 }
550
551 inline int calcPenaltyIndexForNewLine ()
552 {
553 if (lines->size() == 0)
554 return 0;
555 else
556 return
557 (words->getRef(lines->getLastRef()->lastWord)->flags &
558 (Word::DIV_CHAR_AT_EOL | Word::PERM_DIV_CHAR)) ? 1 : 0;
559 }
346560
347561 bool sendSelectionEvent (core::SelectionState::EventType eventType,
348562 core::MousePositionEvent *event);
349563
350 virtual void wordWrap(int wordIndex);
564 void accumulateWordExtremes (int firstWord, int lastWord,
565 int *maxOfMinWidth, int *sumOfMaxWidth);
566 void processWord (int wordIndex);
567 virtual void wordWrap (int wordIndex, bool wrapAll);
568 void handleWordExtremes (int wordIndex);
569 void correctLastWordExtremes ();
570
571 static int getShrinkability(struct Word *word);
572 static int getStretchability(struct Word *word);
573 int hyphenateWord (int wordIndex);
574 void accumulateWordForLine (int lineIndex, int wordIndex);
575 void accumulateWordData (int wordIndex);
576 int calcAvailWidth (int lineIndex);
577 void initLine1Offset (int wordIndex);
578 void alignLine (int lineIndex);
351579
352580 void sizeRequestImpl (core::Requisition *requisition);
353581 void getExtremesImpl (core::Extremes *extremes);
369597
370598 void removeChild (Widget *child);
371599
600 void addText0 (const char *text, size_t len, short flags,
601 core::style::Style *style, core::Requisition *size);
602 void calcTextSizes (const char *text, size_t textLen,
603 core::style::Style *style,
604 int numBreaks, int *breakPos,
605 core::Requisition *wordSize);
606
372607 public:
373608 static int CLASS_ID;
374609
610 static void setPenaltyHyphen (int penaltyHyphen);
611 static void setPenaltyHyphen2 (int penaltyHyphen2);
612 static void setPenaltyEmDashLeft (int penaltyLeftEmDash);
613 static void setPenaltyEmDashRight (int penaltyRightEmDash);
614 static void setPenaltyEmDashRight2 (int penaltyRightEmDash2);
615
375616 Textblock(bool limitTextWidth);
376617 ~Textblock();
377618
386627 }
387628 void addWidget (core::Widget *widget, core::style::Style *style);
388629 bool addAnchor (const char *name, core::style::Style *style);
389 void addSpace(core::style::Style *style);
390 inline void addBreakOption (core::style::Style *style)
391 {
392 int wordIndex = words->size () - 1;
393 if (wordIndex >= 0 &&
394 style->whiteSpace != core::style::WHITE_SPACE_NOWRAP &&
395 style->whiteSpace != core::style::WHITE_SPACE_PRE)
396 words->getRef(wordIndex)->content.breakType = core::Content::BREAK_OK;
397 }
630 void addSpace (core::style::Style *style);
631 void addBreakOption (core::style::Style *style);
398632 void addParbreak (int space, core::style::Style *style);
399633 void addLinebreak (core::style::Style *style);
400634
0 /*
1 * Dillo Widget
2 *
3 * Copyright 2005-2007, 2012-2013 Sebastian Geerken <sgeerken@dillo.org>
4 *
5 * (Parts of this file were originally part of textblock.cc.)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "textblock.hh"
22 #include "../lout/msg.h"
23 #include "../lout/misc.hh"
24
25 #include <stdio.h>
26 #include <math.h>
27
28 using namespace lout;
29
30 namespace dw {
31
32 Textblock::TextblockIterator::TextblockIterator (Textblock *textblock,
33 core::Content::Type mask,
34 bool atEnd):
35 core::Iterator (textblock, mask, atEnd)
36 {
37 index = atEnd ? textblock->words->size () : -1;
38 content.type = atEnd ? core::Content::END : core::Content::START;
39 }
40
41 Textblock::TextblockIterator::TextblockIterator (Textblock *textblock,
42 core::Content::Type mask,
43 int index):
44 core::Iterator (textblock, mask, false)
45 {
46 this->index = index;
47
48 if (index < 0)
49 content.type = core::Content::START;
50 else if (index >= textblock->words->size ())
51 content.type = core::Content::END;
52 else
53 content = textblock->words->getRef(index)->content;
54 }
55
56 object::Object *Textblock::TextblockIterator::clone()
57 {
58 return new TextblockIterator ((Textblock*)getWidget(), getMask(), index);
59 }
60
61 int Textblock::TextblockIterator::compareTo(object::Comparable *other)
62 {
63 return index - ((TextblockIterator*)other)->index;
64 }
65
66 bool Textblock::TextblockIterator::next ()
67 {
68 Textblock *textblock = (Textblock*)getWidget();
69
70 if (content.type == core::Content::END)
71 return false;
72
73 do {
74 index++;
75 if (index >= textblock->words->size ()) {
76 content.type = core::Content::END;
77 return false;
78 }
79 } while ((textblock->words->getRef(index)->content.type & getMask()) == 0);
80
81 content = textblock->words->getRef(index)->content;
82 return true;
83 }
84
85 bool Textblock::TextblockIterator::prev ()
86 {
87 Textblock *textblock = (Textblock*)getWidget();
88
89 if (content.type == core::Content::START)
90 return false;
91
92 do {
93 index--;
94 if (index < 0) {
95 content.type = core::Content::START;
96 return false;
97 }
98 } while ((textblock->words->getRef(index)->content.type & getMask()) == 0);
99
100 content = textblock->words->getRef(index)->content;
101 return true;
102 }
103
104 void Textblock::TextblockIterator::highlight (int start, int end,
105 core::HighlightLayer layer)
106 {
107 Textblock *textblock = (Textblock*)getWidget();
108 int index1 = index, index2 = index;
109
110 int oldStartIndex = textblock->hlStart[layer].index;
111 int oldStartChar = textblock->hlStart[layer].nChar;
112 int oldEndIndex = textblock->hlEnd[layer].index;
113 int oldEndChar = textblock->hlEnd[layer].nChar;
114
115 if (textblock->hlStart[layer].index > textblock->hlEnd[layer].index) {
116 /* nothing is highlighted */
117 textblock->hlStart[layer].index = index;
118 textblock->hlEnd[layer].index = index;
119 }
120
121 if (textblock->hlStart[layer].index >= index) {
122 index2 = textblock->hlStart[layer].index;
123 textblock->hlStart[layer].index = index;
124 textblock->hlStart[layer].nChar = start;
125 }
126
127 if (textblock->hlEnd[layer].index <= index) {
128 index2 = textblock->hlEnd[layer].index;
129 textblock->hlEnd[layer].index = index;
130 textblock->hlEnd[layer].nChar = end;
131 }
132
133 if (oldStartIndex != textblock->hlStart[layer].index ||
134 oldStartChar != textblock->hlStart[layer].nChar ||
135 oldEndIndex != textblock->hlEnd[layer].index ||
136 oldEndChar != textblock->hlEnd[layer].nChar)
137 textblock->queueDrawRange (index1, index2);
138 }
139
140 void Textblock::TextblockIterator::unhighlight (int direction,
141 core::HighlightLayer layer)
142 {
143 Textblock *textblock = (Textblock*)getWidget();
144 int index1 = index, index2 = index;
145
146 if (textblock->hlStart[layer].index > textblock->hlEnd[layer].index)
147 return;
148
149 int oldStartIndex = textblock->hlStart[layer].index;
150 int oldStartChar = textblock->hlStart[layer].nChar;
151 int oldEndIndex = textblock->hlEnd[layer].index;
152 int oldEndChar = textblock->hlEnd[layer].nChar;
153
154 if (direction == 0) {
155 index1 = textblock->hlStart[layer].index;
156 index2 = textblock->hlEnd[layer].index;
157 textblock->hlStart[layer].index = 1;
158 textblock->hlEnd[layer].index = 0;
159 } else if (direction > 0 && textblock->hlStart[layer].index <= index) {
160 index1 = textblock->hlStart[layer].index;
161 textblock->hlStart[layer].index = index + 1;
162 textblock->hlStart[layer].nChar = 0;
163 } else if (direction < 0 && textblock->hlEnd[layer].index >= index) {
164 index1 = textblock->hlEnd[layer].index;
165 textblock->hlEnd[layer].index = index - 1;
166 textblock->hlEnd[layer].nChar = INT_MAX;
167 }
168
169 if (oldStartIndex != textblock->hlStart[layer].index ||
170 oldStartChar != textblock->hlStart[layer].nChar ||
171 oldEndIndex != textblock->hlEnd[layer].index ||
172 oldEndChar != textblock->hlEnd[layer].nChar)
173 textblock->queueDrawRange (index1, index2);
174 }
175
176 void Textblock::TextblockIterator::getAllocation (int start, int end,
177 core::Allocation *allocation)
178 {
179 Textblock *textblock = (Textblock*)getWidget();
180 int lineIndex = textblock->findLineOfWord (index);
181 Line *line = textblock->lines->getRef (lineIndex);
182 Word *word = textblock->words->getRef (index);
183
184 allocation->x =
185 textblock->allocation.x + textblock->lineXOffsetWidget (line);
186
187 for (int i = line->firstWord; i < index; i++) {
188 Word *w = textblock->words->getRef(i);
189 allocation->x += w->size.width + w->effSpace;
190 }
191 if (start > 0 && word->content.type == core::Content::TEXT) {
192 allocation->x += textblock->textWidth (word->content.text, 0, start,
193 word->style,
194 word->flags & Word::WORD_START,
195 (word->flags & Word::WORD_END)
196 && word->content.text[start] == 0);
197 }
198 allocation->y = textblock->lineYOffsetCanvas (line) + line->boxAscent -
199 word->size.ascent;
200
201 allocation->width = word->size.width;
202 if (word->content.type == core::Content::TEXT) {
203 int wordEnd = strlen(word->content.text);
204
205 if (start > 0 || end < wordEnd) {
206 end = misc::min(end, wordEnd); /* end could be INT_MAX */
207 allocation->width =
208 textblock->textWidth (word->content.text, start, end - start,
209 word->style,
210 (word->flags & Word::WORD_START)
211 && start == 0,
212 (word->flags & Word::WORD_END)
213 && word->content.text[end] == 0);
214 }
215 }
216 allocation->ascent = word->size.ascent;
217 allocation->descent = word->size.descent;
218 }
219
220 } // namespace dw
0 /*
1 * Dillo Widget
2 *
3 * Copyright 2005-2007, 2012-2013 Sebastian Geerken <sgeerken@dillo.org>
4 *
5 * (Parts of this file were originally part of textblock.cc.)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21
22 #include "textblock.hh"
23 #include "hyphenator.hh"
24 #include "../lout/msg.h"
25 #include "../lout/misc.hh"
26
27 #include <stdio.h>
28 #include <math.h>
29
30 using namespace lout;
31
32 namespace dw {
33
34 int Textblock::BadnessAndPenalty::badnessValue (int infLevel)
35 {
36 switch (badnessState) {
37 case NOT_STRETCHABLE:
38 return infLevel == INF_NOT_STRETCHABLE ? 1 : 0;
39
40 case QUITE_LOOSE:
41 return infLevel == INF_LARGE ? 1 : 0;
42
43 case BADNESS_VALUE:
44 return infLevel == INF_VALUE ? badness : 0;
45
46 case TOO_TIGHT:
47 return infLevel == INF_TOO_TIGHT ? 1 : 0;
48 }
49
50 // compiler happiness
51 lout::misc::assertNotReached ();
52 return 0;
53 }
54
55 int Textblock::BadnessAndPenalty::penaltyValue (int index, int infLevel)
56 {
57 if (penalty[index] == INT_MIN)
58 return infLevel == INF_PENALTIES ? -1 : 0;
59 else if (penalty[index] == INT_MAX)
60 return infLevel == INF_PENALTIES ? 1 : 0;
61 else
62 return infLevel == INF_VALUE ? penalty[index] : 0;
63 }
64
65 void Textblock::BadnessAndPenalty::calcBadness (int totalWidth, int idealWidth,
66 int totalStretchability,
67 int totalShrinkability)
68 {
69 #ifdef DEBUG
70 this->totalWidth = totalWidth;
71 this->idealWidth = idealWidth;
72 this->totalStretchability = totalStretchability;
73 this->totalShrinkability = totalShrinkability;
74 #endif
75
76 ratio = 0; // because this is used in print()
77
78 if (totalWidth == idealWidth) {
79 badnessState = BADNESS_VALUE;
80 badness = 0;
81 } else if (totalWidth < idealWidth) {
82 if (totalStretchability == 0)
83 badnessState = NOT_STRETCHABLE;
84 else {
85 ratio = 100 * (idealWidth - totalWidth) / totalStretchability;
86 if (ratio > 1024)
87 badnessState = QUITE_LOOSE;
88 else {
89 badnessState = BADNESS_VALUE;
90 badness = ratio * ratio * ratio;
91 }
92 }
93 } else { // if (word->totalWidth > availWidth)
94 if (totalShrinkability == 0)
95 badnessState = TOO_TIGHT;
96 else {
97 // ratio is negative here
98 ratio = 100 * (idealWidth - totalWidth) / totalShrinkability;
99 if (ratio <= - 100)
100 badnessState = TOO_TIGHT;
101 else {
102 badnessState = BADNESS_VALUE;
103 badness = - ratio * ratio * ratio;
104 }
105 }
106 }
107 }
108
109 /**
110 * Sets the penalty, multiplied by 100. Multiplication is necessary
111 * to deal with fractional numbers, without having to use floating
112 * point numbers. So, to set a penalty to 0.5, pass 50.
113 *
114 * INT_MAX and INT_MIN (representing inf and -inf, respectively) are
115 * also allowed.
116 *
117 * The definition of penalties depends on the definition of badness,
118 * which adheres to the description in \ref dw-line-breaking, section
119 * "Criteria for Line-Breaking". The exact calculation may vary, but
120 * this definition of should be rather stable: (i)&nbsp;A perfectly
121 * fitting line has a badness of 0. (ii)&nbsp;A line, where all spaces
122 * are extended by exactly the stretchability, as well as a line, where
123 * all spaces are reduced by the shrinkability, have a badness of 1.
124 *
125 * (TODO plural: penalties, not penalty. Correct above comment)
126 */
127 void Textblock::BadnessAndPenalty::setPenalties (int penalty1, int penalty2)
128 {
129 // TODO Check here some cases, e.g. both or no penalty INT_MIN.
130 setSinglePenalty(0, penalty1);
131 setSinglePenalty(1, penalty2);
132 }
133
134 void Textblock::BadnessAndPenalty::setSinglePenalty (int index, int penalty)
135 {
136 if (penalty == INT_MAX || penalty == INT_MIN)
137 this->penalty[index] = penalty;
138 else
139 // This factor consists of: (i) 100^3, since in calcBadness(), the
140 // ratio is multiplied with 100 (again, to use integer numbers for
141 // fractional numbers), and the badness (which has to be compared
142 // to the penalty!) is the third power or it; (ii) the denominator
143 // 100, of course, since 100 times the penalty is passed to this
144 // method.
145 this->penalty[index] = penalty * (100 * 100 * 100 / 100);
146 }
147
148 bool Textblock::BadnessAndPenalty::lineLoose ()
149 {
150 return
151 badnessState == NOT_STRETCHABLE || badnessState == QUITE_LOOSE ||
152 (badnessState == BADNESS_VALUE && ratio > 0);
153 }
154
155 bool Textblock::BadnessAndPenalty::lineTight ()
156 {
157 return
158 badnessState == TOO_TIGHT || (badnessState == BADNESS_VALUE && ratio < 0);
159 }
160
161 bool Textblock::BadnessAndPenalty::lineTooTight ()
162 {
163 return badnessState == TOO_TIGHT;
164 }
165
166
167 bool Textblock::BadnessAndPenalty::lineMustBeBroken (int penaltyIndex)
168 {
169 return penalty[penaltyIndex] == PENALTY_FORCE_BREAK;
170 }
171
172 bool Textblock::BadnessAndPenalty::lineCanBeBroken (int penaltyIndex)
173 {
174 return penalty[penaltyIndex] != PENALTY_PROHIBIT_BREAK;
175 }
176
177 int Textblock::BadnessAndPenalty::compareTo (int penaltyIndex,
178 BadnessAndPenalty *other)
179 {
180 for (int l = INF_MAX; l >= 0; l--) {
181 int thisValue = badnessValue (l) + penaltyValue (penaltyIndex, l);
182 int otherValue =
183 other->badnessValue (l) + other->penaltyValue (penaltyIndex, l);
184
185 if (thisValue != otherValue)
186 return thisValue - otherValue;
187 }
188
189 return 0;
190 }
191
192 void Textblock::BadnessAndPenalty::print ()
193 {
194 switch (badnessState) {
195 case NOT_STRETCHABLE:
196 printf ("not stretchable");
197 break;
198
199 case TOO_TIGHT:
200 printf ("too tight");
201 break;
202
203 case QUITE_LOOSE:
204 printf ("quite loose (ratio = %d)", ratio);
205 break;
206
207 case BADNESS_VALUE:
208 printf ("%d", badness);
209 break;
210 }
211
212 #ifdef DEBUG
213 printf (" [%d + %d - %d vs. %d]",
214 totalWidth, totalStretchability, totalShrinkability, idealWidth);
215 #endif
216
217 printf (" + (");
218 for (int i = 0; i < 2; i++) {
219 if (penalty[i] == INT_MIN)
220 printf ("-inf");
221 else if (penalty[i] == INT_MAX)
222 printf ("inf");
223 else
224 printf ("%d", penalty[i]);
225
226 if (i == 0)
227 printf (", ");
228 }
229 printf (")");
230 }
231
232 void Textblock::printWordShort (Word *word)
233 {
234 switch(word->content.type) {
235 case core::Content::TEXT:
236 printf ("\"%s\"", word->content.text);
237 break;
238 case core::Content::WIDGET:
239 printf ("<widget: %p (%s)>",
240 word->content.widget, word->content.widget->getClassName());
241 break;
242 case core::Content::BREAK:
243 printf ("<break>");
244 break;
245 default:
246 printf ("<?>");
247 break;
248 }
249 }
250
251 void Textblock::printWordFlags (short flags)
252 {
253 printf ("%s:%s:%s:%s:%s:%s:%s",
254 (flags & Word::CAN_BE_HYPHENATED) ? "h?" : "--",
255 (flags & Word::DIV_CHAR_AT_EOL) ? "de" : "--",
256 (flags & Word::PERM_DIV_CHAR) ? "dp" : "--",
257 (flags & Word::DRAW_AS_ONE_TEXT) ? "t1" : "--",
258 (flags & Word::UNBREAKABLE_FOR_MIN_WIDTH) ? "um" : "--",
259 (flags & Word::WORD_START) ? "st" : "--",
260 (flags & Word::WORD_END) ? "en" : "--");
261 }
262
263 void Textblock::printWordWithFlags (Word *word)
264 {
265 printWordShort (word);
266 printf (" (flags = ");
267 printWordFlags (word->flags);
268 printf (")");
269 }
270
271 void Textblock::printWord (Word *word)
272 {
273 printWordWithFlags (word);
274
275 printf (" [%d / %d + %d - %d => %d + %d - %d] => ",
276 word->size.width, word->origSpace, getStretchability(word),
277 getShrinkability(word), word->totalWidth, word->totalStretchability,
278 word->totalShrinkability);
279 word->badnessAndPenalty.print ();
280 }
281
282 /*
283 * ...
284 *
285 * diff ...
286 */
287 void Textblock::justifyLine (Line *line, int diff)
288 {
289 /* To avoid rounding errors, the calculation is based on accumulated
290 * values. */
291
292 if (diff > 0) {
293 int stretchabilitySum = 0;
294 for (int i = line->firstWord; i < line->lastWord; i++)
295 stretchabilitySum += getStretchability(words->getRef(i));
296
297 if (stretchabilitySum > 0) {
298 int stretchabilityCum = 0;
299 int spaceDiffCum = 0;
300 for (int i = line->firstWord; i < line->lastWord; i++) {
301 Word *word = words->getRef (i);
302 stretchabilityCum += getStretchability(word);
303 int spaceDiff =
304 stretchabilityCum * diff / stretchabilitySum - spaceDiffCum;
305 spaceDiffCum += spaceDiff;
306
307 PRINTF (" %d (of %d): diff = %d\n", i, words->size (),
308 spaceDiff);
309
310 word->effSpace = word->origSpace + spaceDiff;
311 }
312 }
313 } else if (diff < 0) {
314 int shrinkabilitySum = 0;
315 for (int i = line->firstWord; i < line->lastWord; i++)
316 shrinkabilitySum += getShrinkability(words->getRef(i));
317
318 if (shrinkabilitySum > 0) {
319 int shrinkabilityCum = 0;
320 int spaceDiffCum = 0;
321 for (int i = line->firstWord; i < line->lastWord; i++) {
322 Word *word = words->getRef (i);
323 shrinkabilityCum += getShrinkability(word);
324 int spaceDiff =
325 shrinkabilityCum * diff / shrinkabilitySum - spaceDiffCum;
326 spaceDiffCum += spaceDiff;
327
328 word->effSpace = word->origSpace + spaceDiff;
329 }
330 }
331 }
332 }
333
334
335 Textblock::Line *Textblock::addLine (int firstWord, int lastWord,
336 bool temporary)
337 {
338 PRINTF ("[%p] ADD_LINE (%d, %d) => %d\n",
339 this, firstWord, lastWord, lines->size ());
340
341 Word *lastWordOfLine = words->getRef(lastWord);
342 // Word::totalWidth includes the hyphen (which is what we want here).
343 int lineWidth = lastWordOfLine->totalWidth;
344 // "lineWidth" is relative to leftOffset, so we may have to add
345 // "line1OffsetEff" (remember: this is, for list items, negative).
346 if (lines->size () == 0)
347 lineWidth += line1OffsetEff;
348
349 int maxOfMinWidth, sumOfMaxWidth;
350 accumulateWordExtremes (firstWord, lastWord, &maxOfMinWidth,
351 &sumOfMaxWidth);
352
353 PRINTF (" words[%d]->totalWidth = %d\n", lastWord,
354 lastWordOfLine->totalWidth);
355
356 PRINTF ("[%p] ##### LINE ADDED: %d, from %d to %d #####\n",
357 this, lines->size (), firstWord, lastWord);
358
359 lines->increase ();
360 if(!temporary) {
361 // If the last line was temporary, this will be temporary, too, even
362 // if not requested.
363 if (lines->size () == 1 || nonTemporaryLines == lines->size () -1)
364 nonTemporaryLines = lines->size ();
365 }
366
367 PRINTF ("nonTemporaryLines = %d\n", nonTemporaryLines);
368
369 int lineIndex = lines->size () - 1;
370 Line *line = lines->getRef (lineIndex);
371
372 line->firstWord = firstWord;
373 line->lastWord = lastWord;
374 line->boxAscent = line->contentAscent = 0;
375 line->boxDescent = line->contentDescent = 0;
376 line->marginDescent = 0;
377 line->breakSpace = 0;
378 line->leftOffset = 0;
379
380 alignLine (lineIndex);
381 for (int i = line->firstWord; i < line->lastWord; i++) {
382 Word *word = words->getRef (i);
383 lineWidth += (word->effSpace - word->origSpace);
384 }
385
386 if (lines->size () == 1) {
387 // first line
388 line->top = 0;
389 line->maxLineWidth = lineWidth;
390 } else {
391 Line *prevLine = lines->getRef (lines->size () - 2);
392 line->top = prevLine->top + prevLine->boxAscent +
393 prevLine->boxDescent + prevLine->breakSpace;
394 line->maxLineWidth = misc::max (lineWidth, prevLine->maxLineWidth);
395 }
396
397 for(int i = line->firstWord; i <= line->lastWord; i++)
398 accumulateWordForLine (lineIndex, i);
399
400 PRINTF (" line[%d].top = %d\n", lines->size () - 1, line->top);
401 PRINTF (" line[%d].boxAscent = %d\n", lines->size () - 1, line->boxAscent);
402 PRINTF (" line[%d].boxDescent = %d\n",
403 lines->size () - 1, line->boxDescent);
404 PRINTF (" line[%d].contentAscent = %d\n", lines->size () - 1,
405 line->contentAscent);
406 PRINTF (" line[%d].contentDescent = %d\n",
407 lines->size () - 1, line->contentDescent);
408
409 PRINTF (" line[%d].maxLineWidth = %d\n",
410 lines->size () - 1, line->maxLineWidth);
411
412 mustQueueResize = true;
413
414 //printWordShort (words->getRef (line->firstWord));
415 //printf (" ... ");
416 //printWordShort (words->getRef (line->lastWord));
417 //printf (": ");
418 //words->getRef(line->lastWord)->badnessAndPenalty.print ();
419 //printf ("\n");
420
421 return line;
422 }
423
424 void Textblock::accumulateWordExtremes (int firstWord, int lastWord,
425 int *maxOfMinWidth, int *sumOfMaxWidth)
426 {
427 int parMin = 0;
428 *maxOfMinWidth = *sumOfMaxWidth = 0;
429
430 for (int i = firstWord; i <= lastWord; i++) {
431 Word *word = words->getRef (i);
432 bool atLastWord = i == lastWord;
433
434 core::Extremes extremes;
435 getWordExtremes (word, &extremes);
436
437 // Minimum: between two *possible* breaks (or at the end).
438 // TODO This is redundant to getExtremesImpl().
439 // TODO: Again, index 1 is used for lineCanBeBroken(). See getExtremes().
440 if (word->badnessAndPenalty.lineCanBeBroken (1) || atLastWord) {
441 parMin += extremes.minWidth + word->hyphenWidth;
442 *maxOfMinWidth = misc::max (*maxOfMinWidth, parMin);
443 parMin = 0;
444 } else
445 // Shrinkability could be considered, but really does not play a
446 // role.
447 parMin += extremes.minWidth + word->origSpace;
448
449 //printf ("[%p] after word: ", this);
450 //printWord (word);
451 //printf ("\n");
452
453 //printf ("[%p] (%d / %d) => parMin = %d, maxOfMinWidth = %d\n",
454 // this, extremes.minWidth, extremes.maxWidth, parMin,
455 // *maxOfMinWidth);
456
457 *sumOfMaxWidth += (extremes.maxWidth + word->origSpace);
458 // Notice that the last space is added. See also: Line::parMax.
459 }
460 }
461
462 void Textblock::processWord (int wordIndex)
463 {
464 wordWrap (wordIndex, false);
465 handleWordExtremes (wordIndex);
466 }
467
468 /*
469 * This method is called in two cases: (i) when a word is added
470 * (ii) when a page has to be (partially) rewrapped. It does word wrap,
471 * and adds new lines if necessary.
472 */
473 void Textblock::wordWrap (int wordIndex, bool wrapAll)
474 {
475 PRINTF ("[%p] WORD_WRAP (%d, %s)\n",
476 this, wordIndex, wrapAll ? "true" : "false");
477
478 Word *word;
479
480 if (!wrapAll)
481 removeTemporaryLines ();
482
483 initLine1Offset (wordIndex);
484
485 word = words->getRef (wordIndex);
486 word->effSpace = word->origSpace;
487
488 accumulateWordData (wordIndex);
489
490 //printf (" ");
491 //printWord (word);
492 //printf ("\n");
493
494 int penaltyIndex = calcPenaltyIndexForNewLine ();
495
496 bool newLine;
497 do {
498 bool tempNewLine = false;
499 int firstIndex =
500 lines->size() == 0 ? 0 : lines->getLastRef()->lastWord + 1;
501 int searchUntil;
502
503 if (wrapAll && wordIndex >= firstIndex && wordIndex == words->size() -1) {
504 newLine = true;
505 searchUntil = wordIndex;
506 tempNewLine = true;
507 PRINTF (" NEW LINE: last word\n");
508 } else if (wordIndex >= firstIndex &&
509 // TODO: lineMustBeBroken should be independent of
510 // the penalty index?
511 word->badnessAndPenalty.lineMustBeBroken (penaltyIndex)) {
512 newLine = true;
513 searchUntil = wordIndex;
514 PRINTF (" NEW LINE: forced break\n");
515 } else {
516 // Break the line when too tight, but only when there is a
517 // possible break point so far. (TODO: I've forgotten the
518 // original bug which is fixed by this.)
519 bool possibleLineBreak = false;
520 for (int i = firstIndex; !possibleLineBreak && i <= wordIndex - 1; i++)
521 if (words->getRef(i)->badnessAndPenalty
522 .lineCanBeBroken (penaltyIndex))
523 possibleLineBreak = true;
524
525 if (possibleLineBreak && word->badnessAndPenalty.lineTooTight ()) {
526 newLine = true;
527 searchUntil = wordIndex - 1;
528 PRINTF (" NEW LINE: line too tight\n");
529 } else
530 newLine = false;
531 }
532
533 if(!newLine && !wrapAll)
534 // No new line is added. "mustQueueResize" must,
535 // nevertheless, be set, so that flush() will call
536 // queueResize(), and later sizeRequestImpl() is called,
537 // which then calls showMissingLines(), which eventually
538 // calls this method again, with wrapAll == true, so that
539 // newLine is calculated as "true".
540 mustQueueResize = true;
541
542 if(newLine) {
543 accumulateWordData (wordIndex);
544 int wordIndexEnd = wordIndex;
545
546 bool lineAdded;
547 do {
548 PRINTF (" searching from %d to %d\n", firstIndex, searchUntil);
549
550 int breakPos = -1;
551 for (int i = firstIndex; i <= searchUntil; i++) {
552 Word *w = words->getRef(i);
553
554 //printf (" %d (of %d): ", i, words->size ());
555 //printWord (w);
556 //printf ("\n");
557
558 if (breakPos == -1 ||
559 w->badnessAndPenalty.compareTo
560 (penaltyIndex,
561 &words->getRef(breakPos)->badnessAndPenalty) <= 0)
562 // "<=" instead of "<" in the next lines tends to result in
563 // more words per line -- theoretically. Practically, the
564 // case "==" will never occur.
565 breakPos = i;
566 }
567
568 PRINTF (" breakPos = %d\n", breakPos);
569
570 if (wrapAll && searchUntil == words->size () - 1) {
571 // Since no break and no space is added, the last word
572 // will have a penalty of inf. Actually, it should be
573 // less, since it is the last word. However, since more
574 // words may follow, the penalty is not changesd, but
575 // here, the search is corrected (maybe only
576 // temporary).
577
578 // (Notice that it was once (temporally) set to -inf,
579 // not 0, but this will make e.g. test/table-1.html not
580 // work.)
581 Word *lastWord = words->getRef (searchUntil);
582 BadnessAndPenalty correctedBap = lastWord->badnessAndPenalty;
583 correctedBap.setPenalty (0);
584 if (correctedBap.compareTo
585 (penaltyIndex,
586 &words->getRef(breakPos)->badnessAndPenalty) <= 0) {
587 breakPos = searchUntil;
588 PRINTF (" corrected: breakPos = %d\n", breakPos);
589 }
590 }
591
592 int hyphenatedWord = -1;
593 Word *word1 = words->getRef(breakPos);
594 PRINTF ("[%p] line (broken at word %d): ", this, breakPos);
595 //word1->badnessAndPenalty.print ();
596 PRINTF ("\n");
597
598 if (word1->badnessAndPenalty.lineTight () &&
599 (word1->flags & Word::CAN_BE_HYPHENATED) &&
600 word1->style->x_lang[0] &&
601 word1->content.type == core::Content::TEXT &&
602 Hyphenator::isHyphenationCandidate (word1->content.text))
603 hyphenatedWord = breakPos;
604
605 if (word1->badnessAndPenalty.lineLoose () &&
606 breakPos + 1 < words->size ()) {
607 Word *word2 = words->getRef(breakPos + 1);
608 if ((word2->flags & Word::CAN_BE_HYPHENATED) &&
609 word2->style->x_lang[0] &&
610 word2->content.type == core::Content::TEXT &&
611 Hyphenator::isHyphenationCandidate (word2->content.text))
612 hyphenatedWord = breakPos + 1;
613 }
614
615 PRINTF ("[%p] breakPos = %d, hyphenatedWord = %d\n",
616 this, breakPos, hyphenatedWord);
617
618 if(hyphenatedWord == -1) {
619 addLine (firstIndex, breakPos, tempNewLine);
620 PRINTF ("[%p] new line %d (%s), from %d to %d\n",
621 this, lines->size() - 1,
622 tempNewLine ? "temporally" : "permanently",
623 firstIndex, breakPos);
624 lineAdded = true;
625 penaltyIndex = calcPenaltyIndexForNewLine ();
626 } else {
627 // TODO hyphenateWord() should return whether something has
628 // changed at all. So that a second run, with
629 // !word->canBeHyphenated, is unnecessary.
630 // TODO Update: for this, searchUntil == 0 should be checked.
631 PRINTF ("[%p] old searchUntil = %d ...\n", this, searchUntil);
632 int n = hyphenateWord (hyphenatedWord);
633 searchUntil += n;
634 if (hyphenatedWord <= wordIndex)
635 wordIndexEnd += n;
636 PRINTF ("[%p] -> new searchUntil = %d ...\n", this, searchUntil);
637 lineAdded = false;
638
639 // update word pointer as hyphenateWord() can trigger a
640 // reorganization of the words structure
641 word = words->getRef (wordIndex);
642 }
643
644 PRINTF ("[%p] accumulating again from %d to %d\n",
645 this, breakPos + 1, wordIndexEnd);
646 for(int i = breakPos + 1; i <= wordIndexEnd; i++)
647 accumulateWordData (i);
648
649 } while(!lineAdded);
650 }
651 } while (newLine);
652
653 if(word->content.type == core::Content::WIDGET) {
654 // Set parentRef for the child, when necessary.
655 //
656 // parentRef is set for the child already, when a line is
657 // added. There are a couple of different situations to
658 // consider, e.g. when called from showMissingLines(), this word
659 // may already have been added in a previous call. To make
660 // things simple, we just check whether this word is contained
661 // within any line, or still "missing".
662
663 int firstWordWithoutLine;
664 if (lines->size() == 0)
665 firstWordWithoutLine = 0;
666 else
667 firstWordWithoutLine = lines->getLastRef()->lastWord + 1;
668
669 if (wordIndex >= firstWordWithoutLine) {
670 word->content.widget->parentRef = lines->size ();
671 PRINTF ("The %s %p is assigned parentRef = %d.\n",
672 word->content.widget->getClassName(), word->content.widget,
673 word->content.widget->parentRef);
674 }
675 }
676 }
677
678 /**
679 * Counter part to wordWrap(), but for extremes, not size calculation.
680 */
681 void Textblock::handleWordExtremes (int wordIndex)
682 {
683 // TODO Overall, clarify penalty index.
684
685 Word *word = words->getRef (wordIndex);
686 core::Extremes wordExtremes;
687 getWordExtremes (word, &wordExtremes);
688
689 //printf ("[%p] HANDLE_WORD_EXTREMES (%d): ", this, wordIndex);
690 //printWordWithFlags (word);
691 //printf (" => %d / %d\n", wordExtremes.minWidth, wordExtremes.maxWidth);
692
693 if (wordIndex == 0) {
694 wordExtremes.minWidth += line1Offset;
695 wordExtremes.maxWidth += line1Offset;
696 }
697
698 if (paragraphs->size() == 0 ||
699 words->getRef(paragraphs->getLastRef()->lastWord)
700 ->badnessAndPenalty.lineMustBeBroken (1)) {
701 // Add a new paragraph.
702 paragraphs->increase ();
703 Paragraph *prevPar = paragraphs->size() == 1 ?
704 NULL : paragraphs->getRef(paragraphs->size() - 2);
705 Paragraph *par = paragraphs->getLastRef();
706
707 par->firstWord = par->lastWord = wordIndex;
708 par->parMin = par->parMax = 0;
709
710 if (prevPar) {
711 par->maxParMin = prevPar->maxParMin;
712 par->maxParMax = prevPar->maxParMax;
713 } else
714 par->maxParMin = par->maxParMax = 0;
715
716 PRINTF (" new par: %d\n", paragraphs->size() - 1);
717 }
718
719 PRINTF (" last par: %d\n", paragraphs->size() - 1);
720 Paragraph *lastPar = paragraphs->getLastRef();
721
722 int corrDiffMin, corrDiffMax;
723 if (wordIndex - 1 >= lastPar->firstWord) {
724 Word *lastWord = words->getRef (wordIndex - 1);
725 if (lastWord->badnessAndPenalty.lineCanBeBroken (1) &&
726 (lastWord->flags & Word::UNBREAKABLE_FOR_MIN_WIDTH) == 0)
727 corrDiffMin = 0;
728 else
729 corrDiffMin = lastWord->origSpace - lastWord->hyphenWidth;
730
731 corrDiffMax = lastWord->origSpace - lastWord->hyphenWidth;
732 } else
733 corrDiffMin = corrDiffMax = 0;
734
735 PRINTF (" (lastPar from %d to %d; corrDiffMin = %d, corDiffMax = %d)\n",
736 lastPar->firstWord, lastPar->lastWord, corrDiffMin, corrDiffMax);
737
738 // Minimum: between two *possible* breaks.
739 // Shrinkability could be considered, but really does not play a role.
740 lastPar->parMin += wordExtremes.minWidth + word->hyphenWidth + corrDiffMin;
741 lastPar->maxParMin = misc::max (lastPar->maxParMin, lastPar->parMin);
742 if (word->badnessAndPenalty.lineCanBeBroken (1) &&
743 (word->flags & Word::UNBREAKABLE_FOR_MIN_WIDTH) == 0)
744 lastPar->parMin = 0;
745
746 // Maximum: between two *necessary* breaks.
747 lastPar->parMax += wordExtremes.maxWidth + word->hyphenWidth + corrDiffMax;
748 lastPar->maxParMax = misc::max (lastPar->maxParMax, lastPar->parMax);
749
750 PRINTF (" => parMin = %d (max = %d), parMax = %d (max = %d)\n",
751 lastPar->parMin, lastPar->maxParMin, lastPar->parMax,
752 lastPar->maxParMax);
753
754 lastPar->lastWord = wordIndex;
755 }
756
757 /**
758 * Called when something changed for the last word (space, hyphens etc.).
759 */
760 void Textblock::correctLastWordExtremes ()
761 {
762 if (paragraphs->size() > 0) {
763 Word *word = words->getLastRef ();
764 if (word->badnessAndPenalty.lineCanBeBroken (1) &&
765 (word->flags & Word::UNBREAKABLE_FOR_MIN_WIDTH) == 0) {
766 paragraphs->getLastRef()->parMin = 0;
767 PRINTF (" => corrected; parMin = %d\n",
768 paragraphs->getLastRef()->parMin);
769 }
770 }
771 }
772
773
774 int Textblock::hyphenateWord (int wordIndex)
775 {
776 Word *hyphenatedWord = words->getRef(wordIndex);
777 char lang[3] = { hyphenatedWord->style->x_lang[0],
778 hyphenatedWord->style->x_lang[1], 0 };
779 Hyphenator *hyphenator = Hyphenator::getHyphenator (lang);
780 PRINTF ("[%p] considering to hyphenate word %d, '%s', in language '%s'\n",
781 this, wordIndex, words->getRef(wordIndex)->content.text, lang);
782 int numBreaks;
783 int *breakPos =
784 hyphenator->hyphenateWord (layout->getPlatform (),
785 hyphenatedWord->content.text, &numBreaks);
786
787 if (numBreaks > 0) {
788 Word origWord = *hyphenatedWord;
789
790 core::Requisition wordSize[numBreaks + 1];
791 calcTextSizes (origWord.content.text, strlen (origWord.content.text),
792 origWord.style, numBreaks, breakPos, wordSize);
793
794 PRINTF ("[%p] %d words ...\n", this, words->size ());
795 words->insert (wordIndex, numBreaks);
796 PRINTF ("[%p] ... => %d words\n", this, words->size ());
797
798 // Adjust anchor indexes.
799 for (int i = 0; i < anchors->size (); i++) {
800 Anchor *anchor = anchors->getRef (i);
801 if (anchor->wordIndex > wordIndex)
802 anchor->wordIndex += numBreaks;
803 }
804
805 for (int i = 0; i < numBreaks + 1; i++) {
806 Word *w = words->getRef (wordIndex + i);
807
808 fillWord (w, wordSize[i].width, wordSize[i].ascent,
809 wordSize[i].descent, false, origWord.style);
810
811 // TODO There should be a method fillText0.
812 w->content.type = core::Content::TEXT;
813
814 int start = (i == 0 ? 0 : breakPos[i - 1]);
815 int end = (i == numBreaks ?
816 strlen (origWord.content.text) : breakPos[i]);
817 w->content.text =
818 layout->textZone->strndup (origWord.content.text + start,
819 end - start);
820 PRINTF (" [%d] -> '%s'\n", wordIndex + i, w->content.text);
821
822 // Note: there are numBreaks + 1 word parts.
823 if (i == 0)
824 w->flags |= Word::WORD_START;
825 else
826 w->flags &= ~Word::WORD_START;
827
828 if (i == numBreaks)
829 w->flags |= Word::WORD_END;
830 else
831 w->flags &= ~Word::WORD_END;
832
833 if (i < numBreaks) {
834 // TODO There should be a method fillHyphen.
835 w->badnessAndPenalty.setPenalties (penalties[PENALTY_HYPHEN][0],
836 penalties[PENALTY_HYPHEN][1]);
837 // "\xe2\x80\x90" is an unconditional hyphen.
838 w->hyphenWidth =
839 layout->textWidth (w->style->font, hyphenDrawChar,
840 strlen (hyphenDrawChar));
841 w->flags |= (Word::DRAW_AS_ONE_TEXT | Word::DIV_CHAR_AT_EOL |
842 Word::UNBREAKABLE_FOR_MIN_WIDTH);
843
844 PRINTF (" [%d] + hyphen\n", wordIndex + i);
845 } else {
846 if (origWord.content.space) {
847 fillSpace (w, origWord.spaceStyle);
848 PRINTF (" [%d] + space\n", wordIndex + i);
849 } else {
850 PRINTF (" [%d] + nothing\n", wordIndex + i);
851 }
852 }
853
854 accumulateWordData (wordIndex + i);
855
856 //printf ("[%p] %d: hyphenated word part: ", this, wordIndex + i);
857 //printWordWithFlags (w);
858 //printf ("\n");
859 }
860
861 PRINTF (" finished\n");
862
863 //delete origword->content.text; TODO: Via textZone?
864 origWord.style->unref ();
865 origWord.spaceStyle->unref ();
866
867 free (breakPos);
868 } else
869 words->getRef(wordIndex)->flags &= ~Word::CAN_BE_HYPHENATED;
870
871 return numBreaks;
872 }
873
874 void Textblock::accumulateWordForLine (int lineIndex, int wordIndex)
875 {
876 Line *line = lines->getRef (lineIndex);
877 Word *word = words->getRef (wordIndex);
878
879 PRINTF (" %d + %d / %d + %d\n", line->boxAscent, line->boxDescent,
880 word->size.ascent, word->size.descent);
881
882 line->boxAscent = misc::max (line->boxAscent, word->size.ascent);
883 line->boxDescent = misc::max (line->boxDescent, word->size.descent);
884
885 int len = word->style->font->ascent;
886 if (word->style->valign == core::style::VALIGN_SUPER)
887 len += len / 2;
888 line->contentAscent = misc::max (line->contentAscent, len);
889
890 len = word->style->font->descent;
891 if (word->style->valign == core::style::VALIGN_SUB)
892 len += word->style->font->ascent / 3;
893 line->contentDescent = misc::max (line->contentDescent, len);
894
895 if (word->content.type == core::Content::WIDGET) {
896 int collapseMarginTop = 0;
897
898 line->marginDescent =
899 misc::max (line->marginDescent,
900 word->size.descent +
901 word->content.widget->getStyle()->margin.bottom);
902
903 if (lines->size () == 1 &&
904 word->content.widget->blockLevel () &&
905 getStyle ()->borderWidth.top == 0 &&
906 getStyle ()->padding.top == 0) {
907 // collapse top margins of parent element and its first child
908 // see: http://www.w3.org/TR/CSS21/box.html#collapsing-margins
909 collapseMarginTop = getStyle ()->margin.top;
910 }
911
912 line->boxAscent =
913 misc::max (line->boxAscent,
914 word->size.ascent,
915 word->size.ascent
916 + word->content.widget->getStyle()->margin.top
917 - collapseMarginTop);
918
919 word->content.widget->parentRef = lineIndex;
920 } else {
921 line->marginDescent =
922 misc::max (line->marginDescent, line->boxDescent);
923
924 if (word->content.type == core::Content::BREAK)
925 line->breakSpace =
926 misc::max (word->content.breakSpace,
927 line->marginDescent - line->boxDescent,
928 line->breakSpace);
929 }
930 }
931
932 void Textblock::accumulateWordData (int wordIndex)
933 {
934 // Typically, the word in question is in the last line; in any case
935 // quite at the end of the text, so that linear search is actually
936 // the fastest option.
937 int lineIndex = lines->size ();
938 while (lineIndex > 0 && wordIndex <= lines->getRef(lineIndex - 1)->lastWord)
939 lineIndex--;
940
941 int firstWordOfLine;
942 if (lineIndex == 0)
943 firstWordOfLine = 0;
944 else
945 firstWordOfLine = lines->getRef(lineIndex - 1)->lastWord + 1;
946
947 Word *word = words->getRef (wordIndex);
948 PRINTF ("[%p] ACCUMULATE_WORD_DATA (%d); lineIndex = %d: ...\n",
949 this, wordIndex, lineIndex);
950
951 int availWidth = calcAvailWidth (lineIndex);
952
953 PRINTF (" (%s existing line %d starts with word %d)\n",
954 lineIndex < lines->size () ? "already" : "not yet",
955 lineIndex, firstWordOfLine);
956
957 if (wordIndex == firstWordOfLine) {
958 // first word of the (not neccessarily yet existing) line
959 word->totalWidth = word->size.width + word->hyphenWidth;
960 word->totalStretchability = 0;
961 word->totalShrinkability = 0;
962 } else {
963 Word *prevWord = words->getRef (wordIndex - 1);
964
965 word->totalWidth = prevWord->totalWidth
966 + prevWord->origSpace - prevWord->hyphenWidth
967 + word->size.width + word->hyphenWidth;
968 word->totalStretchability =
969 prevWord->totalStretchability + getStretchability(prevWord);
970 word->totalShrinkability =
971 prevWord->totalShrinkability + getShrinkability(prevWord);
972 }
973
974 word->badnessAndPenalty.calcBadness (word->totalWidth, availWidth,
975 word->totalStretchability,
976 word->totalShrinkability);
977
978 //printf (" => ");
979 //printWord (word);
980 //printf ("\n");
981 }
982
983 int Textblock::calcAvailWidth (int lineIndex)
984 {
985 int availWidth =
986 this->availWidth - getStyle()->boxDiffWidth() - innerPadding;
987 if (limitTextWidth &&
988 layout->getUsesViewport () &&
989 availWidth > layout->getWidthViewport () - 10)
990 availWidth = layout->getWidthViewport () - 10;
991 if (lineIndex == 0)
992 availWidth -= line1OffsetEff;
993
994 //PRINTF("[%p] CALC_AVAIL_WIDTH => %d - %d - %d = %d\n",
995 // this, this->availWidth, getStyle()->boxDiffWidth(), innerPadding,
996 // availWidth);
997
998 return availWidth;
999 }
1000
1001 void Textblock::initLine1Offset (int wordIndex)
1002 {
1003 Word *word = words->getRef (wordIndex);
1004
1005 /* Test whether line1Offset can be used. */
1006 if (wordIndex == 0) {
1007 if (ignoreLine1OffsetSometimes &&
1008 line1Offset + word->size.width > availWidth) {
1009 line1OffsetEff = 0;
1010 } else {
1011 int indent = 0;
1012
1013 if (word->content.type == core::Content::WIDGET &&
1014 word->content.widget->blockLevel() == true) {
1015 /* don't use text-indent when nesting blocks */
1016 } else {
1017 if (core::style::isPerLength(getStyle()->textIndent)) {
1018 indent = misc::roundInt(this->availWidth *
1019 core::style::perLengthVal (getStyle()->textIndent));
1020 } else {
1021 indent = core::style::absLengthVal (getStyle()->textIndent);
1022 }
1023 }
1024 line1OffsetEff = line1Offset + indent;
1025 }
1026 }
1027 }
1028
1029 /**
1030 * Align the line.
1031 *
1032 * \todo Use block's style instead once paragraphs become proper blocks.
1033 */
1034 void Textblock::alignLine (int lineIndex)
1035 {
1036 Line *line = lines->getRef (lineIndex);
1037 int availWidth = calcAvailWidth (lineIndex);
1038 Word *firstWord = words->getRef (line->firstWord);
1039 Word *lastWord = words->getRef (line->lastWord);
1040
1041 for (int i = line->firstWord; i < line->lastWord; i++)
1042 words->getRef(i)->origSpace = words->getRef(i)->effSpace;
1043
1044 if (firstWord->content.type != core::Content::BREAK) {
1045 switch (firstWord->style->textAlign) {
1046 case core::style::TEXT_ALIGN_LEFT:
1047 case core::style::TEXT_ALIGN_STRING: /* handled elsewhere (in the
1048 * future)? */
1049 line->leftOffset = 0;
1050 break;
1051 case core::style::TEXT_ALIGN_JUSTIFY: /* see some lines above */
1052 line->leftOffset = 0;
1053 if(lastWord->content.type != core::Content::BREAK &&
1054 line->lastWord != words->size () - 1) {
1055 PRINTF (" justifyLine => %d vs. %d\n",
1056 lastWord->totalWidth, availWidth);
1057 justifyLine (line, availWidth - lastWord->totalWidth);
1058 }
1059 break;
1060 case core::style::TEXT_ALIGN_RIGHT:
1061 line->leftOffset = availWidth - lastWord->totalWidth;
1062 break;
1063 case core::style::TEXT_ALIGN_CENTER:
1064 line->leftOffset = (availWidth - lastWord->totalWidth) / 2;
1065 break;
1066 default:
1067 /* compiler happiness */
1068 line->leftOffset = 0;
1069 }
1070
1071 /* For large lines (images etc), which do not fit into the viewport: */
1072 if (line->leftOffset < 0)
1073 line->leftOffset = 0;
1074 }
1075 }
1076
1077 /**
1078 * Rewrap the page from the line from which this is necessary.
1079 * There are basically two times we'll want to do this:
1080 * either when the viewport is resized, or when the size changes on one
1081 * of the child widgets.
1082 */
1083 void Textblock::rewrap ()
1084 {
1085 PRINTF ("[%p] REWRAP: wrapRef = %d\n", this, wrapRef);
1086
1087 if (wrapRefLines == -1)
1088 /* page does not have to be rewrapped */
1089 return;
1090
1091 /* All lines up from wrapRef will be rebuild from the word list,
1092 * the line list up from this position is rebuild. */
1093 lines->setSize (wrapRefLines);
1094 nonTemporaryLines = misc::min (nonTemporaryLines, wrapRefLines);
1095
1096 int firstWord;
1097 if (lines->size () > 0)
1098 firstWord = lines->getLastRef()->lastWord + 1;
1099 else
1100 firstWord = 0;
1101
1102 for (int i = firstWord; i < words->size (); i++) {
1103 Word *word = words->getRef (i);
1104
1105 if (word->content.type == core::Content::WIDGET)
1106 calcWidgetSize (word->content.widget, &word->size);
1107
1108 wordWrap (i, false);
1109
1110 // Somewhat historical, but still important, note:
1111 //
1112 // For the case that something else is done with this word, it
1113 // is important that wordWrap() may insert some new words; since
1114 // NotSoSimpleVector is used for the words list, the internal
1115 // structure may have changed, so getRef() must be called again.
1116 //
1117 // So this is necessary: word = words->getRef (i);
1118 }
1119
1120 /* Next time, the page will not have to be rewrapped. */
1121 wrapRefLines = -1;
1122 }
1123
1124 /**
1125 * Counter part to rewrap(), but for extremes, not size calculation.
1126 */
1127 void Textblock::fillParagraphs ()
1128 {
1129 if (wrapRefParagraphs == -1)
1130 return;
1131
1132 // Notice that wrapRefParagraphs refers to the lines, not to the paragraphs.
1133 int firstWordOfLine;
1134 if (lines->size () > 0 && wrapRefParagraphs > 0)
1135 firstWordOfLine = lines->getRef(wrapRefParagraphs - 1)->lastWord + 1;
1136 else
1137 firstWordOfLine = 0;
1138
1139 int parNo;
1140 if (paragraphs->size() > 0 &&
1141 firstWordOfLine > paragraphs->getLastRef()->firstWord)
1142 // A special case: the paragraphs list has been partly built, but
1143 // not yet the paragraph containing the word in question. In
1144 // this case, only the rest of the paragraphs list must be
1145 // constructed. (Without this check, findParagraphOfWord would
1146 // return -1 in this case, so that all paragraphs would be
1147 // rebuilt.)
1148 parNo = paragraphs->size ();
1149 else
1150 // If there are no paragraphs yet, findParagraphOfWord will return
1151 // -1: use 0 then instead.
1152 parNo = misc::max (0, findParagraphOfWord (firstWordOfLine));
1153
1154 paragraphs->setSize (parNo);
1155
1156 int firstWord;
1157 if (paragraphs->size () > 0)
1158 firstWord = paragraphs->getLastRef()->lastWord + 1;
1159 else
1160 firstWord = 0;
1161
1162 PRINTF ("[%p] FILL_PARAGRAPHS: now %d paragraphs; starting from word %d\n",
1163 this, parNo, firstWord);
1164
1165 for (int i = firstWord; i < words->size (); i++)
1166 handleWordExtremes (i);
1167
1168 wrapRefParagraphs = -1;
1169 }
1170
1171 void Textblock::showMissingLines ()
1172 {
1173 int firstWordToWrap = lines->size () > 0 ?
1174 lines->getRef(lines->size () - 1)->lastWord + 1 : 0;
1175 PRINTF ("[%p] SHOW_MISSING_LINES: wrap from %d to %d\n",
1176 this, firstWordToWrap, words->size () - 1);
1177 for (int i = firstWordToWrap; i < words->size (); i++)
1178 wordWrap (i, true);
1179 }
1180
1181
1182 void Textblock::removeTemporaryLines ()
1183 {
1184 lines->setSize (nonTemporaryLines);
1185 }
1186
1187 int Textblock::getShrinkability(struct Word *word)
1188 {
1189 if (word->spaceStyle->textAlign == core::style::TEXT_ALIGN_JUSTIFY)
1190 return word->origSpace / 3;
1191 else
1192 return 0;
1193 }
1194
1195 int Textblock::getStretchability(struct Word *word)
1196 {
1197 return word->origSpace / 2;
1198 }
1199
1200 } // namespace dw
267267 rectangleList->append (r);
268268 }
269269
270 } // namespace core
270271 } // namespace dw
271 } // namespace core
193193 REAL_CONTENT = 0xff ^ (START | END),
194194 SELECTION_CONTENT = TEXT | WIDGET | BREAK
195195 };
196 enum BreakType {
197 BREAK_NO,
198 BREAK_OK
199 };
196
200197 /* Content is embedded in struct Word therefore we
201198 * try to be space efficient.
202199 */
203200 short type;
204201 bool space;
205 unsigned char breakType;
206202 union {
207203 const char *text;
208204 Widget *widget;
210206 };
211207 };
212208
209 } // namespace core
213210 } // namespace dw
214 } // namespace core
215211
216212 #endif // __DW_TYPES_HH__
380380
381381 } // namespace ui
382382 } // namespace core
383 } // namespace core
384
383 } // namespace dw
384
1919 * \dot
2020 * digraph G {
2121 * node [shape=record, fontname=Helvetica, fontsize=10];
22 * edge [arrowhead="none", arrowtail="empty", labelfontname=Helvetica,
23 * labelfontsize=10, color="#404040", labelfontcolor="#000080"];
22 * edge [arrowhead="none", arrowtail="empty", dir="both",
23 * labelfontname=Helvetica, labelfontsize=10, color="#404040",
24 * labelfontcolor="#000080"];
2425 * fontname=Helvetica; fontsize=10;
2526 *
2627 * subgraph cluster_core {
420421 {
421422 public:
422423 virtual void addItem (const char *str, bool enabled, bool selected) = 0;
424 virtual void setItem (int index, bool selected) = 0;
423425 virtual void pushGroup (const char *name, bool enabled) = 0;
424426 virtual void popGroup () = 0;
425427
479481 class EntryResource: public TextResource
480482 {
481483 public:
482 enum { UNLIMITED_MAX_LENGTH = -1 };
484 enum { UNLIMITED_SIZE = -1 };
485 virtual void setMaxLength (int maxlen) = 0;
483486 };
484487
485488 class MultiLineTextResource: public TextResource
539542 virtual ListResource *createListResource (ListResource::SelectionMode
540543 selectionMode, int rows) = 0;
541544 virtual OptionMenuResource *createOptionMenuResource () = 0;
542 virtual EntryResource *createEntryResource (int maxLength, bool password,
545 virtual EntryResource *createEntryResource (int size, bool password,
543546 const char *label) = 0;
544547 virtual MultiLineTextResource *createMultiLineTextResource (int cols,
545548 int rows) = 0;
204204 virtual void mergeClippingView (View *clippingView) = 0;
205205 };
206206
207 } // namespace core
207208 } // namespace dw
208 } // namespace core
209209
210210 #endif // __DW_VIEW_HH__
108108 buttonSensitive = parent->buttonSensitive;
109109
110110 //DBG_OBJ_ASSOC (widget, parent);
111 //printf ("The %s %p becomes a child of the %s %p\n",
112 // getClassName(), this, parent->getClassName(), parent);
111113 }
112114
113115 void Widget::queueDrawArea (int x, int y, int width, int height)
124126 {
125127 Widget *widget2, *child;
126128
127 //DEBUG_MSG (DEBUG_SIZE,
128 // "a %stop-level %s with parent_ref = %d has changed its size\n",
129 // widget->parent ? "non-" : "",
130 // gtk_type_name (GTK_OBJECT_TYPE (widget)), widget->parent_ref);
129 //printf("The %stop-level %s %p with parentRef = %d has changed its size.\n",
130 // parent ? "non-" : "", getClassName(), this, parentRef);
131131
132132 setFlags (NEEDS_RESIZE);
133133 setFlags (NEEDS_ALLOCATE);
145145 widget2->markSizeChange (child->parentRef);
146146 widget2->setFlags (NEEDS_ALLOCATE);
147147
148 //DEBUG_MSG (DEBUG_ALLOC,
149 // "setting DW_NEEDS_ALLOCATE for a %stop-level %s "
150 // "with parent_ref = %d\n",
151 // widget2->parent ? "non-" : "",
152 // gtk_type_name (GTK_OBJECT_TYPE (widget2)),
153 // widget2->parent_ref);
148 //printf (" Setting DW_NEEDS_RESIZE and NEEDS_ALLOCATE for the "
149 // "%stop-level %s %p with parentRef = %d\n",
150 // widget2->parent ? "non-" : "", widget2->getClassName(), widget2,
151 // widget2->parentRef);
154152
155153 if (extremesChanged) {
156154 widget2->setFlags (EXTREMES_CHANGED);
210208 allocation->width != this->allocation.width ||
211209 allocation->ascent != this->allocation.ascent ||
212210 allocation->descent != this->allocation.descent) {
213
214 //DEBUG_MSG (DEBUG_ALLOC,
215 // "a %stop-level %s with parent_ref = %d is newly allocated "
216 // "from %d, %d, %d x %d x %d ...\n",
217 // widget->parent ? "non-" : "",
218 // (GTK_OBJECT_TYPE_NAME (widget), widget->parent_ref,
219 // widget->allocation.x, widget->allocation.y,
220 // widget->allocation.width, widget->allocation.ascent,
221 // widget->allocation.descent);
222211
223212 if (wasAllocated ()) {
224213 layout->queueDrawExcept (
504493 Iterator *it;
505494 Widget *childAtPoint;
506495
507 //_MSG ("%*s-> examining the %s %p (%d, %d, %d x (%d + %d))\n",
508 // 3 * level, "", gtk_type_name (GTK_OBJECT_TYPE (widget)), widget,
509 // allocation.x, allocation.y,
510 // allocation.width, allocation.ascent,
511 // allocation.descent);
496 //printf ("%*s-> examining the %s %p (%d, %d, %d x (%d + %d))\n",
497 // 3 * level, "", getClassName (), this, allocation.x, allocation.y,
498 // allocation.width, allocation.ascent, allocation.descent);
512499
513500 if (x >= allocation.x &&
514501 y >= allocation.y &&
614601 misc::assertNotReached ();
615602 }
616603
617
618
604 } // namespace core
619605 } // namespace dw
620 } // namespace core
199199
200200 inline void setCursor (style::Cursor cursor)
201201 { layout->setCursor (cursor); }
202
202 #if 0
203203 inline bool selectionButtonPress (Iterator *it, int charPos, int linkNo,
204204 EventButton *event, bool withinContent)
205205 { return layout->selectionState.buttonPress (it, charPos, linkNo, event); }
211211 inline bool selectionButtonMotion (Iterator *it, int charPos, int linkNo,
212212 EventMotion *event, bool withinContent)
213213 { return layout->selectionState.buttonMotion (it, charPos, linkNo, event); }
214
214 #endif
215215 inline bool selectionHandleEvent (SelectionState::EventType eventType,
216216 Iterator *it, int charPos, int linkNo,
217217 MousePositionEvent *event)
305305 virtual void removeChild (Widget *child);
306306 };
307307
308 } // namespace core
308309 } // namespace dw
309 } // namespace core
310310
311311 #endif // __DW_WIDGET_HH__
00 #!/bin/sh
11 # install - install a program, script, or datafile
22
3 scriptversion=2009-04-28.21; # UTC
3 scriptversion=2011-01-19.21; # UTC
44
55 # This originates from X11R5 (mit/util/scripts/install.sh), which was
66 # later released in X11R6 (xc/config/util/install.sh) with the
155155 -s) stripcmd=$stripprog;;
156156
157157 -t) dst_arg=$2
158 # Protect names problematic for `test' and other utilities.
159 case $dst_arg in
160 -* | [=\(\)!]) dst_arg=./$dst_arg;;
161 esac
158162 shift;;
159163
160164 -T) no_target_directory=true;;
185189 fi
186190 shift # arg
187191 dst_arg=$arg
192 # Protect names problematic for `test' and other utilities.
193 case $dst_arg in
194 -* | [=\(\)!]) dst_arg=./$dst_arg;;
195 esac
188196 done
189197 fi
190198
199207 fi
200208
201209 if test -z "$dir_arg"; then
202 trap '(exit $?); exit' 1 2 13 15
210 do_exit='(exit $ret); exit $ret'
211 trap "ret=129; $do_exit" 1
212 trap "ret=130; $do_exit" 2
213 trap "ret=141; $do_exit" 13
214 trap "ret=143; $do_exit" 15
203215
204216 # Set umask so as not to create temps with too-generous modes.
205217 # However, 'strip' requires both read and write access to temps.
227239
228240 for src
229241 do
230 # Protect names starting with `-'.
242 # Protect names problematic for `test' and other utilities.
231243 case $src in
232 -*) src=./$src;;
244 -* | [=\(\)!]) src=./$src;;
233245 esac
234246
235247 if test -n "$dir_arg"; then
251263 echo "$0: no destination specified." >&2
252264 exit 1
253265 fi
254
255266 dst=$dst_arg
256 # Protect names starting with `-'.
257 case $dst in
258 -*) dst=./$dst;;
259 esac
260267
261268 # If destination is a directory, append the input filename; won't work
262269 # if double slashes aren't ignored.
384391
385392 case $dstdir in
386393 /*) prefix='/';;
387 -*) prefix='./';;
394 [-=\(\)!]*) prefix='./';;
388395 *) prefix='';;
389396 esac
390397
402409
403410 for d
404411 do
405 test -z "$d" && continue
412 test X"$d" = X && continue
406413
407414 prefix=$prefix$d
408415 if test -d "$prefix"; then
1414 object.hh \
1515 signal.cc \
1616 signal.hh \
17 unicode.cc \
18 unicode.hh \
1719 msg.h
0 # Makefile.in generated by automake 1.11.1 from Makefile.am.
0 # Makefile.in generated by automake 1.11.6 from Makefile.am.
11 # @configure_input@
22
33 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
4 # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
5 # Inc.
4 # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
5 # Foundation, Inc.
66 # This Makefile.in is free software; the Free Software Foundation
77 # gives unlimited permission to copy and/or distribute it,
88 # with or without modifications, as long as this notice is preserved.
1515 @SET_MAKE@
1616
1717 VPATH = @srcdir@
18 am__make_dryrun = \
19 { \
20 am__dry=no; \
21 case $$MAKEFLAGS in \
22 *\\[\ \ ]*) \
23 echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
24 | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
25 *) \
26 for am__flg in $$MAKEFLAGS; do \
27 case $$am__flg in \
28 *=*|--*) ;; \
29 *n*) am__dry=yes; break;; \
30 esac; \
31 done;; \
32 esac; \
33 test $$am__dry = yes; \
34 }
1835 pkgdatadir = $(datadir)/@PACKAGE@
1936 pkgincludedir = $(includedir)/@PACKAGE@
2037 pkglibdir = $(libdir)/@PACKAGE@
3754 subdir = lout
3855 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
3956 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
40 am__aclocal_m4_deps = $(top_srcdir)/configure.in
57 am__aclocal_m4_deps = $(top_srcdir)/configure.ac
4158 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
4259 $(ACLOCAL_M4)
4360 mkinstalldirs = $(install_sh) -d
5067 liblout_a_AR = $(AR) $(ARFLAGS)
5168 liblout_a_LIBADD =
5269 am_liblout_a_OBJECTS = container.$(OBJEXT) identity.$(OBJEXT) \
53 misc.$(OBJEXT) object.$(OBJEXT) signal.$(OBJEXT)
70 misc.$(OBJEXT) object.$(OBJEXT) signal.$(OBJEXT) \
71 unicode.$(OBJEXT)
5472 liblout_a_OBJECTS = $(am_liblout_a_OBJECTS)
5573 DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
5674 depcomp = $(SHELL) $(top_srcdir)/depcomp
6785 LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
6886 SOURCES = $(liblout_a_SOURCES)
6987 DIST_SOURCES = $(liblout_a_SOURCES)
88 am__can_run_installinfo = \
89 case $$AM_UPDATE_INFO_DIR in \
90 n|no|NO) false;; \
91 *) (install-info --version) >/dev/null 2>&1;; \
92 esac
7093 ETAGS = etags
7194 CTAGS = ctags
7295 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
202225 object.hh \
203226 signal.cc \
204227 signal.hh \
228 unicode.cc \
229 unicode.hh \
205230 msg.h
206231
207232 all: all-am
241266
242267 clean-noinstLIBRARIES:
243268 -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
244 liblout.a: $(liblout_a_OBJECTS) $(liblout_a_DEPENDENCIES)
269 liblout.a: $(liblout_a_OBJECTS) $(liblout_a_DEPENDENCIES) $(EXTRA_liblout_a_DEPENDENCIES)
245270 -rm -f liblout.a
246271 $(liblout_a_AR) liblout.a $(liblout_a_OBJECTS) $(liblout_a_LIBADD)
247272 $(RANLIB) liblout.a
257282 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc.Po@am__quote@
258283 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/object.Po@am__quote@
259284 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/signal.Po@am__quote@
285 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unicode.Po@am__quote@
260286
261287 .cc.o:
262288 @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
368394
369395 installcheck: installcheck-am
370396 install-strip:
371 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
372 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
373 `test -z '$(STRIP)' || \
374 echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
397 if test -z '$(STRIP)'; then \
398 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
399 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
400 install; \
401 else \
402 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
403 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
404 "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
405 fi
375406 mostlyclean-generic:
376407
377408 clean-generic:
1616 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1717 */
1818
19
19 #define PRINTF(fmt, ...)
20 //#define PRINTF printf
2021
2122 #include "container.hh"
2223 #include "misc.hh"
188189 */
189190 void Vector::sort()
190191 {
191 qsort(array, numElements, sizeof(Object*), misc::Comparable::compareFun);
192 }
193
192 qsort (array, numElements, sizeof(Object*), Comparable::compareFun);
193 }
194194
195195 /**
196 * \bug Not implemented.
196 * \brief Use binary search to find an element in a sorted vector.
197 *
198 * If "mustExist" is true, only exact matches are found; otherwise, -1
199 * is returned. If it is false, the position of the next greater
200 * element is returned, or, if the key is the greatest element, the
201 * size of the array. (This is the value which can be used for
202 * insertion; see insertSortet()).
197203 */
204 int Vector::bsearch(Object *key, bool mustExist)
205 {
206 // The case !mustExist is not handled by bsearch(3), so here is a
207 // new implementation.
208 if (numElements == 0)
209 return mustExist ? -1 : 0;
210
211 int high = numElements - 1, low = 0;
212
213 while (true) {
214 int index = (low + high) / 2;
215 int c = ((Comparable*) key)->compareTo ((Comparable*)array[index]);
216 if (c == 0)
217 return index;
218 else {
219 if (low >= high) {
220 if (mustExist)
221 return -1;
222 else
223 return c > 0 ? index + 1 : index;
224 }
225
226 if (c < 0)
227 high = index - 1;
228 else
229 low = index + 1;
230 }
231 }
232
233
234 /*
235 void *result = ::bsearch (&key, array, numElements, sizeof (Object*),
236 Comparable::compareFun);
237 if (result)
238 return (Object**)result - array;
239 else
240 return -1;
241 */
242 }
243
244 Object *Vector::VectorIterator::getNext()
245 {
246 if (index < vector->numElements - 1)
247 index++;
248
249 return index < vector->numElements ? vector->array[index] : NULL;
250 }
251
252 bool Vector::VectorIterator::hasNext()
253 {
254 return index < vector->numElements - 1;
255 }
256
198257 Collection0::AbstractIterator* Vector::createIterator()
199258 {
200 return NULL;
259 return new VectorIterator(this);
201260 }
202261
203262 // ------------
301360
302361
303362 // ---------------
304 // HashTable
363 // HashSet
305364 // ---------------
306365
307 HashTable::HashTable(bool ownerOfKeys, bool ownerOfValues, int tableSize)
308 {
309 this->ownerOfKeys = ownerOfKeys;
310 this->ownerOfValues = ownerOfValues;
366 HashSet::HashSet(bool ownerOfObjects, int tableSize)
367 {
368 this->ownerOfObjects = ownerOfObjects;
311369 this->tableSize = tableSize;
312370
313371 table = new Node*[tableSize];
315373 table[i] = NULL;
316374 }
317375
318 HashTable::~HashTable()
376 HashSet::~HashSet()
319377 {
320378 for (int i = 0; i < tableSize; i++) {
321379 Node *n1 = table[i];
322380 while (n1) {
323381 Node *n2 = n1->next;
324382
325 if (ownerOfValues && n1->value)
326 delete n1->value;
327 if (ownerOfKeys)
328 delete n1->key;
383 // It seems appropriate to call "clearNode(n1)" here instead
384 // of "delete n1->object", but since this is the destructor,
385 // the implementation of a sub class would not be called
386 // anymore. This is the reason why HashTable has an
387 // destructor.
388 if (ownerOfObjects) {
389 PRINTF ("- deleting object: %s\n", n1->object->toString());
390 delete n1->object;
391 }
392
329393 delete n1;
330
331394 n1 = n2;
332395 }
333396 }
334397
335398 delete[] table;
399 }
400
401 HashSet::Node *HashSet::createNode()
402 {
403 return new Node;
404 }
405
406 void HashSet::clearNode(HashSet::Node *node)
407 {
408 if (ownerOfObjects) {
409 PRINTF ("- deleting object: %s\n", node->object->toString());
410 delete node->object;
411 }
412 }
413
414 HashSet::Node *HashSet::findNode(Object *object)
415 {
416 int h = calcHashValue(object);
417 for (Node *node = table[h]; node; node = node->next) {
418 if (object->equals(node->object))
419 return node;
420 }
421
422 return NULL;
423 }
424
425 HashSet::Node *HashSet::insertNode(Object *object)
426 {
427 // Look whether object is already contained.
428 Node *node = findNode(object);
429 if (node)
430 clearNode(node);
431 else {
432 int h = calcHashValue(object);
433 node = createNode ();
434 node->next = table[h];
435 table[h] = node;
436 }
437
438 node->object = object;
439 return node;
440 }
441
442
443 void HashSet::put(Object *object)
444 {
445 insertNode (object);
446 }
447
448 bool HashSet::contains(Object *object)
449 {
450 int h = calcHashValue(object);
451 for (Node *n = table[h]; n; n = n->next) {
452 if (object->equals(n->object))
453 return true;
454 }
455
456 return false;
457 }
458
459 bool HashSet::remove(Object *object)
460 {
461 int h = calcHashValue(object);
462 Node *last, *cur;
463
464 for (last = NULL, cur = table[h]; cur; last = cur, cur = cur->next) {
465 if (object->equals(cur->object)) {
466 if (last)
467 last->next = cur->next;
468 else
469 table[h] = cur->next;
470
471 clearNode (cur);
472 delete cur;
473
474 return true;
475 }
476 }
477
478 return false;
479
480 // TODO for HashTable: also remove value.
481 }
482
483 // For historical reasons: this method once existed under the name
484 // "getKey" in HashTable. It could be used to get the real object from
485 // the table, but it was dangerous, because a change of this object
486 // would also change the hash value, and so confuse the table.
487
488 /*Object *HashSet::getReference (Object *object)
489 {
490 int h = calcHashValue(object);
491 for (Node *n = table[h]; n; n = n->next) {
492 if (object->equals(n->object))
493 return n->object;
494 }
495
496 return NULL;
497 }*/
498
499 HashSet::HashSetIterator::HashSetIterator(HashSet *set)
500 {
501 this->set = set;
502 node = NULL;
503 pos = -1;
504 gotoNext();
505 }
506
507 void HashSet::HashSetIterator::gotoNext()
508 {
509 if (node)
510 node = node->next;
511
512 while (node == NULL) {
513 if (pos >= set->tableSize - 1)
514 return;
515 pos++;
516 node = set->table[pos];
517 }
518 }
519
520
521 Object *HashSet::HashSetIterator::getNext()
522 {
523 Object *result;
524 if (node)
525 result = node->object;
526 else
527 result = NULL;
528
529 gotoNext();
530 return result;
531 }
532
533 bool HashSet::HashSetIterator::hasNext()
534 {
535 return node != NULL;
536 }
537
538 Collection0::AbstractIterator* HashSet::createIterator()
539 {
540 return new HashSetIterator(this);
541 }
542
543 // ---------------
544 // HashTable
545 // ---------------
546
547 HashTable::HashTable(bool ownerOfKeys, bool ownerOfValues, int tableSize) :
548 HashSet (ownerOfKeys, tableSize)
549 {
550 this->ownerOfValues = ownerOfValues;
551 }
552
553 HashTable::~HashTable()
554 {
555 // See comment in the destructor of HashSet.
556 for (int i = 0; i < tableSize; i++) {
557 for (Node *n = table[i]; n; n = n->next) {
558 if (ownerOfValues) {
559 Object *value = ((KeyValuePair*)n)->value;
560 if (value) {
561 PRINTF ("- deleting value: %s\n", value->toString());
562 delete value;
563 }
564 }
565 }
566 }
567 }
568
569 HashSet::Node *HashTable::createNode()
570 {
571 return new KeyValuePair;
572 }
573
574 void HashTable::clearNode(HashSet::Node *node)
575 {
576 HashSet::clearNode (node);
577 if (ownerOfValues) {
578 Object *value = ((KeyValuePair*)node)->value;
579 if (value) {
580 PRINTF ("- deleting value: %s\n", value->toString());
581 delete value;
582 }
583 }
336584 }
337585
338586 void HashTable::intoStringBuffer(misc::StringBuffer *sb)
344592 for (Node *node = table[i]; node; node = node->next) {
345593 if (!first)
346594 sb->append(", ");
347 node->key->intoStringBuffer(sb);
595 node->object->intoStringBuffer(sb);
596
348597 sb->append(" => ");
349 node->value->intoStringBuffer(sb);
598
599 Object *value = ((KeyValuePair*)node)->value;
600 if (value)
601 value->intoStringBuffer(sb);
602 else
603 sb->append ("null");
604
350605 first = false;
351606 }
352607 }
356611
357612 void HashTable::put(Object *key, Object *value)
358613 {
359 int h = calcHashValue(key);
360 Node *n = new Node;
361 n->key = key;
362 n->value = value;
363 n->next = table[h];
364 table[h] = n;
365 }
366
367 bool HashTable::contains(Object *key)
368 {
369 int h = calcHashValue(key);
370 for (Node *n = table[h]; n; n = n->next) {
371 if (key->equals(n->key))
372 return true;
373 }
374
375 return false;
614 KeyValuePair *node = (KeyValuePair*)insertNode(key);
615 node->value = value;
376616 }
377617
378618 Object *HashTable::get(Object *key)
379619 {
380 int h = calcHashValue(key);
381 for (Node *n = table[h]; n; n = n->next) {
382 if (key->equals(n->key))
383 return n->value;
384 }
385
386 return NULL;
387 }
388
389 bool HashTable::remove(Object *key)
390 {
391 int h = calcHashValue(key);
392 Node *last, *cur;
393
394 for (last = NULL, cur = table[h]; cur; last = cur, cur = cur->next) {
395 if (key->equals(cur->key)) {
396 if (last)
397 last->next = cur->next;
398 else
399 table[h] = cur->next;
400
401 if (ownerOfValues && cur->value)
402 delete cur->value;
403 if (ownerOfKeys)
404 delete cur->key;
405 delete cur;
406
407 return true;
408 }
409 }
410
411 return false;
412 }
413
414 Object *HashTable::getKey (Object *key)
415 {
416 int h = calcHashValue(key);
417 for (Node *n = table[h]; n; n = n->next) {
418 if (key->equals(n->key))
419 return n->key;
420 }
421
422 return NULL;
423 }
424
425 HashTable::HashTableIterator::HashTableIterator(HashTable *table)
426 {
427 this->table = table;
428 node = NULL;
429 pos = -1;
430 gotoNext();
431 }
432
433 void HashTable::HashTableIterator::gotoNext()
434 {
620 Node *node = findNode(key);
435621 if (node)
436 node = node->next;
437
438 while (node == NULL) {
439 if (pos >= table->tableSize - 1)
440 return;
441 pos++;
442 node = table->table[pos];
443 }
444 }
445
446
447 Object *HashTable::HashTableIterator::getNext()
448 {
449 Object *result;
450 if (node)
451 result = node->key;
622 return ((KeyValuePair*)node)->value;
452623 else
453 result = NULL;
454
455 gotoNext();
456 return result;
457 }
458
459 bool HashTable::HashTableIterator::hasNext()
460 {
461 return node != NULL;
462 }
463
464 Collection0::AbstractIterator* HashTable::createIterator()
465 {
466 return new HashTableIterator(this);
624 return NULL;
467625 }
468626
469627 // -----------
11 #define __LOUT_CONTAINER_HH_
22
33 #include "object.hh"
4
5 namespace lout {
46
57 /**
68 * \brief This namespace contains a framework for container classes, which
1416 *
1517 * \sa container::untyped, container::typed
1618 */
17 namespace lout {
18
1919 namespace container {
2020
2121 /**
101101 */
102102 class Vector: public Collection
103103 {
104 friend class VectorIterator;
105
104106 private:
105107 object::Object **array;
106108 int numAlloc, numElements;
107109 bool ownerOfObjects;
108110
111 class VectorIterator: public AbstractIterator
112 {
113 private:
114 Vector *vector;
115 int index;
116
117 public:
118 VectorIterator(Vector *vector) { this->vector = vector; index = -1; }
119 bool hasNext();
120 Object *getNext();
121 };
122
109123 protected:
110124 AbstractIterator* createIterator();
111125
115129
116130 void put(object::Object *newElement, int newPos = -1);
117131 void insert(object::Object *newElement, int pos);
132
133 /**
134 * \brief Insert into an already sorted vector.
135 *
136 * Notice that insertion is not very efficient, unless the position
137 * is rather at the end.
138 */
139 inline void insertSorted(object::Object *newElement)
140 { insert (newElement, bsearch (newElement, false)); }
141
118142 void remove(int pos);
119143 inline object::Object *get(int pos)
120144 { return (pos >= 0 && pos < numElements) ? array[pos] : NULL; }
121145 inline int size() { return numElements; }
122146 void clear();
123147 void sort();
148 int bsearch(Object *key, bool mustExist);
124149 };
125150
126151
178203
179204
180205 /**
181 * \brief A hash table.
182 */
183 class HashTable: public Collection
184 {
185 friend class HashTableIterator;
186
187 private:
206 * \brief A hash set.
207 */
208 class HashSet: public Collection
209 {
210 friend class HashSetIterator;
211
212 protected:
188213 struct Node
189214 {
190 object::Object *key, *value;
215 object::Object *object;
191216 Node *next;
192217 };
193218
194 class HashTableIterator: public Collection0::AbstractIterator
219 Node **table;
220 int tableSize;
221 bool ownerOfObjects;
222
223 inline int calcHashValue(object::Object *object)
224 {
225 return abs(object->hashValue()) % tableSize;
226 }
227
228 virtual Node *createNode();
229 virtual void clearNode(Node *node);
230
231 Node *findNode(object::Object *object);
232 Node *insertNode(object::Object *object);
233
234 AbstractIterator* createIterator();
235
236 private:
237 class HashSetIterator: public Collection0::AbstractIterator
195238 {
196239 private:
197 HashTable *table;
198 HashTable::Node *node;
240 HashSet *set;
241 HashSet::Node *node;
199242 int pos;
200243
201244 void gotoNext();
202245
203246 public:
204 HashTableIterator(HashTable *table);
247 HashSetIterator(HashSet *set);
205248 bool hasNext();
206249 Object *getNext();
207250 };
208251
209 Node **table;
210 int tableSize;
211 bool ownerOfKeys, ownerOfValues;
212
213 private:
214 inline int calcHashValue(object::Object *key)
215 {
216 return abs(key->hashValue()) % tableSize;
217 }
218
219 protected:
220 AbstractIterator* createIterator();
252 public:
253 HashSet(bool ownerOfObjects, int tableSize = 251);
254 ~HashSet();
255
256 void put (object::Object *object);
257 bool contains (object::Object *key);
258 bool remove (object::Object *key);
259 //Object *getReference (object::Object *object);
260 };
261
262 /**
263 * \brief A hash table.
264 */
265 class HashTable: public HashSet
266 {
267 private:
268 bool ownerOfValues;
269
270 struct KeyValuePair: public Node
271 {
272 object::Object *value;
273 };
274
275 protected:
276 Node *createNode();
277 void clearNode(Node *node);
221278
222279 public:
223280 HashTable(bool ownerOfKeys, bool ownerOfValues, int tableSize = 251);
226283 void intoStringBuffer(misc::StringBuffer *sb);
227284
228285 void put (object::Object *key, object::Object *value);
229 bool contains (object::Object *key);
230 Object *get (object::Object *key);
231 bool remove (object::Object *key);
232 Object *getKey (Object *key);
286 object::Object *get (object::Object *key);
233287 };
234288
235289 /**
327381 untyped::Collection *base;
328382
329383 public:
384 Collection () { this->base = NULL; }
385 ~Collection () { if (this->base) delete this->base; }
386
330387 void intoStringBuffer(misc::StringBuffer *sb)
331388 { this->base->intoStringBuffer(sb); }
332389
343400 public:
344401 inline Vector(int initSize, bool ownerOfObjects) {
345402 this->base = new untyped::Vector(initSize, ownerOfObjects); }
346 ~Vector() { delete this->base; }
347403
348404 inline void put(T *newElement, int newPos = -1)
349405 { ((untyped::Vector*)this->base)->put(newElement, newPos); }
350406 inline void insert(T *newElement, int pos)
351407 { ((untyped::Vector*)this->base)->insert(newElement, pos); }
408 inline void insertSorted(T *newElement)
409 { ((untyped::Vector*)this->base)->insertSorted(newElement); }
352410 inline void remove(int pos) { ((untyped::Vector*)this->base)->remove(pos); }
353411 inline T *get(int pos)
354412 { return (T*)((untyped::Vector*)this->base)->get(pos); }
355413 inline int size() { return ((untyped::Vector*)this->base)->size(); }
356414 inline void clear() { ((untyped::Vector*)this->base)->clear(); }
357415 inline void sort() { ((untyped::Vector*)this->base)->sort(); }
416 inline int bsearch(T *key, bool mustExist)
417 { return ((untyped::Vector*)this->base)->bsearch(key, mustExist); }
358418 };
359419
360420
366426 public:
367427 inline List(bool ownerOfObjects)
368428 { this->base = new untyped::List(ownerOfObjects); }
369 ~List() { delete this->base; }
370429
371430 inline void clear() { ((untyped::List*)this->base)->clear(); }
372431 inline void append(T *element)
387446 { return (T*)((untyped::List*)this->base)->getLast(); }
388447 };
389448
449 /**
450 * \brief Typed version of container::untyped::HashSet.
451 */
452 template <class T> class HashSet: public Collection <T>
453 {
454 protected:
455 inline HashSet() { }
456
457 public:
458 inline HashSet(bool owner, int tableSize = 251)
459 { this->base = new untyped::HashSet(owner, tableSize); }
460
461 inline void put(T *object)
462 { return ((untyped::HashSet*)this->base)->put(object); }
463 inline bool contains(T *object)
464 { return ((untyped::HashSet*)this->base)->contains(object); }
465 inline bool remove(T *object)
466 { return ((untyped::HashSet*)this->base)->remove(object); }
467 //inline T *getReference(T *object)
468 //{ return (T*)((untyped::HashSet*)this->base)->getReference(object); }
469 };
390470
391471 /**
392472 * \brief Typed version of container::untyped::HashTable.
393473 */
394 template <class K, class V> class HashTable: public Collection <K>
474 template <class K, class V> class HashTable: public HashSet <K>
395475 {
396476 public:
397477 inline HashTable(bool ownerOfKeys, bool ownerOfValues, int tableSize = 251)
398478 { this->base = new untyped::HashTable(ownerOfKeys, ownerOfValues,
399479 tableSize); }
400 ~HashTable() { delete this->base; }
401480
402481 inline void put(K *key, V *value)
403482 { return ((untyped::HashTable*)this->base)->put(key, value); }
404 inline bool contains(K *key)
405 { return ((untyped::HashTable*)this->base)->contains(key); }
406483 inline V *get(K *key)
407484 { return (V*)((untyped::HashTable*)this->base)->get(key); }
408 inline bool remove(K *key)
409 { return ((untyped::HashTable*)this->base)->remove(key); }
410 inline K *getKey(K *key)
411 { return (K*)((untyped::HashTable*)this->base)->getKey(key); }
412485 };
413486
414487 /**
419492 public:
420493 inline Stack (bool ownerOfObjects)
421494 { this->base = new untyped::Stack (ownerOfObjects); }
422 ~Stack() { delete this->base; }
423495
424496 inline void push (T *object) {
425497 ((untyped::Stack*)this->base)->push (object); }
44 #include "container.hh"
55 #include "signal.hh"
66
7 namespace lout {
8
79 /**
810 * \brief Some stuff to identify classes of objects at run-time.
911 */
10
11 namespace lout {
12
1312 namespace identity {
1413
1514 /**
3434 void init (int argc, char *argv[])
3535 {
3636 prgName = strdup (argv[0]);
37 }
38
39 // ----------------
40 // Comparable
41 // ----------------
42
43 Comparable::~Comparable()
44 {
45 }
46
47 /**
48 * \brief This static method may be used as compare function for qsort(3), for
49 * an array of Object* (Object*[] or Object**).
50 */
51 int Comparable::compareFun(const void *p1, const void *p2)
52 {
53 Comparable **c1 = (Comparable**)p1;
54 Comparable **c2 = (Comparable**)p2;
55 if (c1 && c2)
56 return ((*c1)->compareTo(*c2));
57 else if (c1)
58 return 1;
59 else if (c2)
60 return -1;
61 else
62 return 0;
6337 }
6438
6539
66 #include <string.h>
77 #include <assert.h>
88
9 namespace lout {
10
911 /**
1012 * \brief Miscellaneous stuff, which does not fit anywhere else.
1113 *
1214 * Actually, the other parts, beginning with ::object, depend on this.
1315 */
14 namespace lout {
15
1616 namespace misc {
1717
1818 template <class T> inline T min (T a, T b) { return a < b ? a : b; }
6262 }
6363 return ret;
6464 }
65
66 /**
67 * \brief Instances of a sub class of this interface may be compared (less,
68 * greater).
69 *
70 * Used for sorting etc.
71 */
72 class Comparable
73 {
74 public:
75 virtual ~Comparable();
76
77 /**
78 * \brief Compare two objects c1 and c2.
79 *
80 * return a value < 0, when c1 is less than c2, a value > 0, when c1
81 * is greater than c2, or 0, when c1 and c2 are equal.
82 *
83 * If also object::Object is implemented, and if c1.equals(c2),
84 * c1.compareTo(c2) must be 0, but, unlike you may expect,
85 * the reversed is not necessarily true. This method returns 0, if,
86 * according to the rules for sorting, there is no difference, but there
87 * may still be differences (not relevant for sorting), which "equals" will
88 * care about.
89 */
90 virtual int compareTo(Comparable *other) = 0;
91
92 static int compareFun(const void *p1, const void *p2);
93 };
9465
9566 /**
9667 * \brief Simple (simpler than container::untyped::Vector and
148119
149120 inline T* getArray() { return array; }
150121
122 inline T* detachArray() {
123 T* arr = array;
124 array = NULL;
125 numAlloc = 0;
126 num = 0;
127 return arr;
128 }
129
151130 /**
152131 * \brief Increase the vector size by one.
153132 *
200179 }
201180
202181 /**
182 * \brief Return the reference of the first element (convenience method).
183 */
184 inline T* getFirstRef () {
185 assert (this->num > 0);
186 return this->array;
187 }
188
189 /**
190 * \brief Return the first element, explicitly.
191 */
192 inline T getFirst () {
193 assert (this->num > 0);
194 return this->array[0];
195 }
196
197 /**
198 * \brief Return the reference of the last element (convenience method).
199 */
200 inline T* getLastRef () {
201 assert (this->num > 0);
202 return this->array + this->num - 1;
203 }
204
205 /**
206 * \brief Return the last element, explicitly.
207 */
208 inline T getLast () {
209 assert (this->num > 0);
210 return this->array[this->num - 1];
211 }
212
213 /**
203214 * \brief Store an object in the vector.
204215 *
205216 * Unlike in container::untyped::Vector and container::typed::Vector,
213224 }
214225 };
215226
227 /**
228 * \brief Container similar to lout::misc::SimpleVector, but some cases
229 * of insertion optimized (used for hyphenation).
230 *
231 * For hyphenation, words are often split, so that some space must be
232 * inserted by the method NotSoSimpleVector::insert. Typically, some
233 * elements are inserted quite at the beginning (when the word at the
234 * end of the first or at the beginning of the second line is
235 * hyphenated), then, a bit further (end of second line/beginning of
236 * third line) and so on. In the first time, nearly all words must be
237 * moved; in the second time, a bit less, etc. After all, using a
238 * simple vector would result in O(n<sup>2</sup>) number of elements
239 * moved total. With this class, however, the number can be kept at
240 * O(n).
241 *
242 * The basic idea is to keep an extra array (actually two, of which
243 * the second one is used temporarily), which is inserted in a logical
244 * way. Since there is only one extra array at max, reading is rather
245 * simple and fast (see NotSoSimpleVector::getRef): check whether the
246 * position is before, within, or after the extra array. The first
247 * insertion is also rather simple, when the extra array has to be
248 * created. The following sketch illustrates the most complex case,
249 * when an extra array exists, and something is inserted after it (the
250 * case for which this class has been optimized):
251 *
252 * \image html not-so-simple-container.png
253 *
254 * Dotted lines are used to keep the boxes aligned.
255 *
256 * As you see, only a relatively small fraction of elements has to be
257 * moved.
258 *
259 * There are some other cases, which have to be documented.
260 */
261 template <class T> class NotSoSimpleVector
262 {
263 private:
264 T *arrayMain, *arrayExtra1, *arrayExtra2;
265 int numMain, numExtra, numAllocMain, numAllocExtra, startExtra;
266
267 inline void resizeMain ()
268 {
269 /* This algorithm was tuned for memory&speed with this huge page:
270 * http://downloads.mysql.com/docs/refman-6.0-en.html.tar.gz
271 */
272 if (arrayMain == NULL) {
273 this->numAllocMain = 1;
274 this->arrayMain = (T*) malloc (sizeof (T));
275 }
276 if (this->numAllocMain < this->numMain) {
277 this->numAllocMain = (this->numMain < 100) ?
278 this->numMain : this->numMain + this->numMain/10;
279 this->arrayMain =
280 (T*) realloc(this->arrayMain, (this->numAllocMain * sizeof (T)));
281 }
282 }
283
284 inline void resizeExtra ()
285 {
286 /* This algorithm was tuned for memory&speed with this huge page:
287 * http://downloads.mysql.com/docs/refman-6.0-en.html.tar.gz
288 */
289 if (arrayExtra1 == NULL) {
290 this->numAllocExtra = 1;
291 this->arrayExtra1 = (T*) malloc (sizeof (T));
292 this->arrayExtra2 = (T*) malloc (sizeof (T));
293 }
294 if (this->numAllocExtra < this->numExtra) {
295 this->numAllocExtra = (this->numExtra < 100) ?
296 this->numExtra : this->numExtra + this->numExtra/10;
297 this->arrayExtra1 =
298 (T*) realloc(this->arrayExtra1, (this->numAllocExtra * sizeof (T)));
299 this->arrayExtra2 =
300 (T*) realloc(this->arrayExtra2, (this->numAllocExtra * sizeof (T)));
301 }
302 }
303
304 void consolidate ()
305 {
306 if (startExtra != -1) {
307 numMain += numExtra;
308 resizeMain ();
309 memmove (arrayMain + startExtra + numExtra, arrayMain + startExtra,
310 (numMain - (startExtra + numExtra)) * sizeof (T));
311 memmove (arrayMain + startExtra, arrayExtra1, numExtra * sizeof (T));
312 startExtra = -1;
313 numExtra = 0;
314 }
315 }
316
317 public:
318 inline NotSoSimpleVector (int initAlloc)
319 {
320 this->numMain = this->numExtra = 0;
321 this->numAllocMain = initAlloc;
322 this->numAllocExtra = initAlloc;
323 this->arrayMain = this->arrayExtra1 = this->arrayExtra2 = NULL;
324 this->startExtra = -1;
325 }
326
327 inline NotSoSimpleVector (const NotSoSimpleVector &o)
328 {
329 this->arrayMain = NULL;
330 this->numMain = o.numMain;
331 this->numAllocMain = o.numAllocMain;
332 resizeMain ();
333 memcpy (this->arrayMain, o.arrayMain, sizeof (T) * numMain);
334
335 this->arrayExtra = NULL;
336 this->numExtra = o.numExtra;
337 this->numAllocExtra = o.numAllocExtra;
338 resizeExtra ();
339 memcpy (this->arrayExtra, o.arrayExtra, sizeof (T) * numExtra);
340
341 this->startExtra = o.startExtra;
342 }
343
344 inline ~NotSoSimpleVector ()
345 {
346 if (this->arrayMain)
347 free (this->arrayMain);
348 if (this->arrayExtra1)
349 free (this->arrayExtra1);
350 if (this->arrayExtra2)
351 free (this->arrayExtra2);
352 }
353
354 inline int size() { return this->numMain + this->numExtra; }
355
356 inline void increase() { setSize(size() + 1); }
357
358 inline void setSize(int newSize)
359 {
360 assert (newSize >= 0);
361 this->numMain = newSize - numExtra;
362 this->resizeMain ();
363 }
364
365 void insert (int index, int numInsert)
366 {
367 assert (numInsert >= 0);
368
369 // The following lines are a simple (but inefficient) replacement.
370 //setSize (numMain + numInsert);
371 //memmove (arrayMain + index + numInsert, arrayMain + index,
372 // (numMain - index - numInsert) * sizeof (T));
373 //return;
374
375 if (this->startExtra == -1) {
376 // simple case
377 this->numExtra = numInsert;
378 this->startExtra = index;
379 resizeExtra ();
380 } else {
381 if (index < startExtra) {
382 consolidate ();
383 insert (index, numInsert);
384 } else if (index < startExtra + numExtra) {
385 int oldNumExtra = numExtra;
386 numExtra += numInsert;
387 resizeExtra ();
388
389 int toMove = startExtra + oldNumExtra - index;
390 memmove (arrayExtra1 + numExtra - toMove,
391 arrayExtra1 + index - startExtra,
392 toMove * sizeof (T));
393 } else {
394 int oldNumExtra = numExtra;
395 numExtra += numInsert;
396 resizeExtra ();
397
398 // Note: index refers to the *logical* adress, not to the
399 // *physical* one.
400 int diff = index - this->startExtra - oldNumExtra;
401 T *arrayMainI = arrayMain + this->startExtra;
402 for (int i = diff + oldNumExtra - 1; i >= 0; i--) {
403 T *src = i < oldNumExtra ?
404 this->arrayExtra1 + i : arrayMainI + (i - oldNumExtra);
405 T *dest = i < diff ?
406 arrayMainI + i : arrayExtra2 + (i - diff);
407 *dest = *src;
408 }
409
410 memcpy (arrayExtra1, arrayExtra2, sizeof (T) * oldNumExtra);
411 startExtra = index - oldNumExtra;
412 }
413 }
414 }
415
416 /**
417 * \brief Return the reference of one element.
418 *
419 * \sa misc::SimpleVector::get
420 */
421 inline T* getRef (int i)
422 {
423 if (this->startExtra == -1)
424 return this->arrayMain + i;
425 else {
426 if (i < this->startExtra)
427 return this->arrayMain + i;
428 else if (i >= this->startExtra + this->numExtra)
429 return this->arrayMain + i - this->numExtra;
430 else
431 return this->arrayExtra1 + i - this->startExtra;
432 }
433 }
434
435 /**
436 * \brief Return the one element, explicitly.
437 *
438 * The element is copied, so for complex elements, you should rather used
439 * misc::SimpleVector::getRef.
440 */
441 inline T get (int i)
442 {
443 return *(this->getRef(i));
444 }
445
446 /**
447 * \brief Return the reference of the first element (convenience method).
448 */
449 inline T* getFirstRef () {
450 assert (size () > 0);
451 return this->getRef(0);
452 }
453
454 /**
455 * \brief Return the first element, explicitly.
456 */
457 inline T getFirst () {
458 return *(this->getFirstRef());
459 }
460
461 /**
462 * \brief Return the reference of the last element (convenience method).
463 */
464 inline T* getLastRef () {
465 assert (size () > 0);
466 return this->getRef(size () - 1);
467 }
468
469 /**
470 * \brief Return the last element, explicitly.
471 */
472 inline T getLast () {
473 return *(this->getLastRef());
474 }
475
476 /**
477 * \brief Store an object in the vector.
478 *
479 * Unlike in container::untyped::Vector and container::typed::Vector,
480 * you have to care about the size, so a call to
481 * misc::SimpleVector::increase or misc::SimpleVector::setSize may
482 * be necessary before.
483 */
484 inline void set (int i, T t) {
485 *(this->getRef(i)) = t;
486 }
487 };
216488
217489 /**
218490 * \brief A class for fast concatenation of a large number of strings.
2020
2121 #include "object.hh"
2222 #include <stdio.h>
23 #include <stdint.h>
2324 #include <config.h>
2425
2526 namespace lout {
104105 return sizeof(Object*);
105106 }
106107
108 // ----------------
109 // Comparable
110 // ----------------
111
112 /**
113 * \brief This static method may be used as compare function for
114 * qsort(3) and bsearch(3), for an array of Object* (Object*[] or
115 * Object**).
116 */
117 int Comparable::compareFun(const void *p1, const void *p2)
118 {
119 Comparable *c1 = *(Comparable**)p1;
120 Comparable *c2 = *(Comparable**)p2;
121
122 if (c1 && c2)
123 return ((c1)->compareTo(c2));
124 else if (c1)
125 return 1;
126 else if (c2)
127 return -1;
128 else
129 return 0;
130 }
131
107132 // -------------
108133 // Pointer
109134 // -------------
120145 * if (sizeof (int) == sizeof (void*))
121146 * return (int)value;
122147 * else
123 * return ((int*)value)[0] ^ ((int*)value)[1];
148 * return ((int*)&value)[0] ^ ((int*)&value)[1];
124149 */
125150 #if SIZEOF_VOID_P == 4
151 // Assuming that sizeof(void*) == sizeof(int); on 32 bit systems.
126152 return (int)value;
127153 #else
128 return ((int*)value)[0] ^ ((int*)value)[1];
154 // Assuming that sizeof(void*) == 2 * sizeof(int); on 64 bit
155 // systems (int is still 32 bit).
156 // Combine both parts of the pointer value *itself*, not what it
157 // points to, by first referencing it (operator "&"), then
158 // dereferencing it again (operator "[]").
159 return ((intptr_t)value >> 32) ^ ((intptr_t)value);
129160 #endif
130161 }
131162
132163 void Pointer::intoStringBuffer(misc::StringBuffer *sb)
133164 {
134165 char buf[64];
135 snprintf(buf, sizeof(buf), "0x%p", value);
166 snprintf(buf, sizeof(buf), "%p", value);
136167 sb->append(buf);
137168 }
138169
55
66 #include "misc.hh"
77
8 namespace lout {
9
810 /**
911 * \brief Here, some common classes (or interfaces) are defined, to standardize
1012 * the access to other classes.
1113 */
12 namespace lout {
13
1414 namespace object {
1515
1616 /**
3030 virtual void intoStringBuffer(misc::StringBuffer *sb);
3131 const char *toString();
3232 virtual size_t sizeOf();
33 };
34
35 /**
36 * \brief Instances of a sub class of may be compared (less, greater).
37 *
38 * Used for sorting etc.
39 */
40 class Comparable: public Object
41 {
42 public:
43 /**
44 * \brief Compare two objects c1 and c2.
45 *
46 * Return a value < 0, when c1 is less than c2, a value > 0, when c1
47 * is greater than c2, or 0, when c1 and c2 are equal.
48 *
49 * If c1.equals(c2) (as defined in Object), c1.compareTo(c2) must
50 * be 0, but, unlike you may expect, the reversed is not
51 * necessarily true. This method returns 0, if, according to the
52 * rules for sorting, there is no difference, but there may still
53 * be differences (not relevant for sorting), which "equals" will
54 * care about.
55 */
56 virtual int compareTo(Comparable *other) = 0;
57
58 static int compareFun(const void *p1, const void *p2);
3359 };
3460
3561 /**
6288 /**
6389 * \brief An object::Object wrapper for int's.
6490 */
65 class Integer: public Object, misc::Comparable
91 class Integer: public Comparable
6692 {
6793 int value;
6894
81107 *
82108 * As opposed to object::String, the char array is not copied.
83109 */
84 class ConstString: public Object, misc::Comparable
110 class ConstString: public Comparable
85111 {
86112 protected:
87113 const char *str;
22
33 #include "object.hh"
44 #include "container.hh"
5
6 namespace lout {
57
68 /**
79 * \brief This namespace provides base classes to define signals.
173175 * After this, &\em barReceiver can be connected to all instances of
174176 * BarEmitter, also multiple times.
175177 */
176 namespace lout {
177
178178 namespace signal {
179179
180180 class Receiver;
0 #include "unicode.hh"
1 #include "misc.hh"
2
3 using namespace lout::misc;
4
5 namespace lout {
6
7 namespace unicode {
8
9 static unsigned char alpha[0x500] = {
10 // 0000-007F: C0 Controls and Basic Latin
11 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12 0xfe, 0xff, 0xff, 0x07, 0xfe, 0xff, 0xff, 0x07,
13 // 0080-00FF: C1 Controls and Latin-1 Supplement
14 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
15 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff,
16 // 0100-017F: Latin Extended-A
17 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
18 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
19 // 0180-024F: Latin Extended-B
20 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
21 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
22 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
23 0xff, 0xff,
24 // 0250–02AF: IPA Extensions
25 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
26 0xff, 0xff, 0xff, 0xff,
27 // 02B0–02FF: Spacing Modifier Letters
28 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
29 0x00, 0x00,
30 // 0300–036F: Combining Diacritical Marks
31 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
32 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
33 // 0370–03FF: Greek and Coptic
34 0xcf, 0x00, 0x40, 0x7d, 0xff, 0xff, 0xfb, 0xff,
35 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
36 0xff, 0xff, 0xff, 0xff,
37 // 0400–04FF: Cyrillic
38 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
39 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
40 0x03, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
41 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
42 };
43
44 /**
45 * Returns whether a given unicode character is an alphabetic character.
46 */
47 bool isAlpha (int ch)
48 {
49 return ch < 0x500 && (alpha[ch / 8] & (1 << (ch & 7)));
50 }
51
52 int decodeUtf8 (const char *s)
53 {
54 if((s[0] & 0x80) == 0)
55 return s[0];
56 else if((s[0] & 0xe0) == 0xc0 && (s[1] & 0xc0) == 0x80)
57 return ((s[0] & 0x1f) << 6) | (s[1] & 0x3f);
58 else if((s[0] & 0xf0) == 0xe0 && (s[1] & 0xc0) == 0x80
59 && (s[2] & 0xc0) == 0x80)
60 return ((s[0] & 0x0f) << 12) | ((s[1] & 0x3f) << 6) | (s[2] & 0x3f);
61 else if((s[0] & 0xf8) == 0xf0 && (s[1] & 0xc0) == 0x80
62 && (s[2] & 0xc0) == 0x80 && (s[3] & 0xc0) == 0x80)
63 return ((s[0] & 0x0f) << 18) | ((s[1] & 0x3f) << 12)
64 | ((s[2] & 0x3f) << 6) | (s[3] & 0x3f);
65 else
66 // Treat as ISO-8859-1 / ISO-8859-15 / Windows-1252
67 return s[0];
68 }
69
70
71 int decodeUtf8 (const char *s, int len)
72 {
73 if(len >= 1 && (s[0] & 0x80) == 0)
74 return s[0];
75 else if(len >= 2 && (s[0] & 0xe0) == 0xc0 && (s[1] & 0xc0) == 0x80)
76 return ((s[0] & 0x1f) << 6) | (s[1] & 0x3f);
77 else if(len >= 3 && (s[0] & 0xf0) == 0xe0 && (s[1] & 0xc0) == 0x80
78 && (s[2] & 0xc0) == 0x80)
79 return ((s[0] & 0x0f) << 12) | ((s[1] & 0x3f) << 6) | (s[2] & 0x3f);
80 else if(len >= 4 && (s[0] & 0xf8) == 0xf0 && (s[1] & 0xc0) == 0x80
81 && (s[2] & 0xc0) == 0x80 && (s[3] & 0xc0) == 0x80)
82 return ((s[0] & 0x0f) << 18) | ((s[1] & 0x3f) << 12)
83 | ((s[2] & 0x3f) << 6) | (s[3] & 0x3f);
84 else
85 // Treat as ISO-8859-1 / ISO-8859-15 / Windows-1252
86 return s[0];
87 }
88
89 const char *nextUtf8Char (const char *s)
90 {
91 const char *r;
92
93 if (s == NULL || s[0] == 0)
94 r = NULL;
95 else if((s[0] & 0x80) == 0)
96 r = s + 1;
97 else if((s[0] & 0xe0) == 0xc0 && (s[1] & 0xc0) == 0x80)
98 r = s + 2;
99 else if((s[0] & 0xf0) == 0xe0 && (s[1] & 0xc0) == 0x80
100 && (s[2] & 0xc0) == 0x80)
101 r = s + 3;
102 else if((s[0] & 0xf8) == 0xf0 && (s[1] & 0xc0) == 0x80
103 && (s[2] & 0xc0) == 0x80 && (s[3] & 0xc0) == 0x80)
104 r = s + 4;
105 else
106 // invalid UTF-8 sequence: treat as one byte.
107 r = s + 1;
108
109 if (r && r[0] == 0)
110 return NULL;
111 else
112 return r;
113 }
114
115 const char *nextUtf8Char (const char *s, int len)
116 {
117 const char *r;
118
119 if (s == NULL || len <= 0)
120 r = NULL;
121 else if(len >= 1 && (s[0] & 0x80) == 0)
122 r = s + 1;
123 else if(len >= 2 && (s[0] & 0xe0) == 0xc0 && (s[1] & 0xc0) == 0x80)
124 r = s + 2;
125 else if(len >= 3 && (s[0] & 0xf0) == 0xe0 && (s[1] & 0xc0) == 0x80
126 && (s[2] & 0xc0) == 0x80)
127 r = s + 3;
128 else if(len >= 4 && (s[0] & 0xf8) == 0xf0 && (s[1] & 0xc0) == 0x80
129 && (s[2] & 0xc0) == 0x80 && (s[3] & 0xc0) == 0x80)
130 r = s + 4;
131 else
132 // invalid UTF-8 sequence: treat as one byte.
133 r = s + 1;
134
135 if (r && r - s >= len)
136 return NULL;
137 else
138 return r;
139 }
140
141 int numUtf8Chars (const char *s)
142 {
143 int numUtf8 = 0;
144 for (const char *r = s; r; r = nextUtf8Char (r))
145 numUtf8++;
146 return numUtf8;
147 }
148
149 int numUtf8Chars (const char *s, int len)
150 {
151 int numUtf8 = 0;
152 for (const char *r = s; len > 0 && r; r = nextUtf8Char (r, len))
153 numUtf8++;
154 return numUtf8;
155 }
156
157 } // namespace lout
158
159 } // namespace unicode
0 #ifndef __UNICODE_HH__
1 #define __UNICODE_HH__
2
3 namespace lout {
4
5 /**
6 * \brief Stuff dealing with Unicode characters: UTF-8, character classes etc.
7 *
8 */
9 namespace unicode {
10
11 bool isAlpha (int ch);
12
13 int decodeUtf8 (const char *s);
14
15 int decodeUtf8 (const char *s, int len);
16
17 const char *nextUtf8Char (const char *s);
18
19 const char *nextUtf8Char (const char *s, int len);
20
21 int numUtf8Chars (const char *s);
22
23 int numUtf8Chars (const char *s, int len);
24
25 } // namespace lout
26
27 } // namespace unicode
28
29 #endif // __UNICODE_HH__
00 #! /bin/sh
11 # Common stub for a few missing GNU programs while installing.
22
3 scriptversion=2009-04-28.21; # UTC
3 scriptversion=2012-01-06.13; # UTC
44
55 # Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006,
6 # 2008, 2009 Free Software Foundation, Inc.
6 # 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
77 # Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
88
99 # This program is free software; you can redistribute it and/or modify
8383 help2man touch the output file
8484 lex create \`lex.yy.c', if possible, from existing .c
8585 makeinfo touch the output file
86 tar try tar, gnutar, gtar, then tar without non-portable flags
8786 yacc create \`y.tab.[ch]', if possible, from existing .[ch]
8887
8988 Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and
119118 case $1 in
120119 lex*|yacc*)
121120 # Not GNU programs, they don't have --version.
122 ;;
123
124 tar*)
125 if test -n "$run"; then
126 echo 1>&2 "ERROR: \`tar' requires --run"
127 exit 1
128 elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
129 exit 1
130 fi
131121 ;;
132122
133123 *)
225215 \`Bison' from any GNU archive site."
226216 rm -f y.tab.c y.tab.h
227217 if test $# -ne 1; then
228 eval LASTARG="\${$#}"
218 eval LASTARG=\${$#}
229219 case $LASTARG in
230220 *.y)
231221 SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
255245 \`Flex' from any GNU archive site."
256246 rm -f lex.yy.c
257247 if test $# -ne 1; then
258 eval LASTARG="\${$#}"
248 eval LASTARG=\${$#}
259249 case $LASTARG in
260250 *.l)
261251 SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
317307 touch $file
318308 ;;
319309
320 tar*)
321 shift
322
323 # We have already tried tar in the generic part.
324 # Look for gnutar/gtar before invocation to avoid ugly error
325 # messages.
326 if (gnutar --version > /dev/null 2>&1); then
327 gnutar "$@" && exit 0
328 fi
329 if (gtar --version > /dev/null 2>&1); then
330 gtar "$@" && exit 0
331 fi
332 firstarg="$1"
333 if shift; then
334 case $firstarg in
335 *o*)
336 firstarg=`echo "$firstarg" | sed s/o//`
337 tar "$firstarg" "$@" && exit 0
338 ;;
339 esac
340 case $firstarg in
341 *h*)
342 firstarg=`echo "$firstarg" | sed s/h//`
343 tar "$firstarg" "$@" && exit 0
344 ;;
345 esac
346 fi
347
348 echo 1>&2 "\
349 WARNING: I can't seem to be able to run \`tar' with the given arguments.
350 You may want to install GNU tar or Free paxutils, or check the
351 command line arguments."
352 exit 1
353 ;;
354
355310 *)
356311 echo 1>&2 "\
357312 WARNING: \`$1' is needed, and is $msg.
124124 */
125125 static void IO_close_fd(IOData_t *io, int CloseCode)
126126 {
127 int st;
128127 int events = 0;
129128
130129 _MSG("====> begin IO_close_fd (%d) Key=%d CloseCode=%d Flags=%d ",
134133 * closed! (other clients may set 'IOFlag_ForceClose') */
135134 if (((io->Flags & IOFlag_ForceClose) || (CloseCode == IO_StopRdWr)) &&
136135 io->FD != -1) {
137 do
138 st = close(io->FD);
139 while (st < 0 && errno == EINTR);
136 dClose(io->FD);
140137 } else {
141138 _MSG(" NOT CLOSING ");
142139 }
368365 case OpAbort:
369366 io = Info->LocalKey;
370367 if (io->Buf->len > 0) {
371 MSG_WARN("IO_write, closing with pending data not sent\n");
372 MSG_WARN(" \"%s\"\n", dStr_printable(io->Buf, 2048));
368 char *newline = memchr(io->Buf->str, '\n', io->Buf->len);
369 int msglen = newline ? newline - io->Buf->str : 2048;
370
371 MSG_WARN("IO_write, closing with pending data not sent: "
372 "\"%s\"\n", dStr_printable(io->Buf, msglen));
373373 }
374374 /* close FD, remove from ValidIOs and remove its watch */
375375 IO_close_fd(io, Op == OpEnd ? IO_StopWr : IO_StopRdWr);
0 # Makefile.in generated by automake 1.11.1 from Makefile.am.
0 # Makefile.in generated by automake 1.11.6 from Makefile.am.
11 # @configure_input@
22
33 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
4 # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
5 # Inc.
4 # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
5 # Foundation, Inc.
66 # This Makefile.in is free software; the Free Software Foundation
77 # gives unlimited permission to copy and/or distribute it,
88 # with or without modifications, as long as this notice is preserved.
1515 @SET_MAKE@
1616
1717 VPATH = @srcdir@
18 am__make_dryrun = \
19 { \
20 am__dry=no; \
21 case $$MAKEFLAGS in \
22 *\\[\ \ ]*) \
23 echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
24 | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
25 *) \
26 for am__flg in $$MAKEFLAGS; do \
27 case $$am__flg in \
28 *=*|--*) ;; \
29 *n*) am__dry=yes; break;; \
30 esac; \
31 done;; \
32 esac; \
33 test $$am__dry = yes; \
34 }
1835 pkgdatadir = $(datadir)/@PACKAGE@
1936 pkgincludedir = $(includedir)/@PACKAGE@
2037 pkglibdir = $(libdir)/@PACKAGE@
3754 subdir = src/IO
3855 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
3956 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
40 am__aclocal_m4_deps = $(top_srcdir)/configure.in
57 am__aclocal_m4_deps = $(top_srcdir)/configure.ac
4158 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
4259 $(ACLOCAL_M4)
4360 mkinstalldirs = $(install_sh) -d
6784 -o $@
6885 SOURCES = $(libDiof_a_SOURCES)
6986 DIST_SOURCES = $(libDiof_a_SOURCES)
87 am__can_run_installinfo = \
88 case $$AM_UPDATE_INFO_DIR in \
89 n|no|NO) false;; \
90 *) (install-info --version) >/dev/null 2>&1;; \
91 esac
7092 ETAGS = etags
7193 CTAGS = ctags
7294 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
242264
243265 clean-noinstLIBRARIES:
244266 -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
245 libDiof.a: $(libDiof_a_OBJECTS) $(libDiof_a_DEPENDENCIES)
267 libDiof.a: $(libDiof_a_OBJECTS) $(libDiof_a_DEPENDENCIES) $(EXTRA_libDiof_a_DEPENDENCIES)
246268 -rm -f libDiof.a
247269 $(libDiof_a_AR) libDiof.a $(libDiof_a_OBJECTS) $(libDiof_a_LIBADD)
248270 $(RANLIB) libDiof.a
384406
385407 installcheck: installcheck-am
386408 install-strip:
387 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
388 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
389 `test -z '$(STRIP)' || \
390 echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
409 if test -z '$(STRIP)'; then \
410 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
411 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
412 install; \
413 else \
414 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
415 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
416 "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
417 fi
391418 mostlyclean-generic:
392419
393420 clean-generic:
7474 " <tr>\n"
7575 " <td>&nbsp;&nbsp;\n"
7676 " <td>\n"
77 " <a href='http://hg.dillo.org/dillo/file/tip/ChangeLog'>\n"
77 " <a href='http://hg.dillo.org/dillo/raw-file/tip/ChangeLog'>\n"
7878 " ChangeLog</a>\n"
7979 " <tr>\n"
8080 " <td>&nbsp;&nbsp;\n"
117117 " <td>&nbsp;&nbsp;\n"
118118 " <td>\n"
119119 " <a href='http://slashdot.org/'>Slashdot</a>\n"
120 " <tr>\n"
121 " <td>&nbsp;&nbsp;\n"
122 " <td>\n"
123 " <a href='http://www.linux.org.uk/Portaloo.cs'>Linux.org.uk</a>\n"
124120 " <tr>\n"
125121 " <td>&nbsp;&nbsp;\n"
126122 " <td>\n"
233229 "<tr>\n"
234230 " <td bgcolor='#CCCCCC'>\n"
235231 " <h4>Release overview</h4>\n"
236 " December 05, 2011\n"
232 " April 17, 2013\n"
237233 "<tr>\n"
238234 " <td bgcolor='#FFFFFF'>\n"
239235 " <table border='0' cellspacing='0' cellpadding='5'>\n"
240236 " <tr>\n"
241237 " <td>\n"
242238 "<p>\n"
243 "dillo-3.0.2 brings you some new bits and pieces, as listed below :)\n"
244 "<p>\n"
245 "After this release, the core team plans to focus on implementing the CSS\n"
246 "feature of floating elements. This will <em>greatly</em> improve dillo's\n"
247 "web page rendering since many sites have adopted floats instead of tables.\n"
248 "<p>\n"
249 "Dillo3 uses the FLTK GUI toolkit's 1.3.x series. In June, fltk-1.3.0 was\n"
250 "<a href='http://fltk.org/articles.php?L1086'>released</a>,\n"
251 "clearing the way for Dillo to return to those distributions\n"
239 "dillo-3.0.3 adds some nice new features, as listed below.\n"
240 "<p>\n"
241 "This release comes with <b>configurable UI colors</b> in\n"
242 "<a href='http://www.dillo.org/dillorc'>dillorc</a>.\n"
243 "Packagers should set the theme that better fits the distro, and\n"
244 "end users may tweak freely if they like!\n"
245 "<p>\n"
246 "In order to use the <b>hyphenation</b> feature, pattern files from CTAN\n"
247 "need to be installed. Most probably your packager did it for you. If not\n"
248 "enabled, just follow directions from the README file.\n"
249 "<p>\n"
250 "A new <a href='http://www.dillo.org/domainrc'>domainrc</a> mechanism has\n"
251 "been introduced to provide finer-grained control over automatic requests\n"
252 "for third-party resources, and the old filter_auto_requests dillorc option\n"
253 "has been removed. This makes it easier to block ads and trackers but permit\n"
254 "legitimate use such as wikipedia pulling images from wikimedia.org.\n"
255 "<p>\n"
256 "Dillo3 uses the FLTK GUI toolkit's 1.3.x series, whose release\n"
257 "cleared the way for Dillo to return to those distributions\n"
252258 "which had excluded Dillo2 due to FLTK2 never being officially released.\n"
253259 "<p>\n"
254260 "The core team welcomes developers willing to join our workforce.\n"
265271 " <td bgcolor='#CCCCCC'>\n"
266272 " <h4>ChangeLog highlights</h4>\n"
267273 " (Extracted from the\n"
268 " <a href='http://hg.dillo.org/dillo/file/tip/ChangeLog'>full\n"
274 " <a href='http://hg.dillo.org/dillo/raw-file/tip/ChangeLog'>full\n"
269275 " ChangeLog</a>)\n"
270276 "<tr>\n"
271277 " <td bgcolor='#FFFFFF'>\n"
273279 " <tr>\n"
274280 " <td>\n"
275281 "<ul>\n"
276 "<li>Digest authentication.\n"
277 "<li>Rework line breaking and fix white-space:nowrap handling.\n"
278 "<li>text-transform property.\n"
279 "<li>Locale-independent ASCII character case handling (fixes Turkic locales).\n"
280 "<li>Bind Ctrl-{PageUp,PageDown} to tab-{previous,next}.\n"
282 "<li>Automatic hyphenation (includes penalty_* preferences that control line-breaking).\n"
283 "<li>Added the domainrc mechanism.\n"
284 "<li>Added user interface color preferences (ui_*).\n"
285 "<li>Support for CSS display property.\n"
281286 "</ul>\n"
282287 " </table>\n"
283288 "</table>\n"
8282 void a_Dpi_init(void)
8383 {
8484 /* empty */
85 }
86
87 /*
88 * Close a FD handling EINTR
89 */
90 static void Dpi_close_fd(int fd)
91 {
92 int st;
93
94 dReturn_if (fd < 0);
95 do
96 st = close(fd);
97 while (st < 0 && errno == EINTR);
9885 }
9986
10087 /*
361348 if (pid == 0) {
362349 /* This is the child process. Execute the command. */
363350 char *path1 = dStrconcat(dGethomedir(), "/.dillo/dpid", NULL);
364 Dpi_close_fd(st_pipe[0]);
351 dClose(st_pipe[0]);
365352 if (execl(path1, "dpid", (char*)NULL) == -1) {
366353 dFree(path1);
367354 path1 = dStrconcat(DILLO_BINDIR, "dpid", NULL);
372359 if (Dpi_blocking_write(st_pipe[1], "ERROR", 5) == -1) {
373360 MSG("Dpi_start_dpid (child): can't write to pipe.\n");
374361 }
375 Dpi_close_fd(st_pipe[1]);
362 dClose(st_pipe[1]);
376363 _exit (EXIT_FAILURE);
377364 }
378365 }
381368 /* The fork failed. Report failure. */
382369 MSG("Dpi_start_dpid: %s\n", dStrerror(errno));
383370 /* close the unused pipe */
384 Dpi_close_fd(st_pipe[0]);
385 Dpi_close_fd(st_pipe[1]);
386
371 dClose(st_pipe[0]);
372 dClose(st_pipe[1]);
387373 } else {
388374 /* This is the parent process, check our child status... */
389 Dpi_close_fd(st_pipe[1]);
375 dClose(st_pipe[1]);
390376 if ((answer = Dpi_blocking_read(st_pipe[0])) != NULL) {
391377 MSG("Dpi_start_dpid: can't start dpid\n");
392378 dFree(answer);
393379 } else {
394380 ret = 0;
395381 }
396 Dpi_close_fd(st_pipe[0]);
382 dClose(st_pipe[0]);
397383 }
398384
399385 return ret;
466452 } else if (connect(sock_fd, (struct sockaddr *)&sin, sin_sz) == -1) {
467453 MSG("Dpi_check_dpid_ids: %s\n", dStrerror(errno));
468454 } else {
469 Dpi_close_fd(sock_fd);
455 dClose(sock_fd);
470456 ret = 1;
471457 }
472458 }
602588 dFree(cmd);
603589 }
604590 dFree(rply);
605 Dpi_close_fd(sock_fd);
591 dClose(sock_fd);
606592
607593 return ok ? dpi_port : -1;
608594 }
613599 * We have to ask 'dpid' (dpi daemon) for the port of the target dpi server.
614600 * Once we have it, then the proper file descriptor is returned (-1 on error).
615601 */
616 static int Dpi_connect_socket(const char *server_name, int retry)
602 static int Dpi_connect_socket(const char *server_name)
617603 {
618604 struct sockaddr_in sin;
619 int sock_fd, err, dpi_port, ret=-1;
605 int sock_fd, dpi_port, ret = -1;
620606 char *cmd = NULL;
621607
622608 /* Query dpid for the port number for this server */
635621 if ((sock_fd = Dpi_make_socket_fd()) == -1) {
636622 perror("[dpi::socket]");
637623 } else if (connect(sock_fd, (void*)&sin, sizeof(sin)) == -1) {
638 err = errno;
639 sock_fd = -1;
640624 MSG("[dpi::connect] errno:%d %s\n", errno, dStrerror(errno));
641 if (retry) {
642 switch (err) {
643 case ECONNREFUSED: case EBADF: case ENOTSOCK: case EADDRNOTAVAIL:
644 sock_fd = Dpi_connect_socket(server_name, FALSE);
645 break;
646 }
647 }
648
649 /* send authentication Key (the server closes sock_fd on error) */
625
626 /* send authentication Key (the server closes sock_fd on auth error) */
650627 } else if (!(cmd = a_Dpip_build_cmd("cmd=%s msg=%s", "auth", SharedKey))) {
651628 MSG_ERR("[Dpi_connect_socket] Can't make auth message.\n");
652629 } else if (Dpi_blocking_write(sock_fd, cmd, strlen(cmd)) == -1) {
655632 ret = sock_fd;
656633 }
657634 dFree(cmd);
635 if (sock_fd != -1 && ret == -1) /* can't send cmd? */
636 dClose(sock_fd);
658637
659638 return ret;
660639 }
676655 switch (Op) {
677656 case OpStart:
678657 if ((st = Dpi_blocking_start_dpid()) == 0) {
679 SockFD = Dpi_connect_socket(Data1, TRUE);
680 if (SockFD != -1) {
658 if ((SockFD = Dpi_connect_socket(Data1)) != -1) {
681659 int *fd = dNew(int, 1);
682660 *fd = SockFD;
683661 Info->LocalKey = fd;
684662 a_Chain_link_new(Info, a_Dpi_ccc, BCK, a_IO_ccc, 1, 1);
685663 a_Chain_bcb(OpStart, Info, NULL, NULL);
664 /* Let the FD known and tracked */
665 a_Chain_bcb(OpSend, Info, &SockFD, "FD");
666 a_Chain_fcb(OpSend, Info, &SockFD, "FD");
667 a_Chain_fcb(OpSend, Info, NULL, "DpidOK");
668 } else {
669 a_Dpi_ccc(OpAbort, 1, FWD, Info, NULL, NULL);
686670 }
687 }
688
689 if (st == 0 && SockFD != -1) {
690 a_Chain_bcb(OpSend, Info, &SockFD, "FD");
691 a_Chain_fcb(OpSend, Info, &SockFD, "FD");
692 a_Chain_fcb(OpSend, Info, NULL, "DpidOK");
693671 } else {
694672 MSG_ERR("dpi.c: can't start dpi daemon\n");
695673 a_Dpi_ccc(OpAbort, 1, FWD, Info, NULL, "DpidERROR");
797775 return ret;
798776 }
799777
800 if ((sock_fd = Dpi_connect_socket(server_name, TRUE)) == -1) {
778 if ((sock_fd = Dpi_connect_socket(server_name)) == -1) {
801779 MSG_ERR("[a_Dpi_send_blocking_cmd] Can't connect to server.\n");
802780 } else if (Dpi_blocking_write(sock_fd, cmd, strlen(cmd)) == -1) {
803781 MSG_ERR("[a_Dpi_send_blocking_cmd] Can't send message.\n");
804782 } if ((ret = Dpi_blocking_read(sock_fd)) == NULL) {
805783 MSG_ERR("[a_Dpi_send_blocking_cmd] Can't read message.\n");
806784 }
807 Dpi_close_fd(sock_fd);
785 dClose(sock_fd);
808786
809787 return ret;
810788 }
206206 dFree(S);
207207 }
208208 }
209 }
210
211 /*
212 * Close the socket's FD
213 */
214 static void Http_socket_close(SocketData_t *S)
215 {
216 int st;
217 do
218 st = close(S->SockFD);
219 while (st < 0 && errno == EINTR);
220209 }
221210
222211 /*
447436 status = connect(S->SockFD, (struct sockaddr *)&name, socket_len);
448437 if (status == -1 && errno != EINPROGRESS) {
449438 S->Err = errno;
450 Http_socket_close(S);
439 dClose(S->SockFD);
451440 MSG("Http_connect_socket ERROR: %s\n", dStrerror(S->Err));
452441 } else {
453442 a_Chain_bcb(OpSend, Info, &S->SockFD, "FD");
115115
116116
117117 /*
118 * Call the handler for the MIME type to set Call and Data as appropriate
118 * Get the handler for the MIME type.
119119 *
120120 * Return Value:
121 * On success: a new Dw (and Call and Data properly set).
122 * On failure: NULL (and Call and Data untouched).
121 * On success: viewer
122 * On failure: NULL
123123 */
124 void *a_Mime_set_viewer(const char *content_type, void *Ptr,
125 CA_Callback_t *Call, void **Data)
124 Viewer_t a_Mime_get_viewer(const char *content_type)
126125 {
127
128126 Viewer_t viewer;
129127 uint_t MinSize, MajSize, i;
130128 const char *str = content_type;
136134 }
137135 MinSize = i;
138136
139 /* Try minor type */
140137 viewer = Mime_minor_type_fetch(content_type, MinSize);
141 if (viewer)
142 return viewer(content_type, Ptr, Call, Data);
138 if (!viewer)
139 viewer = Mime_major_type_fetch(content_type, MajSize);
143140
144 /* Try major type */
145 viewer = Mime_major_type_fetch(content_type, MajSize);
146 if (viewer)
147 return viewer(content_type, Ptr, Call, Data);
148
149 /* Type not handled */
150 return NULL;
141 return viewer;
151142 }
4040 * Functions defined inside Mime module
4141 */
4242 void a_Mime_init(void);
43 void *a_Mime_set_viewer(const char *content_type, void *Ptr,
44 CA_Callback_t *Call, void **Data);
43 Viewer_t a_Mime_get_viewer(const char *content_type);
4544
4645 #ifdef __cplusplus
4746 }
2424 dillo.cc \
2525 paths.cc \
2626 paths.hh \
27 tipwin.cc \
28 tipwin.hh \
2729 ui.cc \
2830 ui.hh \
2931 uicmd.cc \
8183 dicache.h \
8284 capi.c \
8385 capi.h \
86 domain.c \
87 domain.h \
8488 css.cc \
8589 css.hh \
8690 cssparser.cc \
120124 xembed.cc \
121125 xembed.hh
122126
123 EXTRA_DIST = chg srch keysrc
124 sysconf_DATA = keysrc
127 dist_sysconf_DATA = domainrc keysrc
128 EXTRA_DIST = chg srch
0 # Makefile.in generated by automake 1.11.1 from Makefile.am.
0 # Makefile.in generated by automake 1.11.6 from Makefile.am.
11 # @configure_input@
22
33 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
4 # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
5 # Inc.
4 # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
5 # Foundation, Inc.
66 # This Makefile.in is free software; the Free Software Foundation
77 # gives unlimited permission to copy and/or distribute it,
88 # with or without modifications, as long as this notice is preserved.
1616
1717
1818 VPATH = @srcdir@
19 am__make_dryrun = \
20 { \
21 am__dry=no; \
22 case $$MAKEFLAGS in \
23 *\\[\ \ ]*) \
24 echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
25 | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
26 *) \
27 for am__flg in $$MAKEFLAGS; do \
28 case $$am__flg in \
29 *=*|--*) ;; \
30 *n*) am__dry=yes; break;; \
31 esac; \
32 done;; \
33 esac; \
34 test $$am__dry = yes; \
35 }
1936 pkgdatadir = $(datadir)/@PACKAGE@
2037 pkgincludedir = $(includedir)/@PACKAGE@
2138 pkglibdir = $(libdir)/@PACKAGE@
3754 target_triplet = @target@
3855 bin_PROGRAMS = dillo$(EXEEXT)
3956 subdir = src
40 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
57 DIST_COMMON = $(dist_sysconf_DATA) $(srcdir)/Makefile.am \
58 $(srcdir)/Makefile.in
4159 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
42 am__aclocal_m4_deps = $(top_srcdir)/configure.in
60 am__aclocal_m4_deps = $(top_srcdir)/configure.ac
4361 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
4462 $(ACLOCAL_M4)
4563 mkinstalldirs = $(install_sh) -d
4866 CONFIG_CLEAN_VPATH_FILES =
4967 am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sysconfdir)"
5068 PROGRAMS = $(bin_PROGRAMS)
51 am_dillo_OBJECTS = dillo.$(OBJEXT) paths.$(OBJEXT) ui.$(OBJEXT) \
52 uicmd.$(OBJEXT) bw.$(OBJEXT) cookies.$(OBJEXT) auth.$(OBJEXT) \
53 md5.$(OBJEXT) digest.$(OBJEXT) colors.$(OBJEXT) misc.$(OBJEXT) \
54 history.$(OBJEXT) prefs.$(OBJEXT) prefsparser.$(OBJEXT) \
55 keys.$(OBJEXT) url.$(OBJEXT) bitvec.$(OBJEXT) klist.$(OBJEXT) \
56 chain.$(OBJEXT) utf8.$(OBJEXT) timeout.$(OBJEXT) \
57 dialog.$(OBJEXT) web.$(OBJEXT) nav.$(OBJEXT) cache.$(OBJEXT) \
58 decode.$(OBJEXT) dicache.$(OBJEXT) capi.$(OBJEXT) \
69 am_dillo_OBJECTS = dillo.$(OBJEXT) paths.$(OBJEXT) tipwin.$(OBJEXT) \
70 ui.$(OBJEXT) uicmd.$(OBJEXT) bw.$(OBJEXT) cookies.$(OBJEXT) \
71 auth.$(OBJEXT) md5.$(OBJEXT) digest.$(OBJEXT) colors.$(OBJEXT) \
72 misc.$(OBJEXT) history.$(OBJEXT) prefs.$(OBJEXT) \
73 prefsparser.$(OBJEXT) keys.$(OBJEXT) url.$(OBJEXT) \
74 bitvec.$(OBJEXT) klist.$(OBJEXT) chain.$(OBJEXT) \
75 utf8.$(OBJEXT) timeout.$(OBJEXT) dialog.$(OBJEXT) \
76 web.$(OBJEXT) nav.$(OBJEXT) cache.$(OBJEXT) decode.$(OBJEXT) \
77 dicache.$(OBJEXT) capi.$(OBJEXT) domain.$(OBJEXT) \
5978 css.$(OBJEXT) cssparser.$(OBJEXT) styleengine.$(OBJEXT) \
6079 plain.$(OBJEXT) html.$(OBJEXT) form.$(OBJEXT) table.$(OBJEXT) \
6180 bookmark.$(OBJEXT) dns.$(OBJEXT) gif.$(OBJEXT) jpeg.$(OBJEXT) \
89108 install-pdf-recursive install-ps-recursive install-recursive \
90109 installcheck-recursive installdirs-recursive pdf-recursive \
91110 ps-recursive uninstall-recursive
111 am__can_run_installinfo = \
112 case $$AM_UPDATE_INFO_DIR in \
113 n|no|NO) false;; \
114 *) (install-info --version) >/dev/null 2>&1;; \
115 esac
92116 am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
93117 am__vpath_adj = case $$p in \
94118 $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
110134 am__base_list = \
111135 sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
112136 sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
113 DATA = $(sysconf_DATA)
137 am__uninstall_files_from_dir = { \
138 test -z "$$files" \
139 || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
140 || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
141 $(am__cd) "$$dir" && rm -f $$files; }; \
142 }
143 DATA = $(dist_sysconf_DATA)
114144 RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
115145 distclean-recursive maintainer-clean-recursive
116146 AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
285315 dillo.cc \
286316 paths.cc \
287317 paths.hh \
318 tipwin.cc \
319 tipwin.hh \
288320 ui.cc \
289321 ui.hh \
290322 uicmd.cc \
342374 dicache.h \
343375 capi.c \
344376 capi.h \
377 domain.c \
378 domain.h \
345379 css.cc \
346380 css.hh \
347381 cssparser.cc \
381415 xembed.cc \
382416 xembed.hh
383417
384 EXTRA_DIST = chg srch keysrc
385 sysconf_DATA = keysrc
418 dist_sysconf_DATA = domainrc keysrc
419 EXTRA_DIST = chg srch
386420 all: all-recursive
387421
388422 .SUFFIXES:
419453 $(am__aclocal_m4_deps):
420454 install-binPROGRAMS: $(bin_PROGRAMS)
421455 @$(NORMAL_INSTALL)
422 test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
423456 @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
457 if test -n "$$list"; then \
458 echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
459 $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
460 fi; \
424461 for p in $$list; do echo "$$p $$p"; done | \
425462 sed 's/$(EXEEXT)$$//' | \
426463 while read p p1; do if test -f $$p; \
454491
455492 clean-binPROGRAMS:
456493 -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
457 dillo$(EXEEXT): $(dillo_OBJECTS) $(dillo_DEPENDENCIES)
494 dillo$(EXEEXT): $(dillo_OBJECTS) $(dillo_DEPENDENCIES) $(EXTRA_dillo_DEPENDENCIES)
458495 @rm -f dillo$(EXEEXT)
459496 $(CXXLINK) $(dillo_OBJECTS) $(dillo_LDADD) $(LIBS)
460497
481518 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/digest.Po@am__quote@
482519 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dillo.Po@am__quote@
483520 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dns.Po@am__quote@
521 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/domain.Po@am__quote@
484522 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dpiapi.Po@am__quote@
485523 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findbar.Po@am__quote@
486524 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/form.Po@am__quote@
504542 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/styleengine.Po@am__quote@
505543 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/table.Po@am__quote@
506544 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/timeout.Po@am__quote@
545 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tipwin.Po@am__quote@
507546 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ui.Po@am__quote@
508547 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uicmd.Po@am__quote@
509548 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/url.Po@am__quote@
538577 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
539578 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
540579 @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
541 install-sysconfDATA: $(sysconf_DATA)
580 install-dist_sysconfDATA: $(dist_sysconf_DATA)
542581 @$(NORMAL_INSTALL)
543 test -z "$(sysconfdir)" || $(MKDIR_P) "$(DESTDIR)$(sysconfdir)"
544 @list='$(sysconf_DATA)'; test -n "$(sysconfdir)" || list=; \
582 @list='$(dist_sysconf_DATA)'; test -n "$(sysconfdir)" || list=; \
583 if test -n "$$list"; then \
584 echo " $(MKDIR_P) '$(DESTDIR)$(sysconfdir)'"; \
585 $(MKDIR_P) "$(DESTDIR)$(sysconfdir)" || exit 1; \
586 fi; \
545587 for p in $$list; do \
546588 if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
547589 echo "$$d$$p"; \
551593 $(INSTALL_DATA) $$files "$(DESTDIR)$(sysconfdir)" || exit $$?; \
552594 done
553595
554 uninstall-sysconfDATA:
596 uninstall-dist_sysconfDATA:
555597 @$(NORMAL_UNINSTALL)
556 @list='$(sysconf_DATA)'; test -n "$(sysconfdir)" || list=; \
598 @list='$(dist_sysconf_DATA)'; test -n "$(sysconfdir)" || list=; \
557599 files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
558 test -n "$$files" || exit 0; \
559 echo " ( cd '$(DESTDIR)$(sysconfdir)' && rm -f" $$files ")"; \
560 cd "$(DESTDIR)$(sysconfdir)" && rm -f $$files
600 dir='$(DESTDIR)$(sysconfdir)'; $(am__uninstall_files_from_dir)
561601
562602 # This directory's subdirectories are mostly independent; you can cd
563603 # into them and run `make' without going through this Makefile.
726766 done
727767 @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
728768 if test "$$subdir" = .; then :; else \
729 test -d "$(distdir)/$$subdir" \
730 || $(MKDIR_P) "$(distdir)/$$subdir" \
731 || exit 1; \
732 fi; \
733 done
734 @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
735 if test "$$subdir" = .; then :; else \
769 $(am__make_dryrun) \
770 || test -d "$(distdir)/$$subdir" \
771 || $(MKDIR_P) "$(distdir)/$$subdir" \
772 || exit 1; \
736773 dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
737774 $(am__relativize); \
738775 new_distdir=$$reldir; \
770807
771808 installcheck: installcheck-recursive
772809 install-strip:
773 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
774 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
775 `test -z '$(STRIP)' || \
776 echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
810 if test -z '$(STRIP)'; then \
811 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
812 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
813 install; \
814 else \
815 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
816 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
817 "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
818 fi
777819 mostlyclean-generic:
778820
779821 clean-generic:
813855
814856 install-dvi-am:
815857
816 install-exec-am: install-binPROGRAMS install-sysconfDATA
858 install-exec-am: install-binPROGRAMS install-dist_sysconfDATA
817859
818860 install-html: install-html-recursive
819861
852894
853895 ps-am:
854896
855 uninstall-am: uninstall-binPROGRAMS uninstall-sysconfDATA
897 uninstall-am: uninstall-binPROGRAMS uninstall-dist_sysconfDATA
856898
857899 .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \
858900 install-am install-strip tags-recursive
862904 clean-generic ctags ctags-recursive distclean \
863905 distclean-compile distclean-generic distclean-tags distdir dvi \
864906 dvi-am html html-am info info-am install install-am \
865 install-binPROGRAMS install-data install-data-am install-dvi \
866 install-dvi-am install-exec install-exec-am install-html \
867 install-html-am install-info install-info-am install-man \
868 install-pdf install-pdf-am install-ps install-ps-am \
869 install-strip install-sysconfDATA installcheck installcheck-am \
870 installdirs installdirs-am maintainer-clean \
871 maintainer-clean-generic mostlyclean mostlyclean-compile \
872 mostlyclean-generic pdf pdf-am ps ps-am tags tags-recursive \
873 uninstall uninstall-am uninstall-binPROGRAMS \
874 uninstall-sysconfDATA
907 install-binPROGRAMS install-data install-data-am \
908 install-dist_sysconfDATA install-dvi install-dvi-am \
909 install-exec install-exec-am install-html install-html-am \
910 install-info install-info-am install-man install-pdf \
911 install-pdf-am install-ps install-ps-am install-strip \
912 installcheck installcheck-am installdirs installdirs-am \
913 maintainer-clean maintainer-clean-generic mostlyclean \
914 mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \
915 tags tags-recursive uninstall uninstall-am \
916 uninstall-binPROGRAMS uninstall-dist_sysconfDATA
875917
876918
877919 # Tell versions [3.59,3.63) of GNU make to not export all variables.
618618 const DilloUrl *url)
619619 {
620620 int ret;
621 char *message;
621 char *title, *msg;
622622 AuthDialogData_t *data;
623623 const char *typestr = auth_parse->type == DIGEST ? "Digest" : "Basic";
624624
625625 _MSG("auth.c: Auth_do_auth_dialog: realm = '%s'\n", auth_parse->realm);
626626
627 message = dStrconcat("The server at ", URL_HOST(url), " requires a username"
628 " and password for \"", auth_parse->realm, "\".\n\n"
629 "Authentication scheme: ", typestr, NULL);
627 title = dStrconcat("Dillo: Password for ", auth_parse->realm, NULL);
628 msg = dStrconcat("The server at ", URL_HOST(url), " requires a username"
629 " and password for \"", auth_parse->realm, "\".\n\n"
630 "Authentication scheme: ", typestr, NULL);
630631 data = dNew(AuthDialogData_t, 1);
631632 data->auth_parse = auth_parse;
632633 data->url = a_Url_dup(url);
633 ret = a_Dialog_user_password(message, Auth_do_auth_dialog_cb, data);
634 dFree(message);
634 ret = a_Dialog_user_password(title, msg, Auth_do_auth_dialog_cb, data);
635 dFree(title); dFree(msg);
635636 a_Url_free((void *)data->url);
636637 dFree(data);
637638 return ret;
55 #define BVEC_TYPE uchar_t
66 #define BVEC_SIZE sizeof(BVEC_TYPE)
77
8 typedef struct _bitvec bitvec_t;
9
10 struct _bitvec {
8 typedef struct {
119 BVEC_TYPE *vec;
1210 int len; /* number of bits [1 based] */
13 };
11 } bitvec_t;
1412
1513
1614 /*
1010 #define BW_Force (4) /* Stop connection too */
1111
1212
13 typedef struct _BrowserWindow BrowserWindow;
14
15
1613 /* browser_window contains the specific data for a single window */
17 struct _BrowserWindow
18 {
14 typedef struct {
1915 /* Pointer to the UI object this bw belongs to */
2016 void *ui;
2117
6056 /* HTML-bugs detected at parse time */
6157 int num_page_bugs;
6258 Dstr *page_bugs;
63 };
59 } BrowserWindow;
6460
6561
6662 #ifdef __cplusplus
1414
1515 #include <sys/types.h>
1616
17 #include <limits.h>
1718 #include <stdlib.h>
1819 #include <string.h>
1920
2829 #include "capi.h"
2930 #include "decode.h"
3031 #include "auth.h"
31
32 #include "domain.h"
3233 #include "timeout.hh"
3334 #include "uicmd.hh"
34
35 #define NULLKey 0
3635
3736 /* Maximum initial size for the automatically-growing data buffer */
3837 #define MAX_INIT_BUF 1024*1024
141140 static int ClientKey = 0; /* Provide a primary key for each client */
142141 CacheClient_t *NewClient;
143142
144 if (++ClientKey <= 0)
143 if (ClientKey < INT_MAX) /* check for integer overflow */
144 ClientKey++;
145 else
145146 ClientKey = 1;
146147
147148 NewClient = dNew(CacheClient_t, 1);
170171 /*
171172 * Remove a client from the queue
172173 */
173 static void Cache_client_dequeue(CacheClient_t *Client, int Key)
174 {
175 if (!Client) {
176 Client = dList_find_custom(ClientQueue, INT2VOIDP(Key),
177 Cache_client_by_key_cmp);
178 }
174 static void Cache_client_dequeue(CacheClient_t *Client)
175 {
179176 if (Client) {
180177 dList_remove(ClientQueue, Client);
181178 a_Web_free(Client->Web);
235232 break;
236233 }
237234 /* Test for a working redirection */
238 if (entry && entry->Flags & CA_Redirect && entry->Location) {
235 if (entry->Flags & CA_Redirect && entry->Location) {
239236 Url = entry->Location;
240237 } else
241238 break;
678675 /* 30x: URL redirection */
679676 DilloUrl *location_url = a_Url_new(location_str,URL_STR_(entry->Url));
680677
681 if (prefs.filter_auto_requests == PREFS_FILTER_SAME_DOMAIN &&
682 !a_Url_same_organization(entry->Url, location_url)) {
678 if (!a_Domain_permit(entry->Url, location_url)) {
683679 /* don't redirect; just show body like usual (if any) */
684680 MSG("Redirection not followed from %s to %s\n",
685681 URL_HOST(entry->Url), URL_STR(location_url));
908904 }
909905 if ((entry->Flags & CA_GotLength) &&
910906 (entry->ExpectedSize != entry->TransferSize)) {
911 MSG_HTTP("Content-Length does NOT match message body,\n"
912 " at: %s\n", URL_STR_(entry->Url));
913 MSG("entry->ExpectedSize = %d, entry->TransferSize = %d\n",
907 MSG_HTTP("Content-Length does NOT match message body at\n"
908 "%s\n", URL_STR_(entry->Url));
909 MSG("Expected size: %d, Transfer size: %d\n",
914910 entry->ExpectedSize, entry->TransferSize);
915911 }
916912 if (!entry->TransferSize && !(entry->Flags & CA_Redirect) &&
11991195 if (ClientWeb->flags & WEB_RootUrl)
12001196 a_Nav_cancel_expect_if_eq(Client_bw, Client->Url);
12011197 a_Bw_remove_client(Client_bw, Client->Key);
1202 Cache_client_dequeue(Client, NULLKey);
1198 Cache_client_dequeue(Client);
12031199 --i; /* Keep the index value in the next iteration */
12041200 continue;
12051201 }
12291225 (Client->Callback)(CA_Close, Client);
12301226 if (ClientWeb->flags & WEB_RootUrl)
12311227 a_UIcmd_set_page_prog(Client_bw, 0, 0);
1232 Cache_client_dequeue(Client, NULLKey);
1228 Cache_client_dequeue(Client);
12331229 --i; /* Keep the index value in the next iteration */
12341230
12351231 /* within CA_GotData, we assert just one redirect call */
13471343 dList_remove(DelayedQueue, entry);
13481344
13491345 /* Main queue */
1350 Cache_client_dequeue(Client, NULLKey);
1346 Cache_client_dequeue(Client);
13511347
13521348 } else {
13531349 _MSG("WARNING: Cache_stop_client, nonexistent client\n");
13651361
13661362 /* free the client queue */
13671363 while ((Client = dList_nth_data(ClientQueue, 0)))
1368 Cache_client_dequeue(Client, NULLKey);
1364 Cache_client_dequeue(Client);
13691365
13701366 /* Remove every cache entry */
13711367 while ((data = dList_nth_data(CachedURLs, 0))) {
3333 #define CA_HugeFile 0x1000 /* URL content is too big */
3434 #define CA_IsEmpty 0x2000 /* True until a byte of content arrives */
3535
36 typedef struct CacheClient CacheClient_t;
37
3638 /*
3739 * Callback type for cache clients
3840 */
39 typedef struct _CacheClient CacheClient_t;
4041 typedef void (*CA_Callback_t)(int Op, CacheClient_t *Client);
4142
4243 /*
4344 * Data structure for cache clients.
4445 */
45 struct _CacheClient {
46 struct CacheClient {
4647 int Key; /* Primary Key for this client */
4748 const DilloUrl *Url; /* Pointer to a cache entry Url */
4849 int Version; /* Dicache version of this Url (0 if not used) */
2525 #include "nav.h"
2626 #include "dpiapi.h"
2727 #include "uicmd.hh"
28 #include "domain.h"
2829 #include "../dpip/dpip.h"
2930
3031 /* for testing dpi chat */
300301 /* Let's be kind and make the HTTP query string for the dpi */
301302 char *proxy_connect = a_Http_make_connect_str(web->url);
302303 Dstr *http_query = a_Http_make_query_str(web->url, web->requester,FALSE);
303 /* BUG: embedded NULLs in query data will truncate message */
304
305 if ((uint_t) http_query->len > strlen(http_query->str)) {
306 /* Can't handle NULLs embedded in query data */
307 MSG_ERR("HTTPS query truncated!\n");
308 }
304309
305310 /* BUG: WORKAROUND: request to only check the root URL's certificate.
306311 * This avoids the dialog bombing that stems from loading multiple
362367 }
363368
364369 /*
365 * When dillo wants to open an URL, this can be either due to user action
366 * (e.g., typing in an URL, clicking a link), or automatic (HTTP header
367 * indicates redirection, META HTML tag with refresh attribute and 0 delay,
368 * and images and stylesheets on an HTML page when autoloading is enabled).
369 *
370 * For a user request, the action will be permitted.
371 * For an automatic request, permission to load depends on the filter set
372 * by the user.
373 */
374 static bool_t Capi_filters_test(const DilloUrl *wanted,
375 const DilloUrl *requester)
376 {
377 bool_t ret;
378
379 if (requester == NULL) {
380 /* request made by user */
381 ret = TRUE;
382 } else {
383 switch (prefs.filter_auto_requests) {
384 case PREFS_FILTER_SAME_DOMAIN:
385 {
386 const char *req_host = URL_HOST(requester),
387 *want_host = URL_HOST(wanted);
388 if (want_host[0] == '\0') {
389 ret = (req_host[0] == '\0' ||
390 !dStrAsciiCasecmp(URL_SCHEME(wanted), "data"))
391 ? TRUE : FALSE;
392 } else {
393 /* This will regard "www.dillo.org" and "www.dillo.org." as
394 * different, but it doesn't seem worth caring about.
395 */
396 ret = a_Url_same_organization(wanted, requester);
397 }
398 if (ret == FALSE) {
399 MSG("Capi_filters_test: deny from '%s' to '%s'\n", req_host,
400 want_host);
401 }
402 break;
403 }
404 case PREFS_FILTER_ALLOW_ALL:
405 default:
406 ret = TRUE;
407 break;
408 }
409 }
410 return ret;
411 }
412
413 /*
414370 * Most used function for requesting a URL.
415371 * TODO: clean up the ad-hoc bindings with an API that allows dynamic
416372 * addition of new plugins.
426382 const char *scheme = URL_SCHEME(web->url);
427383 int safe = 0, ret = 0, use_cache = 0;
428384
429 dReturn_val_if_fail((a_Capi_get_flags(web->url) & CAPI_IsCached) ||
430 Capi_filters_test(web->url, web->requester), 0);
385 /* web->requester is NULL if the action is initiated by user */
386 if (!(a_Capi_get_flags(web->url) & CAPI_IsCached ||
387 web->requester == NULL ||
388 a_Domain_permit(web->requester, web->url))) {
389 return 0;
390 }
431391
432392 /* reload test */
433393 reload = (!(a_Capi_get_flags(web->url) & CAPI_IsCached) ||
449409 cmd = Capi_dpi_build_cmd(web, server);
450410 a_Capi_dpi_send_cmd(web->url, web->bw, cmd, server, 1);
451411 dFree(cmd);
412 } else {
413 MSG_WARN("Ignoring download request for '%s': "
414 "not in cache and not downloadable.\n",
415 URL_STR(web->url));
452416 }
453417
454418 } else if (Capi_url_uses_dpi(web->url, &server)) {
2828 #define FWD 1
2929 #define BCK 2
3030
31
32 typedef struct _ChainLink ChainLink;
33 typedef struct _DataBuf DataBuf;
31 typedef struct ChainLink ChainLink;
3432 typedef void (*ChainFunction_t)(int Op, int Branch, int Dir, ChainLink *Info,
3533 void *Data1, void *Data2);
3634
3735 /* This is the main data structure for CCC nodes */
38 struct _ChainLink {
36 struct ChainLink {
3937 void *LocalKey;
4038
4139 int Flags;
5048 };
5149
5250 /* A convenience data structure for passing data chunks between nodes */
53 struct _DataBuf {
51 typedef struct {
5452 char *Buf;
5553 int Size;
5654 int Code;
57 };
55 } DataBuf;
5856
5957
6058
200200 #endif
201201 };
202202
203 #define NCOLORS (sizeof(color_keyword) / sizeof(struct key))
203 #define NCOLORS (sizeof(color_keyword) / sizeof(color_keyword[0]))
204204
205205 /*
206206 * Parse a color in hex (RRGGBB) or (RGB)
230230 }
231231
232232 /*
233 * Parse the color info from a subtag.
234 * If subtag string begins with # or with 0x simply return the color number
235 * otherwise search one color from the set of named colors.
233 * Parse a color string.
234 *
235 * - If the string begins with # or with 0x, return the color number
236 * (with 'RGB' expanded to 'RRGGBB').
237 * - Else search the set of named colors.
238 * - As a last resort, treat it as bare hex as in the first case.
236239 *
237240 * Return Value:
238241 * Parsed color if successful,
239 * default_color (+ error code) on error.
240 */
241 int32_t a_Color_parse (const char *subtag, int32_t default_color, int *err)
242 * default_color on error.
243 *
244 * "err" argument:
245 * 0 if a color beginning with '#' is successfully parsed
246 * or the color is a recognized word.
247 * 1 if the color is bare hex or can't be parsed at all.
248 * 2 if a color beginning with 0[xX] is successfully parsed.
249 */
250 int32_t a_Color_parse (const char *str, int32_t default_color, int *err)
242251 {
243252 const char *cp;
244253 int32_t ret_color;
245254 int ret, low, mid, high, st = 1;
246255
247256 /* skip leading spaces */
248 for (cp = subtag; dIsspace(*cp); cp++);
257 for (cp = str; dIsspace(*cp); cp++);
249258
250259 ret_color = default_color;
251260 if (*cp == '#') {
253262
254263 } else if (*cp == '0' && (cp[1] == 'x' || cp[1] == 'X') ) {
255264 ret_color = Color_parse_hex(cp + 2, default_color, &st);
256 st = 2;
257
265 if (!st)
266 st = 2;
258267 } else {
259268 /* Binary search */
260269 low = 0;
279288 }
280289 }
281290
282 _MSG("subtag: %s\n", subtag);
291 _MSG("color string: %s\n", str);
283292 _MSG("color : %X\n", ret_color);
284293
285294 *err = st;
77 extern "C" {
88 #endif /* __cplusplus */
99
10 int32_t a_Color_parse (const char *subtag, int32_t default_color, int *err);
10 int32_t a_Color_parse (const char *str, int32_t default_color, int *err);
1111 int32_t a_Color_vc(int32_t candidate, int32_t c1, int32_t c2, int32_t c3);
1212
1313 #ifdef __cplusplus
8989 filename, dStrerror(errno));
9090 }
9191 }
92 close(fd);
92 dClose(fd);
9393
9494 MSG("Cookies: Created file: %s\n", filename);
9595 F_in = fopen(filename, "r");
259259 if (!rc && ferror(stream)) {
260260 MSG("Cookies1: Error while reading rule from cookiesrc: %s\n",
261261 dStrerror(errno));
262 fclose(stream);
262263 return 2; /* bail out */
263264 }
264265
1010
1111 #include <stdio.h>
1212 #include "../dlib/dlib.h"
13 #include "misc.h"
1413 #include "msg.h"
1514 #include "html_common.hh"
1615 #include "css.hh"
17 #include "cssparser.hh"
1816
1917 using namespace dw::core::style;
2018
2826 lout::misc::SimpleVector <CssProperty> (p)
2927 {
3028 refCount = 0;
29 safe = p.safe;
3130 if (deep) {
3231 for (int i = 0; i < size (); i++) {
3332 CssProperty *p = getRef(i);
4443 } else {
4544 ownerOfStrings = false;
4645 }
47 };
46 }
4847
4948 CssPropertyList::~CssPropertyList () {
5049 if (ownerOfStrings)
5857 void CssPropertyList::set (CssPropertyName name, CssValueType type,
5958 CssPropertyValue value) {
6059 CssProperty *prop;
60
61 if (name == CSS_PROPERTY_DISPLAY || name == CSS_PROPERTY_BACKGROUND_IMAGE)
62 safe = false;
6163
6264 for (int i = 0; i < size (); i++) {
6365 prop = getRef (i);
8284 * \brief Merge properties into argument property list.
8385 */
8486 void CssPropertyList::apply (CssPropertyList *props) {
85 for (int i = 0; i < size (); i++)
87 for (int i = 0; i < size (); i++) {
88 CssPropertyValue value = getRef (i)->value;
89
90 if (props->ownerOfStrings &&
91 (getRef (i)->type == CSS_TYPE_STRING ||
92 getRef (i)->type == CSS_TYPE_SYMBOL))
93 value.strVal = strdup(value.strVal);
94
8695 props->set ((CssPropertyName) getRef (i)->name,
8796 (CssValueType) getRef (i)->type,
88 getRef (i)->value);
97 value);
98 }
8999 }
90100
91101 void CssPropertyList::print () {
103113 cs = selectorList->getRef (selectorList->size () - 1);
104114
105115 cs->notMatchingBefore = -1;
106 cs->combinator = CHILD;
116 cs->combinator = COMB_NONE;
107117 cs->selector = new CssSimpleSelector ();
108 };
118 }
109119
110120 CssSelector::~CssSelector () {
111121 for (int i = selectorList->size () - 1; i >= 0; i--)
116126 /**
117127 * \brief Return whether selector matches at a given node in the document tree.
118128 */
119 bool CssSelector::match (Doctree *docTree, const DoctreeNode *node) {
120 CssSimpleSelector *sel;
121 Combinator comb = CHILD;
122 int *notMatchingBefore;
123 const DoctreeNode *n;
124
125 for (int i = selectorList->size () - 1; i >= 0; i--) {
126 struct CombinatorAndSelector *cs = selectorList->getRef (i);
127
128 sel = cs->selector;
129 notMatchingBefore = &cs->notMatchingBefore;
130
131 if (node == NULL)
129 bool CssSelector::match (Doctree *docTree, const DoctreeNode *node,
130 int i, Combinator comb) {
131 assert (node);
132
133 if (i < 0)
134 return true;
135
136 struct CombinatorAndSelector *cs = selectorList->getRef (i);
137 CssSimpleSelector *sel = cs->selector;
138
139 switch (comb) {
140 case COMB_NONE:
141 break;
142 case COMB_CHILD:
143 node = docTree->parent (node);
144 break;
145 case COMB_ADJACENT_SIBLING:
146 node = docTree->sibling (node);
147 break;
148 case COMB_DESCENDANT:
149 node = docTree->parent (node);
150
151 for (const DoctreeNode *n = node;
152 n && n->num > cs->notMatchingBefore; n = docTree->parent (n))
153 if (sel->match (n) && match (docTree, n, i - 1, cs->combinator))
154 return true;
155
156 if (node) // remember that it didn't match to avoid future tests
157 cs->notMatchingBefore = node->num;
158
132159 return false;
133
134 switch (comb) {
135 case CHILD:
136 case ADJACENT_SIBLING:
137 if (!sel->match (node))
138 return false;
139 break;
140 case DESCENDANT:
141 n = node;
142
143 while (true) {
144 if (node == NULL || node->num <= *notMatchingBefore) {
145 *notMatchingBefore = n->num;
146 return false;
147 }
148
149 if (sel->match (node))
150 break;
151
152 node = docTree->parent (node);
153 }
154 break;
155 default:
156 return false; // \todo implement other combinators
157 }
158
159 comb = cs->combinator;
160
161 if (comb == ADJACENT_SIBLING)
162 node = docTree->sibling (node);
163 else
164 node = docTree->parent (node);
165 }
166
167 return true;
160 break;
161 default:
162 return false; // \todo implement other combinators
163 }
164
165 if (!node || !sel->match (node))
166 return false;
167
168 // tail recursion should be optimized by the compiler
169 return match (docTree, node, i - 1, cs->combinator);
168170 }
169171
170172 void CssSelector::addSimpleSelector (Combinator c) {
178180 cs->selector = new CssSimpleSelector ();
179181 }
180182
183 bool CssSelector::checksPseudoClass () {
184 for (int i = 0; i < selectorList->size (); i++)
185 if (selectorList->getRef (i)->selector->getPseudoClass ())
186 return true;
187 return false;
188 }
189
181190 /**
182191 * \brief Return the specificity of the selector.
183192 *
199208
200209 if (i < selectorList->size () - 1) {
201210 switch (selectorList->getRef (i + 1)->combinator) {
202 case CHILD:
211 case COMB_CHILD:
203212 fprintf (stderr, "> ");
204213 break;
205 case DESCENDANT:
214 case COMB_DESCENDANT:
206215 fprintf (stderr, "\" \" ");
207216 break;
208 case ADJACENT_SIBLING:
217 case COMB_ADJACENT_SIBLING:
209218 fprintf (stderr, "+ ");
210219 break;
211220 default:
261270 * the document tree.
262271 */
263272 bool CssSimpleSelector::match (const DoctreeNode *n) {
273 assert (n);
264274 if (element != ELEMENT_ANY && element != n->element)
265275 return false;
266276 if (pseudo != NULL &&
326336 this->props->ref ();
327337 this->pos = pos;
328338 spec = selector->specificity ();
329 };
339 }
330340
331341 CssRule::~CssRule () {
332342 selector->unref ();
333343 props->unref ();
334 };
344 }
335345
336346 void CssRule::apply (CssPropertyList *props,
337347 Doctree *docTree, const DoctreeNode *node) {
363373 *getRef (i) = rule;
364374 }
365375
366 CssStyleSheet::CssStyleSheet () {
367 for (int i = 0; i < ntags; i++)
368 elementTable[i] = new RuleList ();
369
370 idTable = new RuleMap ();
371 classTable = new RuleMap ();
372 anyTable = new RuleList ();
373 }
374
375 CssStyleSheet::~CssStyleSheet () {
376 for (int i = 0; i < ntags; i++)
377 delete elementTable[i];
378 delete idTable;
379 delete classTable;
380 delete anyTable;
381 }
382
383376 /**
384377 * \brief Insert a rule into CssStyleSheet.
385378 *
393386
394387 if (top->getId ()) {
395388 string = new lout::object::ConstString (top->getId ());
396 ruleList = idTable->get (string);
389 ruleList = idTable.get (string);
397390 if (ruleList == NULL) {
398391 ruleList = new RuleList ();
399 idTable->put (string, ruleList);
392 idTable.put (string, ruleList);
400393 } else {
401394 delete string;
402395 }
403396 } else if (top->getClass () && top->getClass ()->size () > 0) {
404397 string = new lout::object::ConstString (top->getClass ()->get (0));
405 ruleList = classTable->get (string);
398 ruleList = classTable.get (string);
406399 if (ruleList == NULL) {
407400 ruleList = new RuleList;
408 classTable->put (string, ruleList);
401 classTable.put (string, ruleList);
409402 } else {
410403 delete string;
411404 }
412405 } else if (top->getElement () >= 0 && top->getElement () < ntags) {
413 ruleList = elementTable[top->getElement ()];
406 ruleList = &elementTable[top->getElement ()];
414407 } else if (top->getElement () == CssSimpleSelector::ELEMENT_ANY) {
415 ruleList = anyTable;
408 ruleList = &anyTable;
416409 }
417410
418411 if (ruleList) {
438431 if (node->id) {
439432 lout::object::ConstString idString (node->id);
440433
441 ruleList[numLists] = idTable->get (&idString);
434 ruleList[numLists] = idTable.get (&idString);
442435 if (ruleList[numLists])
443436 numLists++;
444437 }
452445
453446 lout::object::ConstString classString (node->klass->get (i));
454447
455 ruleList[numLists] = classTable->get (&classString);
448 ruleList[numLists] = classTable.get (&classString);
456449 if (ruleList[numLists])
457450 numLists++;
458451 }
459452 }
460453
461 ruleList[numLists] = elementTable[node->element];
454 ruleList[numLists] = &elementTable[node->element];
462455 if (ruleList[numLists])
463456 numLists++;
464457
465 ruleList[numLists] = anyTable;
458 ruleList[numLists] = &anyTable;
466459 if (ruleList[numLists])
467460 numLists++;
468461
476469 int minSpecIndex = -1;
477470
478471 for (int i = 0; i < numLists; i++) {
479 if (ruleList[i] && ruleList[i]->size () > index[i] &&
480 (ruleList[i]->get(index[i])->specificity () < minSpec ||
481 (ruleList[i]->get(index[i])->specificity () == minSpec &&
482 ruleList[i]->get(index[i])->position () < minPos))) {
483
484 minSpec = ruleList[i]->get(index[i])->specificity ();
485 minPos = ruleList[i]->get(index[i])->position ();
472 RuleList *rl = ruleList[i];
473
474 if (rl && rl->size () > index[i] &&
475 (rl->get(index[i])->specificity () < minSpec ||
476 (rl->get(index[i])->specificity () == minSpec &&
477 rl->get(index[i])->position () < minPos))) {
478
479 minSpec = rl->get(index[i])->specificity ();
480 minPos = rl->get(index[i])->position ();
486481 minSpecIndex = i;
487482 }
488483 }
499494
500495 CssContext::CssContext () {
501496 pos = 0;
502
503 memset (sheet, 0, sizeof(sheet));
504 sheet[CSS_PRIMARY_USER_AGENT] = new CssStyleSheet ();
505 sheet[CSS_PRIMARY_USER] = new CssStyleSheet ();
506 sheet[CSS_PRIMARY_USER_IMPORTANT] = new CssStyleSheet ();
507
508 buildUserAgentStyle ();
509 buildUserStyle ();
510 }
511
512 CssContext::~CssContext () {
513 for (int o = CSS_PRIMARY_USER_AGENT; o < CSS_PRIMARY_LAST; o++)
514 delete sheet[o];
515497 }
516498
517499 /**
527509 DoctreeNode *node,
528510 CssPropertyList *tagStyle, CssPropertyList *tagStyleImportant,
529511 CssPropertyList *nonCssHints) {
530 if (sheet[CSS_PRIMARY_USER_AGENT])
531 sheet[CSS_PRIMARY_USER_AGENT]->apply (props, docTree, node);
532
533 if (sheet[CSS_PRIMARY_USER])
534 sheet[CSS_PRIMARY_USER]->apply (props, docTree, node);
512
513 sheet[CSS_PRIMARY_USER_AGENT].apply (props, docTree, node);
514 sheet[CSS_PRIMARY_USER].apply (props, docTree, node);
535515
536516 if (nonCssHints)
537517 nonCssHints->apply (props);
538518
539 if (sheet[CSS_PRIMARY_AUTHOR])
540 sheet[CSS_PRIMARY_AUTHOR]->apply (props, docTree, node);
519 sheet[CSS_PRIMARY_AUTHOR].apply (props, docTree, node);
541520
542521 if (tagStyle)
543522 tagStyle->apply (props);
544523
545 if (sheet[CSS_PRIMARY_AUTHOR_IMPORTANT])
546 sheet[CSS_PRIMARY_AUTHOR_IMPORTANT]->apply (props, docTree, node);
524 sheet[CSS_PRIMARY_AUTHOR_IMPORTANT].apply (props, docTree, node);
547525
548526 if (tagStyleImportant)
549527 tagStyleImportant->apply (props);
550528
551 if (sheet[CSS_PRIMARY_USER_IMPORTANT])
552 sheet[CSS_PRIMARY_USER_IMPORTANT]->apply (props, docTree, node);
529 sheet[CSS_PRIMARY_USER_IMPORTANT].apply (props, docTree, node);
553530 }
554531
555532 void CssContext::addRule (CssSelector *sel, CssPropertyList *props,
558535 if (props->size () > 0) {
559536 CssRule *rule = new CssRule (sel, props, pos++);
560537
561 if (sheet[order] == NULL)
562 sheet[order] = new CssStyleSheet ();
563
564 sheet[order]->addRule (rule);
565 }
566 }
567
568 /**
569 * \brief Create the user agent style.
570 *
571 * The user agent style defines how dillo renders HTML in the absence of
572 * author or user styles.
573 */
574 void CssContext::buildUserAgentStyle () {
575 const char *cssBuf =
576 "body {margin: 5px}"
577 "big {font-size: 1.17em}"
578 "blockquote, dd {margin-left: 40px; margin-right: 40px}"
579 "center {text-align: center}"
580 "dt {font-weight: bolder}"
581 ":link {color: blue; text-decoration: underline; cursor: pointer}"
582 ":visited {color: #800080; text-decoration: underline; cursor: pointer}"
583 "h1, h2, h3, h4, h5, h6, b, strong {font-weight: bolder}"
584 "i, em, cite, address, var {font-style: italic}"
585 ":link img, :visited img {border: 1px solid}"
586 "frameset, ul, ol, dir {margin-left: 40px}"
587 "h1 {font-size: 2em; margin-top: .67em; margin-bottom: 0}"
588 "h2 {font-size: 1.5em; margin-top: .75em; margin-bottom: 0}"
589 "h3 {font-size: 1.17em; margin-top: .83em; margin-bottom: 0}"
590 "h4 {margin-top: 1.12em; margin-bottom: 0}"
591 "h5 {font-size: 0.83em; margin-top: 1.5em; margin-bottom: 0}"
592 "h6 {font-size: 0.75em; margin-top: 1.67em; margin-bottom: 0}"
593 "hr {width: 100%; border: 1px inset}"
594 "li {margin-top: 0.1em}"
595 "pre {white-space: pre}"
596 "ol {list-style-type: decimal}"
597 "ul {list-style-type: disc}"
598 "ul ul {list-style-type: circle}"
599 "ul ul ul {list-style-type: square}"
600 "ul ul ul ul {list-style-type: disc}"
601 "u {text-decoration: underline}"
602 "small, sub, sup {font-size: 0.83em}"
603 "sub {vertical-align: sub}"
604 "sup {vertical-align: super}"
605 "s, strike, del {text-decoration: line-through}"
606 "table {border-spacing: 2px}"
607 "td, th {padding: 2px}"
608 "thead, tbody, tfoot {vertical-align: middle}"
609 "th {font-weight: bolder; text-align: center}"
610 "code, tt, pre, samp, kbd {font-family: monospace}"
611 /* WORKAROUND: Reset font properties in tables as some
612 * pages rely on it (e.g. gmail).
613 * http://developer.mozilla.org/En/Fixing_Table_Inheritance_in_Quirks_Mode
614 * has a detailed description of the issue.
615 */
616 "table, caption {font-size: medium; font-weight: normal}";
617
618 CssParser::parse (NULL, NULL, this, cssBuf, strlen (cssBuf),
619 CSS_ORIGIN_USER_AGENT);
620 }
621
622 void CssContext::buildUserStyle () {
623 Dstr *style;
624 char *filename = dStrconcat(dGethomedir(), "/.dillo/style.css", NULL);
625
626 if ((style = a_Misc_file2dstr(filename))) {
627 CssParser::parse (NULL,NULL,this,style->str, style->len,CSS_ORIGIN_USER);
628 dStr_free (style, 1);
629 }
630 dFree (filename);
631 }
538 if ((order == CSS_PRIMARY_AUTHOR ||
539 order == CSS_PRIMARY_AUTHOR_IMPORTANT) &&
540 !rule->isSafe ()) {
541 MSG_WARN ("Ignoring unsafe author style that might reveal browsing history\n");
542 delete rule;
543 } else {
544 sheet[order].addRule (rule);
545 }
546 }
547 }
222222 CSS_PROPERTY_X_COLSPAN,
223223 CSS_PROPERTY_X_ROWSPAN,
224224 PROPERTY_X_LINK,
225 PROPERTY_X_LANG,
225226 PROPERTY_X_IMG,
226227 PROPERTY_X_TOOLTIP,
227228 CSS_PROPERTY_LAST
296297 class CssPropertyList : public lout::misc::SimpleVector <CssProperty> {
297298 int refCount;
298299 bool ownerOfStrings;
300 bool safe;
299301
300302 public:
301303 inline CssPropertyList(bool ownerOfStrings = false) :
302304 lout::misc::SimpleVector <CssProperty> (1) {
303305 refCount = 0;
306 safe = true;
304307 this->ownerOfStrings = ownerOfStrings;
305308 };
306309 CssPropertyList(const CssPropertyList &p, bool deep = false);
309312 void set (CssPropertyName name, CssValueType type,
310313 CssPropertyValue value);
311314 void apply (CssPropertyList *props);
315 bool isSafe () { return safe; };
312316 void print ();
313317 inline void ref () { refCount++; }
314318 inline void unref () { if (--refCount == 0) delete this; }
354358 class CssSelector {
355359 public:
356360 typedef enum {
357 DESCENDANT,
358 CHILD,
359 ADJACENT_SIBLING,
361 COMB_NONE,
362 COMB_DESCENDANT,
363 COMB_CHILD,
364 COMB_ADJACENT_SIBLING,
360365 } Combinator;
361366
362367 private:
369374 int refCount;
370375 lout::misc::SimpleVector <struct CombinatorAndSelector> *selectorList;
371376
377 bool match (Doctree *dt, const DoctreeNode *node, int i, Combinator comb);
378
372379 public:
373380 CssSelector ();
374381 ~CssSelector ();
377384 return selectorList->getRef (selectorList->size () - 1)->selector;
378385 };
379386 inline int size () { return selectorList->size (); };
380 bool match (Doctree *dt, const DoctreeNode *node);
387 inline bool match (Doctree *dt, const DoctreeNode *node) {
388 return match (dt, node, selectorList->size () - 1, COMB_NONE);
389 };
381390 int specificity ();
391 bool checksPseudoClass ();
382392 void print ();
383393 inline void ref () { refCount++; }
384394 inline void unref () { if (--refCount == 0) delete this; }
402412
403413 void apply (CssPropertyList *props,
404414 Doctree *docTree, const DoctreeNode *node);
415 inline bool isSafe () {
416 return !selector->checksPseudoClass () || props->isSafe ();
417 };
405418 inline int specificity () { return spec; };
406419 inline int position () { return pos; };
407420 void print ();
438451 };
439452
440453 static const int ntags = 90; // \todo replace 90
441 RuleList *elementTable[ntags];
442
443 RuleMap *idTable;
444 RuleMap *classTable;
445 RuleList *anyTable;
446
447 public:
448 CssStyleSheet();
449 ~CssStyleSheet();
454
455 RuleList elementTable[ntags], anyTable;
456 RuleMap idTable, classTable;
457
458 public:
450459 void addRule (CssRule *rule);
451460 void apply (CssPropertyList *props,
452461 Doctree *docTree, const DoctreeNode *node);
457466 */
458467 class CssContext {
459468 private:
460 CssStyleSheet *sheet[CSS_PRIMARY_USER_IMPORTANT + 1];
469 CssStyleSheet sheet[CSS_PRIMARY_USER_IMPORTANT + 1];
461470 int pos;
462471
463 void buildUserAgentStyle ();
464 void buildUserStyle ();
465
466472 public:
467473 CssContext ();
468 ~CssContext ();
469474
470475 void addRule (CssSelector *sel, CssPropertyList *props,
471476 CssPrimaryOrder order);
7070 };
7171
7272 static const char *const Css_display_enum_vals[] = {
73 "block", "inline", "list-item", "none", "table", "table-row-group",
74 "table-header-group", "table-footer-group", "table-row",
73 "block", "inline", "inline-block", "list-item", "none", "table",
74 "table-row-group", "table-header-group", "table-footer-group", "table-row",
7575 "table-cell", NULL
7676 };
7777
411411 };
412412
413413 #define CSS_SHORTHAND_NUM \
414 (sizeof(Css_shorthand_info) / sizeof(CssShorthandInfo))
414 (sizeof(Css_shorthand_info) / sizeof(Css_shorthand_info[0]))
415415
416416 /* ----------------------------------------------------------------------
417417 * Parsing
696696 case CSS_TYPE_LENGTH_PERCENTAGE:
697697 case CSS_TYPE_LENGTH_PERCENTAGE_NUMBER:
698698 case CSS_TYPE_LENGTH:
699 if (tval[0] == '-')
699 if (tval[0] == '-')
700700 return false;
701701 // Fall Through
702702 case CSS_TYPE_SIGNED_LENGTH:
10581058
10591059 CssPropertyName prop;
10601060 CssPropertyValue val, dir_vals[4];
1061 CssValueType dir_types[4];
1061 CssValueType dir_types[4];
10621062 bool found, weight;
10631063 int sh_index, i, j, n;
10641064 int dir_set[4][4] = {
12561256 if (selectType != CssSimpleSelector::SELECT_NONE) {
12571257 nextToken();
12581258 if (spaceSeparated)
1259 return true;
1259 return false;
12601260
12611261 if (ttype == CSS_TK_SYMBOL) {
12621262 selector->setSelect (selectType, tval);
12911291 (tval[0] == ',' || tval[0] == '{')) {
12921292 break;
12931293 } else if (ttype == CSS_TK_CHAR && tval[0] == '>') {
1294 selector->addSimpleSelector (CssSelector::CHILD);
1294 selector->addSimpleSelector (CssSelector::COMB_CHILD);
12951295 nextToken();
12961296 } else if (ttype == CSS_TK_CHAR && tval[0] == '+') {
1297 selector->addSimpleSelector (CssSelector::ADJACENT_SIBLING);
1297 selector->addSimpleSelector (CssSelector::COMB_ADJACENT_SIBLING);
12981298 nextToken();
12991299 } else if (ttype != CSS_TK_END && spaceSeparated) {
1300 selector->addSimpleSelector (CssSelector::DESCENDANT);
1300 selector->addSimpleSelector (CssSelector::COMB_DESCENDANT);
13011301 } else {
13021302 delete selector;
13031303 selector = NULL;
241241 }
242242
243243 /*
244 * Legal names for the ASCII character set
245 */
246 static int Decode_is_ascii(const char *str)
247 {
248 return (!(dStrAsciiCasecmp(str, "ASCII") &&
249 dStrAsciiCasecmp(str, "US-ASCII") &&
250 dStrAsciiCasecmp(str, "us") &&
251 dStrAsciiCasecmp(str, "IBM367") &&
252 dStrAsciiCasecmp(str, "cp367") &&
253 dStrAsciiCasecmp(str, "csASCII") &&
254 dStrAsciiCasecmp(str, "ANSI_X3.4-1968") &&
255 dStrAsciiCasecmp(str, "iso-ir-6") &&
256 dStrAsciiCasecmp(str, "ANSI_X3.4-1986") &&
257 dStrAsciiCasecmp(str, "ISO_646.irv:1991") &&
258 dStrAsciiCasecmp(str, "ISO646-US")));
259 }
260
261 /*
262244 * Initialize decoder to translate from any character set known to iconv()
263245 * to UTF-8.
264246 *
271253
272254 if (format &&
273255 strlen(format) &&
274 dStrAsciiCasecmp(format,"UTF-8") &&
275 !Decode_is_ascii(format)) {
256 dStrAsciiCasecmp(format,"UTF-8")) {
276257
277258 iconv_t ic = iconv_open("UTF-8", format);
278259 if (ic != (iconv_t) -1) {
66 extern "C" {
77 #endif /* __cplusplus */
88
9 typedef struct _Decode Decode;
10
11 struct _Decode {
9 typedef struct Decode {
1210 char *buffer;
1311 Dstr *leftover;
1412 void *state;
15 Dstr *(*decode) (Decode *dc, const char *instr, int inlen);
16 void (*free) (Decode *dc);
17 };
13 Dstr *(*decode) (struct Decode *dc, const char *instr, int inlen);
14 void (*free) (struct Decode *dc);
15 } Decode;
1816
1917 Decode *a_Decode_transfer_init(const char *format);
2018 Decode *a_Decode_content_init(const char *format);
1212
1313 #include <math.h> // for rint()
1414
15 #include <FL/fl_ask.H>
1516 #include <FL/Fl_Window.H>
1617 #include <FL/Fl_File_Chooser.H>
1718 #include <FL/Fl_Return_Button.H>
3435 */
3536 static int input_answer;
3637 static char *input_str = NULL;
37 static int choice5_answer;
38 static int choice_answer;
3839
3940
4041 /*
8081 /*
8182 * Used to make the ENTER key activate the CustChoice
8283 */
83 class CustChoice : public Fl_Choice {
84 class CustChoice2 : public Fl_Choice {
8485 public:
85 CustChoice (int x, int y, int w, int h, const char* l=0) :
86 CustChoice2 (int x, int y, int w, int h, const char* l=0) :
8687 Fl_Choice(x,y,w,h,l) {};
8788 int handle(int e) {
8889 if (e == FL_KEYBOARD &&
118119 /*
119120 * Display a message in a popup window.
120121 */
121 void a_Dialog_msg(const char *msg)
122 {
122 void a_Dialog_msg(const char *title, const char *msg)
123 {
124 if (!(title && *title))
125 title = "Dillo: Message";
126 fl_message_title(title);
123127 fl_message("%s", msg);
124128 }
125129
139143 *
140144 * Return value: string on success, NULL upon Cancel or Close window
141145 */
142 const char *a_Dialog_input(const char *msg)
146 const char *a_Dialog_input(const char *title, const char *msg)
143147 {
144148 static Fl_Menu_Item *pm = 0;
145149 int ww = 450, wh = 130, gap = 10, ih = 60, bw = 80, bh = 30;
146150
147151 input_answer = 0;
148152
149 Fl_Window *window = new Fl_Window(ww,wh,"Ask");
153 if (!(title && *title))
154 title = "Dillo: Input";
155
156 Fl_Window *window = new Fl_Window(ww,wh,title);
150157 window->set_modal();
151158 window->begin();
152159 Fl_Group* ib = new Fl_Group(0,0,window->w(),window->h());
158165 o->box(FL_THIN_UP_BOX);
159166 o->labelfont(FL_TIMES_BOLD);
160167 o->labelsize(34);
161 o->color(FL_WHITE);
162 o->labelcolor(FL_BLUE);
163168 o->label("?");
164169 o->show();
165170
172177 c_inp->labelsize(14);
173178 c_inp->textsize(14);
174179
175 CustChoice *ch = new CustChoice(1*gap,ih+3*gap,180,24);
180 CustChoice2 *ch = new CustChoice2(1*gap,ih+3*gap,180,24);
176181 if (!pm) {
177182 int n_it = dList_length(prefs.search_urls);
178183 pm = new Fl_Menu_Item[n_it+1];
188193 ch->tooltip("Select search engine");
189194 ch->menu(pm);
190195 ch->value(prefs.search_url_idx);
191 ch->textcolor(FL_DARK_BLUE);
192196
193197 int xpos = ww-2*(gap+bw), ypos = ih+3*gap;
194198 Fl_Return_Button *rb = new Fl_Return_Button(xpos, ypos, bw, bh, "OK");
221225 /*
222226 * Dialog for password
223227 */
224 const char *a_Dialog_passwd(const char *msg)
225 {
228 const char *a_Dialog_passwd(const char *title, const char *msg)
229 {
230 if (!(title && *title))
231 title = "Dillo: Password";
232 fl_message_title(title);
226233 return fl_password("%s", "", msg);
227234 }
228235
231238 *
232239 * Return: pointer to chosen filename, or NULL on Cancel.
233240 */
234 const char *a_Dialog_save_file(const char *msg,
241 const char *a_Dialog_save_file(const char *title,
235242 const char *pattern, const char *fname)
236243 {
237 return fl_file_chooser(msg, pattern, fname);
244 return fl_file_chooser(title, pattern, fname);
238245 }
239246
240247 /*
242249 *
243250 * Return: pointer to chosen filename, or NULL on Cancel.
244251 */
245 const char *a_Dialog_select_file(const char *msg,
252 const char *a_Dialog_select_file(const char *title,
246253 const char *pattern, const char *fname)
247254 {
248255 /*
249256 * FileChooser::type(MULTI) appears to allow multiple files to be selected,
250257 * but just follow save_file's path for now.
251258 */
252 return a_Dialog_save_file(msg, pattern, fname);
259 return a_Dialog_save_file(title, pattern, fname);
253260 }
254261
255262 /*
257264 *
258265 * Return: pointer to chosen filename, or NULL on Cancel.
259266 */
260 char *a_Dialog_open_file(const char *msg,
267 char *a_Dialog_open_file(const char *title,
261268 const char *pattern, const char *fname)
262269 {
263270 const char *fc_name;
264271
265 fc_name = fl_file_chooser(msg, pattern, fname);
266 return (fc_name) ? a_Misc_escape_chars(fc_name, "% ") : NULL;
272 fc_name = fl_file_chooser(title, pattern, fname);
273 return (fc_name) ? a_Misc_escape_chars(fc_name, "% #") : NULL;
267274 }
268275
269276 /*
281288 /*
282289 * Show a new window with the provided text
283290 */
284 void a_Dialog_text_window(const char *txt, const char *title)
291 void a_Dialog_text_window(const char *title, const char *txt)
285292 {
286293 int wh = prefs.height, ww = prefs.width, bh = 30;
287294
288 Fl_Window *window = new Fl_Window(ww, wh, title ? title : "Dillo text");
295 if (!(title && *title))
296 title = "Dillo: Text";
297
298 Fl_Window *window = new Fl_Window(ww, wh, title);
289299 Fl_Group::current(0);
290300
291301
296306 td->textsize((int) rint(14.0 * prefs.font_factor));
297307
298308 /* enable wrapping lines; text uses entire width of window */
299 td->wrap_mode(true, false);
309 td->wrap_mode(Fl_Text_Display::WRAP_AT_BOUNDS, 0);
300310 window->add(td);
301311
302312 Fl_Return_Button *b = new Fl_Return_Button (0, wh-bh, ww, bh, "Close");
310320
311321 /*--------------------------------------------------------------------------*/
312322
313 static void choice5_cb(Fl_Widget *button, void *number)
314 {
315 choice5_answer = VOIDP2INT(number);
316 _MSG("choice5_cb: %d\n", choice5_answer);
323 static void choice_cb(Fl_Widget *button, void *number)
324 {
325 choice_answer = VOIDP2INT(number);
326 _MSG("choice_cb: %d\n", choice_answer);
317327 button->window()->hide();
318328 }
319329
320330 /*
321 * Make a question-dialog with a question and up to five alternatives.
322 * (if less alternatives, non used parameters must be NULL).
323 *
324 * Return value: 0 = dialog was cancelled, 1-5 = selected alternative.
325 */
326 int a_Dialog_choice5(const char *QuestionTxt,
327 const char *alt1, const char *alt2, const char *alt3,
328 const char *alt4, const char *alt5)
329 {
330 choice5_answer = 0;
331
332 int ww = 440, wh = 120, bw = 50, bh = 45, ih = 50, nb = 0;
333 const char *txt[7];
334
335 txt[0] = txt[6] = NULL;
336 txt[1] = alt1; txt[2] = alt2; txt[3] = alt3;
337 txt[4] = alt4; txt[5] = alt5;
338 for (int i=1; txt[i]; ++i, ++nb)
339 ;
340
341 if (!nb) {
342 MSG_ERR("a_Dialog_choice5: No choices.\n");
343 return choice5_answer;
331 * Make a question-dialog with a question and alternatives.
332 * Last parameter must be NULL.
333 *
334 * Return value: 0 = dialog was cancelled, >0 = selected alternative.
335 */
336 int a_Dialog_choice(const char *title, const char *msg, ...)
337 {
338 va_list ap;
339 int i, n;
340
341 if (title == NULL || *title == '\0')
342 title = "Dillo: Choice";
343
344 va_start(ap, msg);
345 for (n = 0; va_arg(ap, char *) != NULL; n++);
346 va_end(ap);
347
348 if (n == 0) {
349 MSG_ERR("Dialog_choice: no alternatives.\n");
350 return 0;
344351 }
345 ww = 140 + nb*(bw+10);
346
347 Fl_Window *window = new Fl_Window(ww,wh,"Choice5");
352
353 int gap = 8;
354 int ww = 140 + n * 60, wh = 120;
355 int bw = (ww - gap) / n - gap, bh = 45;
356 int ih = 50;
357
358 Fl_Window *window = new Fl_Window(ww, wh, title);
348359 window->set_modal();
349360 window->begin();
350 Fl_Group* ib = new Fl_Group(0,0,window->w(),window->h());
361 Fl_Group *ib = new Fl_Group(0, 0, window->w(), window->h());
351362 ib->begin();
352363 window->resizable(ib);
353
364
354365 /* '?' Icon */
355 Fl_Box* o = new Fl_Box(10, (wh-bh-ih)/2, ih, ih);
366 Fl_Box *o = new Fl_Box(10, (wh - bh - ih) / 2, ih, ih);
356367 o->box(FL_THIN_UP_BOX);
357368 o->labelfont(FL_TIMES_BOLD);
358369 o->labelsize(34);
360371 o->labelcolor(FL_BLUE);
361372 o->label("?");
362373 o->show();
363
364 Fl_Box *box = new Fl_Box(60,0,ww-60,wh-bh, QuestionTxt);
365 box->labelfont(FL_HELVETICA);
366 box->labelsize(14);
367 box->align(FL_ALIGN_WRAP);
368
369 Fl_Button *b;
370 int xpos = 0, gap = 8;
371 bw = (ww - gap)/nb - gap;
372 xpos += gap;
373 for (int i=1; i <= nb; ++i) {
374 b = new EnterButton(xpos, wh-bh, bw, bh, txt[i]);
375 b->align(FL_ALIGN_WRAP|FL_ALIGN_CLIP);
374
375 if (msg != NULL){
376 Fl_Box *box = new Fl_Box(60, 0, ww - 60, wh - bh, msg);
377 box->labelfont(FL_HELVETICA);
378 box->labelsize(14);
379 box->align(FL_ALIGN_WRAP);
380 }
381
382 int xpos = gap;
383 va_start(ap, msg);
384 for (i = 1; i <= n; i++) {
385 Fl_Button *b = new EnterButton(xpos, wh-bh, bw, bh, va_arg(ap, char *));
386 b->align(FL_ALIGN_WRAP | FL_ALIGN_CLIP);
376387 b->box(FL_UP_BOX);
377 b->callback(choice5_cb, INT2VOIDP(i));
388 b->callback(choice_cb, INT2VOIDP(i));
378389 xpos += bw + gap;
379390 /* TODO: set focus to the *-prefixed alternative */
380391 }
392 va_end(ap);
381393 window->end();
382394
383395 window->show();
384396 while (window->shown())
385397 Fl::wait();
386 _MSG("a_Dialog_choice5 answer = %d\n", choice5_answer);
398 _MSG("Dialog_choice answer = %d\n", answer);
387399 delete window;
388400
389 return choice5_answer;
390 }
391
401 return choice_answer;
402 }
392403
393404 /*--------------------------------------------------------------------------*/
394405 static void Dialog_user_password_cb(Fl_Widget *button, void *)
402413 * Call the callback with the result (OK or not) and the given user and
403414 * password if OK.
404415 */
405 int a_Dialog_user_password(const char *message, UserPasswordCB cb, void *vp)
416 int a_Dialog_user_password(const char *title, const char *msg,
417 UserPasswordCB cb, void *vp)
406418 {
407419 int ok = 0, window_h = 280, y, msg_w, msg_h;
408420 const int window_w = 300, input_x = 80, input_w = 200, input_h = 30,
409421 button_h = 30;
410422
411423 /* window is resized below */
412 Fl_Window *window = new Fl_Window(window_w,window_h,"Dillo User/Password");
424 if (!(title && *title))
425 title = "Dillo: User/Password";
426 Fl_Window *window = new Fl_Window(window_w,window_h,title);
413427 Fl_Group::current(0);
414428 window->user_data(NULL);
415429
416430 /* message */
417431 y = 20;
418432 msg_w = window_w - 40;
419 Fl_Box *msg = new Fl_Box(20, y, msg_w, 100); /* resized below */
420 msg->label(message);
421 msg->labelfont(FL_HELVETICA);
422 msg->labelsize(14);
423 msg->align(FL_ALIGN_INSIDE | FL_ALIGN_TOP_LEFT | FL_ALIGN_WRAP);
424
425 fl_font(msg->labelfont(), msg->labelsize());
433 Fl_Box *msg_box = new Fl_Box(20, y, msg_w, 100); /* resized below */
434 msg_box->label(msg);
435 msg_box->labelfont(FL_HELVETICA);
436 msg_box->labelsize(14);
437 msg_box->align(FL_ALIGN_INSIDE | FL_ALIGN_TOP_LEFT | FL_ALIGN_WRAP);
438
439 fl_font(msg_box->labelfont(), msg_box->labelsize());
426440 msg_w -= 6; /* The label doesn't fill the entire box. */
427 fl_measure(msg->label(), msg_w, msg_h, 0); /* fl_measure wraps at msg_w */
428 msg->size(msg->w(), msg_h);
429 window->add(msg);
441 fl_measure(msg_box->label(), msg_w, msg_h, 0); // fl_measure wraps at msg_w
442 msg_box->size(msg_box->w(), msg_h);
443 window->add(msg_box);
430444
431445 /* inputs */
432446 y += msg_h + 20;
77 typedef void (*UserPasswordCB)(const char *user, const char *password,
88 void *vp);
99
10 void a_Dialog_msg(const char *msg);
11 int a_Dialog_choice5(const char *QuestionTxt,
12 const char *alt1, const char *alt2, const char *alt3,
13 const char *alt4, const char *alt5);
14 int a_Dialog_user_password(const char *message, UserPasswordCB cb, void *vp);
15 const char *a_Dialog_input(const char *msg);
16 const char *a_Dialog_passwd(const char *msg);
17 const char *a_Dialog_save_file(const char *msg,
10 void a_Dialog_msg(const char *title, const char *msg);
11 int a_Dialog_choice(const char *title, const char *msg, ...);
12 int a_Dialog_user_password(const char *title, const char *msg,
13 UserPasswordCB cb, void *vp);
14 const char *a_Dialog_input(const char *title, const char *msg);
15 const char *a_Dialog_passwd(const char *title, const char *msg);
16 const char *a_Dialog_save_file(const char *title,
1817 const char *pattern, const char *fname);
19 const char *a_Dialog_select_file(const char *msg,
18 const char *a_Dialog_select_file(const char *title,
2019 const char *pattern, const char *fname);
21 char *a_Dialog_open_file(const char *msg,
20 char *a_Dialog_open_file(const char *title,
2221 const char *pattern, const char *fname);
23 void a_Dialog_text_window(const char *txt, const char *title);
22 void a_Dialog_text_window(const char *title, const char *txt);
2423
2524 #ifdef __cplusplus
2625 }
2020 #include "dgif.h"
2121 #include "djpeg.h"
2222
23 typedef struct _DICacheNode DICacheNode;
2423
2524 enum {
2625 DIC_Gif,
2827 DIC_Jpeg
2928 };
3029
31 struct _DICacheNode {
30 typedef struct {
3231 int valid; /* flag */
3332 DilloUrl *url; /* primary "Key" for this dicache entry */
3433 DICacheEntry *first; /* pointer to the first dicache entry in this list */
35 };
34 } DICacheNode;
3635
3736 /*
3837 * List of DICacheNode. One node per URL. Each node may have several
2323 DIC_Abort /* Image transfer aborted */
2424 } DicEntryState;
2525
26 typedef struct _DICacheEntry DICacheEntry;
27
28 struct _DICacheEntry {
26 typedef struct DICacheEntry {
2927 DilloUrl *url; /* Image URL for this entry */
3028 uint_t width, height; /* As taken from image data */
3129 DilloImgType type; /* Image type */
4341 void *DecoderData; /* Client function data */
4442 uint_t DecodedSize; /* Size of already decoded data */
4543
46 DICacheEntry *next; /* Link to the next "newer" version */
47 };
44 struct DICacheEntry *next; /* Link to the next "newer" version */
45 } DICacheEntry;
4846
4947
5048 void a_Dicache_init (void);
2525
2626 #include <FL/Fl.H>
2727 #include <FL/Fl_Window.H>
28 #include <FL/fl_ask.H>
2829 #include <FL/fl_draw.H>
2930
3031 #include "msg.h"
4546 #include "capi.h"
4647 #include "dicache.h"
4748 #include "cookies.h"
49 #include "domain.h"
4850 #include "auth.h"
4951
5052 #include "dw/fltkcore.hh"
53 #include "dw/textblock.hh"
5154
5255 /*
5356 * Command line options structure
8184 {"-h", "--help", 0, DILLO_CLI_HELP,
8285 " -h, --help Display this help text and exit."},
8386 {"-l", "--local", 0, DILLO_CLI_LOCAL,
84 " -l, --local Don't load images for these URL(s)."},
87 " -l, --local Don't load images or stylesheets for these "
88 "URL(s)."},
8589 {"-v", "--version", 0, DILLO_CLI_VERSION,
8690 " -v, --version Display version info and exit."},
8791 {"-x", "--xid", 1, DILLO_CLI_XID,
145149 }
146150 if (state == O_FOUND) {
147151 int n_arg = options[i].opt_argc;
148 opt_id = options[i].id;
152 opt_id = options[i].id;
149153 /* Find the required/optional arguments of the option */
150154 for (i = 0; *idx < argc && i < abs(n_arg) && argv[*idx][0] != '-'; i++)
151155 opt_argv[i] = argv[(*idx)++];
233237 }
234238
235239 /*
240 * Set UI color. 'color' is an 0xrrggbb value, whereas 'default_val' is a fltk
241 * color (index 0-0xFF, or 0xrrggbb00).
242 */
243 static void setUIColorWdef(Fl_Color idx, int32_t color, Fl_Color default_val)
244 {
245 if (color != -1)
246 Fl::set_color(idx, color << 8);
247 else if (default_val != 0xFFFFFFFF)
248 Fl::set_color(idx, default_val);
249 }
250
251 static void setColors()
252 {
253 /* The main background is a special case because Fl::background() will
254 * set the "gray ramp", which is a set of lighter and darker colors based
255 * on the main background and used for box edges and such.
256 */
257 if (prefs.ui_main_bg_color != -1) {
258 uchar r = prefs.ui_main_bg_color >> 16,
259 g = prefs.ui_main_bg_color >> 8 & 0xff,
260 b = prefs.ui_main_bg_color & 0xff;
261
262 Fl::background(r, g, b);
263 }
264
265 setUIColorWdef(FL_BACKGROUND2_COLOR, prefs.ui_text_bg_color, 0xFFFFFFFF);
266 setUIColorWdef(FL_FOREGROUND_COLOR, prefs.ui_fg_color, 0xFFFFFFFF);
267 setUIColorWdef(FL_SELECTION_COLOR, prefs.ui_selection_color,
268 fl_contrast(FL_SELECTION_COLOR, FL_BACKGROUND2_COLOR));
269 setUIColorWdef(PREFS_UI_BUTTON_HIGHLIGHT_COLOR,
270 prefs.ui_button_highlight_color,
271 fl_lighter(FL_BACKGROUND_COLOR));
272 setUIColorWdef(PREFS_UI_TAB_ACTIVE_BG_COLOR, prefs.ui_tab_active_bg_color,
273 Fl::get_color(FL_BACKGROUND2_COLOR));
274 setUIColorWdef(PREFS_UI_TAB_BG_COLOR, prefs.ui_tab_bg_color,
275 Fl::get_color(FL_BACKGROUND_COLOR));
276 setUIColorWdef(PREFS_UI_TAB_ACTIVE_FG_COLOR, prefs.ui_tab_active_fg_color,
277 Fl::get_color(FL_FOREGROUND_COLOR));
278 setUIColorWdef(PREFS_UI_TAB_FG_COLOR, prefs.ui_tab_fg_color,
279 Fl::get_color(FL_FOREGROUND_COLOR));
280 }
281
282 /*
236283 * Given a command line argument, build a DilloUrl for it.
237284 */
238285 static DilloUrl *makeStartUrl(char *str, bool local)
246293
247294 if (access(p, F_OK) == 0) {
248295 /* absolute path may have non-URL characters */
249 url_str = a_Misc_escape_chars(p, "% ");
296 url_str = a_Misc_escape_chars(p, "% #");
250297 start_url = a_Url_new(url_str + 1, "file:/");
251298 } else {
252299 /* Not a file, filter URL string */
337384 if ((fp = Paths::getPrefsFP(PATHS_RC_KEYS))) {
338385 Keys::parse(fp);
339386 }
387 // parse domainrc
388 if ((fp = Paths::getPrefsFP(PATHS_RC_DOMAIN))) {
389 a_Domain_parse(fp);
390 fclose(fp);
391 }
340392 dLib_show_messages(prefs.show_msg);
341393
342394 // initialize internal modules
350402 a_Bw_init();
351403 a_Cookies_init();
352404 a_Auth_init();
405 a_UIcmd_init();
406
407 dw::Textblock::setPenaltyHyphen (prefs.penalty_hyphen);
408 dw::Textblock::setPenaltyHyphen2 (prefs.penalty_hyphen_2);
409 dw::Textblock::setPenaltyEmDashLeft (prefs.penalty_em_dash_left);
410 dw::Textblock::setPenaltyEmDashRight (prefs.penalty_em_dash_right);
411 dw::Textblock::setPenaltyEmDashRight2 (prefs.penalty_em_dash_right_2);
353412
354413 /* command line options override preferences */
355414 if (options_got & DILLO_CLI_FULLWINDOW)
365424 Fl_Window::default_xclass("dillo");
366425
367426 Fl::scheme(prefs.theme);
427 setColors();
368428
369429 if (!prefs.show_tooltip) {
370430 // turn off UI tooltips
384444 Fl::set_font(FL_HELVETICA, defaultFont); // this seems to be the
385445 // only way to set the
386446 // default font in fltk1.3
447
448 fl_message_title_default("Dillo: Message");
387449
388450 // Create a new UI/bw pair
389451 BrowserWindow *bw = a_UIcmd_browser_window_new(0, 0, xid, NULL);
411473 /* No URLs/files on cmdline. Send startup screen */
412474 if (dStrAsciiCasecmp(URL_SCHEME(prefs.start_page), "about") == 0 &&
413475 strcmp(URL_PATH(prefs.start_page), "blank") == 0)
414 a_UIcmd_open_url(bw, NULL);
415 else
476 a_UIcmd_open_url(bw, NULL); // NULL URL focuses location
477 else {
416478 a_UIcmd_open_url(bw, prefs.start_page);
479 a_UIcmd_set_location_text(bw, URL_STR(prefs.start_page));
480 }
417481 } else {
418482 for (int i = idx; i < argc; i++) {
419483 DilloUrl *start_url = makeStartUrl(argv[i], local);
428492 }
429493 } else {
430494 a_UIcmd_open_url(bw, start_url);
495 a_UIcmd_set_location_text(bw, URL_STR(start_url));
431496 }
432497 a_Url_free(start_url);
433498 }
440505 * (This can be left to the OS, but we'll do it, with a view to test
441506 * and fix our memory management)
442507 */
508 a_Domain_freeall();
443509 a_Cookies_freeall();
444510 a_Cache_freeall();
445511 a_Dicache_freeall();
2323 #endif
2424
2525
26 #include <assert.h>
2627 #include <netdb.h>
2728 #include <sys/types.h>
2829 #include <sys/socket.h>
2930 #include <arpa/inet.h>
3031 #include <netinet/in.h>
32 #include <fcntl.h>
3133 #include <errno.h>
3234 #include <unistd.h>
3335 #include <stdlib.h>
3739 #include "msg.h"
3840 #include "dns.h"
3941 #include "list.h"
40 #include "timeout.hh"
42 #include "IO/iowatch.hh"
4143
4244
4345 /* Maximum dns resolving threads */
4749 # define D_DNS_MAX_SERVERS 1
4850 #endif
4951
52 typedef enum {
53 DNS_SERVER_IDLE,
54 DNS_SERVER_PROCESSING,
55 DNS_SERVER_RESOLVED,
56 } DnsServerState_t;
5057
5158 typedef struct {
5259 int channel; /* Index of this channel [0 based] */
53 bool_t in_use; /* boolean to tell if server is doing a lookup */
54 bool_t ip_ready; /* boolean: is IP lookup done? */
60 DnsServerState_t state;
5561 Dlist *addr_list; /* IP address */
56 char *hostname; /* Adress to resolve */
62 char *hostname; /* Address to resolve */
5763 int status; /* errno code for resolving function */
5864 #ifdef D_DNS_THREADED
5965 pthread_t th1; /* Thread id */
7682 /*
7783 * Forward declarations
7884 */
79 static void Dns_timeout_client(void *data);
85 static void Dns_timeout_client(int fd, void *data);
8086
8187 /*
8288 * Local Data
8793 static int dns_cache_size, dns_cache_size_max;
8894 static GDnsQueue *dns_queue;
8995 static int dns_queue_size, dns_queue_size_max;
96 static int dns_notify_pipe[2];
9097
9198
9299 /* ----------------------------------------------------------------------
168175 */
169176 void a_Dns_init(void)
170177 {
171 int i;
178 int res, i;
172179
173180 #ifdef D_DNS_THREADED
174181 MSG("dillo_dns_init: Here we go! (threaded)\n");
186193
187194 num_servers = D_DNS_MAX_SERVERS;
188195
196 res = pipe(dns_notify_pipe);
197 assert(res == 0);
198 fcntl(dns_notify_pipe[0], F_SETFL, O_NONBLOCK);
199 a_IOwatch_add_fd(dns_notify_pipe[0], DIO_READ, Dns_timeout_client, NULL);
200
189201 /* Initialize servers data */
190202 for (i = 0; i < num_servers; ++i) {
191203 dns_server[i].channel = i;
192 dns_server[i].in_use = FALSE;
193 dns_server[i].ip_ready = FALSE;
204 dns_server[i].state = DNS_SERVER_IDLE;
194205 dns_server[i].addr_list = NULL;
195206 dns_server[i].hostname = NULL;
196207 dns_server[i].status = 0;
205216 /* If the IPv6 address family is not available there is no point
206217 wasting time trying to connect to v6 addresses. */
207218 int fd = socket(AF_INET6, SOCK_STREAM, 0);
208 if (fd >= 0) {
209 close(fd);
210 }
219 if (fd >= 0)
220 dClose(fd);
211221 }
212222 #endif
213223 }
272282 char addr_string[40];
273283
274284 memset(&hints, 0, sizeof(hints));
285 #ifdef ENABLE_IPV6
275286 hints.ai_family = AF_UNSPEC;
287 #else
288 hints.ai_family = AF_INET;
289 #endif
276290 hints.ai_socktype = SOCK_STREAM;
277291
278292 hosts = dList_new(2);
322336 MSG(" (nil)\n");
323337 }
324338 dns_server[channel].addr_list = hosts;
325 dns_server[channel].ip_ready = TRUE;
339 dns_server[channel].state = DNS_SERVER_RESOLVED;
340
341 write(dns_notify_pipe[1], ".", 1);
326342
327343 return NULL; /* (avoids a compiler warning) */
328344 }
338354 static int thrATTRInitialized = 0;
339355 #endif
340356
341 dns_server[channel].in_use = TRUE;
342 dns_server[channel].ip_ready = FALSE;
357 dns_server[channel].state = DNS_SERVER_PROCESSING;
343358
344359 dFree(dns_server[channel].hostname);
345360 dns_server[channel].hostname = dStrdup(hostname);
346
347 /* Let's set a timeout client to poll the server channel (5 times/sec) */
348 a_Timeout_add(0.2,Dns_timeout_client,
349 INT2VOIDP(dns_server[channel].channel));
350361
351362 #ifdef D_DNS_THREADED
352363 /* set the thread attribute to the detached state */
392403
393404 /* Find a channel we can send the request to */
394405 for (channel = 0; channel < num_servers; channel++)
395 if (!dns_server[channel].in_use)
406 if (dns_server[channel].state == DNS_SERVER_IDLE)
396407 break;
397408 if (channel < num_servers) {
398409 /* Found a free channel! */
421432 --i;
422433 }
423434 }
424 /* set current channel free */
425 srv->in_use = FALSE;
426435 }
427436
428437 /*
433442 int ch, i, j;
434443
435444 for (ch = 0; ch < num_servers; ++ch) {
436 if (dns_server[ch].in_use == FALSE) {
445 if (dns_server[ch].state == DNS_SERVER_IDLE) {
437446 /* Find the next query in the queue (we're a FIFO) */
438447 for (i = 0; i < dns_queue_size; i++)
439448 if (dns_queue[i].channel == -2)
456465 }
457466
458467 /*
459 * This is a timeout function that
460 * reads the DNS results and resumes the stopped jobs.
461 */
462 static void Dns_timeout_client(void *data)
463 {
464 int channel = VOIDP2INT(data);
465 DnsServer *srv = &dns_server[channel];
466
467 if (srv->ip_ready) {
468 if (srv->addr_list != NULL) {
469 /* DNS succeeded, let's cache it */
470 Dns_cache_add(srv->hostname, srv->addr_list);
471 }
472 Dns_serve_channel(channel);
473 Dns_assign_channels();
474 a_Timeout_remove(); /* Done! */
475
476 } else {
477 /* IP not already resolved, keep on trying... */
478 a_Timeout_repeat(0.2, Dns_timeout_client, data);
479 }
468 * This function is called on the main thread and
469 * reads the DNS results.
470 */
471 static void Dns_timeout_client(int fd, void *data)
472 {
473 int i;
474 char buf[16];
475
476 while (read(dns_notify_pipe[0], buf, sizeof(buf)) > 0);
477
478 for (i = 0; i < num_servers; ++i) {
479 DnsServer *srv = &dns_server[i];
480
481 if (srv->state == DNS_SERVER_RESOLVED) {
482 if (srv->addr_list != NULL) {
483 /* DNS succeeded, let's cache it */
484 Dns_cache_add(srv->hostname, srv->addr_list);
485 }
486 Dns_serve_channel(i);
487 srv->state = DNS_SERVER_IDLE;
488 }
489 }
490 Dns_assign_channels();
480491 }
481492
482493
496507 dFree(dList_nth_data(dns_cache[i].addr_list, j));
497508 dList_free(dns_cache[i].addr_list);
498509 }
510 a_IOwatch_remove_fd(dns_notify_pipe[0], DIO_READ);
511 dClose(dns_notify_pipe[0]);
512 dClose(dns_notify_pipe[1]);
499513 dFree(dns_cache);
500514 }
501515
511525 switch (errno) {
512526 case EAFNOSUPPORT:
513527 snprintf(dst, size, "Unknown address family");
528 break;
514529 case ENOSPC:
515530 snprintf(dst, size, "Buffer too small");
516 }
517 }
518 }
531 break;
532 }
533 }
534 }
1919 # define DILLO_ADDR_MAX sizeof(struct in_addr)
2020 #endif
2121
22 typedef struct _DilloHost
23 {
22 typedef struct {
2423 int af;
2524 int alen;
2625 char data[DILLO_ADDR_MAX];
2726 } DilloHost;
27
2828 void a_Dns_dillohost_to_string(DilloHost *host, char *dst, size_t size);
2929
3030 #ifdef __cplusplus
0 /*
1 * File: domain.c
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 3 of the License, or
6 * (at your option) any later version.
7 */
8
9 #include <stdlib.h>
10
11 #include "../dlib/dlib.h"
12 #include "msg.h"
13 #include "list.h"
14 #include "domain.h"
15
16 typedef struct {
17 char *origin;
18 char *destination;
19 } Rule;
20
21 static Rule *exceptions = NULL;
22 static int num_exceptions = 0;
23 static int num_exceptions_max = 1;
24
25 static bool_t default_deny = FALSE;
26
27 /*
28 * Parse domainrc.
29 */
30 void a_Domain_parse(FILE *fp)
31 {
32 char *line;
33 uint_t lineno = 0;
34
35 _MSG("Reading domainrc...\n");
36
37 while ((line = dGetline(fp)) != NULL) {
38 ++lineno;
39
40 /* Remove leading and trailing whitespace */
41 dStrstrip(line);
42
43 if (line[0] && line[0] != '#') {
44 const char *delim = " \t";
45 char *tok1 = strtok(line, delim);
46 char *tok2 = strtok(NULL, delim);
47
48 if (strtok(NULL, delim) != NULL) {
49 MSG("Domain: Ignoring extraneous text at end of line %u.\n",
50 lineno);
51 }
52 if (!tok2) {
53 MSG("Domain: Not enough fields in line %u.\n", lineno);
54 } else {
55 if (dStrAsciiCasecmp(tok1, "default") == 0) {
56 if (dStrAsciiCasecmp(tok2, "deny") == 0) {
57 default_deny = TRUE;
58 MSG("Domain: Default deny.\n");
59 } else if (dStrAsciiCasecmp(tok2, "accept") == 0) {
60 default_deny = FALSE;
61 MSG("Domain: Default accept.\n");
62 } else {
63 MSG("Domain: Default action \"%s\" not recognised.\n", tok2);
64 }
65 } else {
66 a_List_add(exceptions, num_exceptions, num_exceptions_max);
67 exceptions[num_exceptions].origin = dStrdup(tok1);
68 exceptions[num_exceptions].destination = dStrdup(tok2);
69 num_exceptions++;
70 _MSG("Domain: Exception from %s to %s.\n", tok1, tok2);
71 }
72 }
73 }
74 dFree(line);
75 }
76 }
77
78 void a_Domain_freeall(void)
79 {
80 int i = 0;
81
82 for (i = 0; i < num_exceptions; i++) {
83 dFree(exceptions[i].origin);
84 dFree(exceptions[i].destination);
85 }
86 dFree(exceptions);
87 }
88
89 /*
90 * Wildcard ('*') pattern always matches.
91 * "example.org" pattern matches "example.org".
92 * ".example.org" pattern matches "example.org" and "sub.example.org".
93 */
94 static bool_t Domain_match(const char *host, const char *pattern) {
95 int cmp = strcmp(pattern, "*");
96
97 if (cmp) {
98 if (pattern[0] != '.')
99 cmp = dStrAsciiCasecmp(host, pattern);
100 else {
101 int diff = strlen(host) - strlen(pattern);
102
103 if (diff == -1)
104 cmp = dStrAsciiCasecmp(host, pattern + 1);
105 else if (diff >= 0)
106 cmp = dStrAsciiCasecmp(host + diff, pattern);
107 }
108 }
109 return cmp ? FALSE : TRUE;
110 }
111
112 /*
113 * Is the resource at 'source' permitted to request the resource at 'dest'?
114 */
115 bool_t a_Domain_permit(const DilloUrl *source, const DilloUrl *dest)
116 {
117 int i;
118 bool_t ret;
119 const char *source_host, *dest_host;
120
121 if (default_deny == FALSE && num_exceptions == 0)
122 return TRUE;
123
124 source_host = URL_HOST(source);
125 dest_host = URL_HOST(dest);
126
127 if (dest_host[0] == '\0')
128 return source_host[0] == '\0' ||
129 !dStrAsciiCasecmp(URL_SCHEME(dest), "data");
130
131 if (a_Url_same_organization(source, dest))
132 return TRUE;
133
134 ret = default_deny ? FALSE : TRUE;
135
136 for (i = 0; i < num_exceptions; i++) {
137 if (Domain_match(source_host, exceptions[i].origin) &&
138 Domain_match(dest_host, exceptions[i].destination)) {
139 ret = default_deny;
140 _MSG("Domain: Matched rule from %s to %s.\n", exceptions[i].origin,
141 exceptions[i].destination);
142 break;
143 }
144 }
145
146 if (ret == FALSE)
147 MSG("Domain: DENIED from %s to %s.\n", source_host, dest_host);
148
149 return ret;
150 }
0 #ifndef __DOMAIN_H__
1 #define __DOMAIN_H__
2
3 #ifdef __cplusplus
4 extern "C" {
5 #endif
6
7 #include <stdio.h>
8 #include "url.h"
9
10 void a_Domain_parse(FILE *fp);
11 void a_Domain_freeall(void);
12 bool_t a_Domain_permit(const DilloUrl *source, const DilloUrl *dest);
13
14 #ifdef __cplusplus
15 }
16 #endif
17
18 #endif
0 # domainrc - Dillo cross-domain request rules file.
1 #
2 # Here you can tell Dillo what to do when one site wants to retrieve resources
3 # (e.g., images, style sheets, redirection) from a different site.
4 #
5 # Lines that begin with a '#' are comments.
6
7 # Default rule can be "accept" or "deny".
8
9 default accept
10
11
12 # Now we list exceptions to the default. The format is:
13 #
14 # source destination
15 #
16 # There are three ways that you can specify a source or destination domain:
17 #
18 # 1. * - wildcard will match any domain
19 # 2. example.com - match the specific host example.com
20 # 3. .example.com - match example.com and any of its subdomains
21
22 # Let's block some of the most notorious ad sites and trackers.
23
24 * .2o7.net
25 * .admt.com
26 * .adnxs.com
27 * .atdmt.com
28 * .collective-media.net
29 * .crwdcntrl.com
30 * .doubleclick.net
31 * .effectivemeasure.net
32 * .googleadservices.com
33 * .imrworldwide.com
34 * .quantserve.com
35 * .revsci.net
36 * .scorecardresearch.com
37 * .webtrendslive.com
38 * .yieldmanager.com
4848 */
4949 void a_Dpiapi_dialog(BrowserWindow *bw, char *server, char *dpip_tag)
5050 {
51 char *question, *alt1, *alt2, *alt3, *alt4, *alt5;
51 char *title, *msg, *alt1, *alt2, *alt3, *alt4, *alt5;
5252 size_t dpip_tag_len;
5353 int ret;
5454
6060
6161 /* other options can be parsed the same way */
6262 dpip_tag_len = strlen(dpip_tag);
63 question = a_Dpip_get_attr_l(dpip_tag, dpip_tag_len, "msg");
63 title = a_Dpip_get_attr_l(dpip_tag, dpip_tag_len, "title");
64 msg = a_Dpip_get_attr_l(dpip_tag, dpip_tag_len, "msg");
6465 alt1 = a_Dpip_get_attr_l(dpip_tag, dpip_tag_len, "alt1");
6566 alt2 = a_Dpip_get_attr_l(dpip_tag, dpip_tag_len, "alt2");
6667 alt3 = a_Dpip_get_attr_l(dpip_tag, dpip_tag_len, "alt3");
6768 alt4 = a_Dpip_get_attr_l(dpip_tag, dpip_tag_len, "alt4");
6869 alt5 = a_Dpip_get_attr_l(dpip_tag, dpip_tag_len, "alt5");
6970
70 ret = a_Dialog_choice5(question, alt1, alt2, alt3, alt4, alt5);
71 /* As choice5 is modal, call the callback function directly. */
71 ret = a_Dialog_choice(title, msg, alt1, alt2, alt3, alt4, alt5, NULL);
72 /* As choice is modal, call the callback function directly. */
7273 Dpiapi_dialog_answer_cb(bw, ret);
7374
7475 dFree(alt1); dFree(alt2); dFree(alt3); dFree(alt4); dFree(alt5);
75 dFree(question);
76 dFree(title); dFree(msg);
7677 }
7778
3535 unsigned modifier = Fl::event_state() & (FL_SHIFT| FL_CTRL| FL_ALT|FL_META);
3636
3737 if (e == FL_KEYBOARD) {
38 if (k == FL_Page_Down || k == FL_Page_Up || k == FL_Up || k == FL_Down) {
39 // Let them through for key commands and viewport motion.
40 return 0;
41 }
3842 if (modifier == FL_SHIFT) {
3943 if (k == FL_Left || k == FL_Right) {
4044 // Let these keys get to the UI
5054 } else if (k == 'd') {
5155 cut(position(), position()+1);
5256 return 1;
57 } else if (k == 'h' || k == 'i' || k == 'j' || k == 'l' || k == 'm') {
58 // Fl_Input wants to use ^H as backspace, and also "insert a few
59 // selected control characters literally", but this gets in the way
60 // of key commands.
61 return 0;
5362 }
5463 } else if (k == FL_Escape && modifier == 0) {
5564 // Avoid clearing the text with Esc, just hide the findbar.
6069 if (ret)
6170 ret = Fl_Input::handle(e);
6271 return ret;
63 };
72 }
6473
6574 /*
6675 * Find next occurrence of input key
117126
118127 box(FL_THIN_UP_BOX);
119128
120 hide_btn = new Fl_Button(x, border, 16, height, 0);
129 hide_btn = new CustButton(x, border, 16, height, 0);
121130 hideImg = new Fl_Pixmap(new_s_xpm);
122131 hide_btn->image(hideImg);
123132 x += 16 + gap;
124133 hide_btn->callback(hide_cb, this);
125134 hide_btn->clear_visible_focus();
126135 hide_btn->box(FL_THIN_UP_BOX);
127 hide_btn->tooltip("Hide");
136 hide_btn->set_tooltip("Hide");
128137 add(hide_btn);
129138
130139 i = new MyInput(x, border, input_width, height);
131140 x += input_width + gap;
132141 resizable(i);
133 i->color(206);
134142 i->when(FL_WHEN_NEVER);
135143 add(i);
136144
137 next_btn = new Fl_Button(x, border, button_width, height, "Next");
145 next_btn = new CustButton(x, border, button_width, height, "Next");
138146 x += button_width + gap;
139147 next_btn->shortcut(FL_Enter);
140148 next_btn->callback(search_cb, this);
141149 next_btn->clear_visible_focus();
142150 next_btn->box(FL_THIN_UP_BOX);
143 next_btn->tooltip("Find next occurrence of the search phrase\n"
144 "shortcut: Enter");
151 next_btn->set_tooltip("Find next occurrence of the search phrase\n"
152 "shortcut: Enter");
145153 add(next_btn);
146154
147 prev_btn= new Fl_Button(x, border, button_width, height, "Previous");
155 prev_btn= new CustButton(x, border, button_width, height, "Previous");
148156 x += button_width + gap;
149157 prev_btn->shortcut(FL_SHIFT+FL_Enter);
150158 prev_btn->callback(searchBackwards_cb, this);
151159 prev_btn->clear_visible_focus();
152160 prev_btn->box(FL_THIN_UP_BOX);
153 prev_btn->tooltip("Find previous occurrence of the search phrase\n"
154 "shortcut: Shift+Enter");
161 prev_btn->set_tooltip("Find previous occurrence of the search phrase\n"
162 "shortcut: Shift+Enter");
155163 add(prev_btn);
156164
157165 check_btn = new Fl_Check_Button(x, border, 2*button_width, height,
77 #include <FL/Fl_Group.H>
88 #include <FL/Fl_Check_Button.H>
99
10 #include "tipwin.hh"
11
1012 /*
1113 * Searchbar to find text in page.
1214 */
1315 class Findbar : public Fl_Group {
14 Fl_Button *clrb;
15 Fl_Button *hide_btn, *next_btn, *prev_btn;
16 CustButton *hide_btn, *next_btn, *prev_btn;
1617 Fl_Check_Button *check_btn;
1718 Fl_Pixmap *hideImg;
1819 Fl_Input *i;
176176 void addOption (char *value, bool selected, bool enabled);
177177 void ensureSelection ();
178178 void addOptionsTo (SelectionResource *res);
179 void reset (SelectionResource *res);
179180 void appendValuesTo (Dlist *values, SelectionResource *res);
180181 };
181182
278279 }
279280
280281 /*
281 * Get the current input.
282 * Note that this _assumes_ that there _is_ a current input.
282 * Get the current input if available.
283283 */
284284 static DilloHtmlInput *Html_get_current_input(DilloHtml *html)
285285 {
290290 else
291291 inputs = html->inputs_outside_form;
292292
293 return inputs->get (inputs->size() - 1);
293 return (inputs && inputs->size() > 0) ?
294 inputs->get (inputs->size() - 1) : NULL;
294295 }
295296
296297 /*
326327 if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "action")))
327328 action = a_Html_url_new(html, attrbuf, NULL, 0);
328329 else {
329 BUG_MSG("action attribute required for <form>\n");
330 BUG_MSG("action attribute is required for <form>\n");
330331 action = a_Url_dup(html->base_url);
331332 }
332333 content_type = DILLO_HTML_ENC_URLENCODED;
359360 a_Url_free(action);
360361 }
361362
362 void Html_tag_close_form(DilloHtml *html, int TagIdx)
363 {
364 // DilloHtmlForm *form;
365 // int i;
366 //
367 // if (html->InFlags & IN_FORM) {
368 // form = html->getCurrentForm ();
369 //
370 // /* Make buttons sensitive again */
371 // for (i = 0; i < form->inputs->size(); i++) {
372 // input_i = form->inputs->get(i);
373 // /* Check for tricky HTML (e.g. <input type=image>) */
374 // if (!input_i->widget)
375 // continue;
376 // if (input_i->type == DILLO_HTML_INPUT_SUBMIT ||
377 // input_i->type == DILLO_HTML_INPUT_RESET) {
378 // gtk_widget_set_sensitive(input_i->widget, TRUE);
379 // } else if (input_i->type == DILLO_HTML_INPUT_IMAGE ||
380 // input_i->type == DILLO_HTML_INPUT_BUTTON_SUBMIT ||
381 // input_i->type == DILLO_HTML_INPUT_BUTTON_RESET) {
382 // a_Dw_button_set_sensitive(DW_BUTTON(input_i->widget), TRUE);
383 // }
384 // }
385 // }
386
363 void Html_tag_close_form(DilloHtml *html)
364 {
387365 html->InFlags &= ~IN_FORM;
388366 html->InFlags &= ~IN_SELECT;
389367 html->InFlags &= ~IN_OPTION;
469447 inp_type = DILLO_HTML_INPUT_SUBMIT;
470448 init_str = (value) ? value : dStrdup("submit");
471449 resource = factory->createLabelButtonResource(init_str);
472 // gtk_widget_set_sensitive(widget, FALSE); /* Until end of FORM! */
473450 } else if (!dStrAsciiCasecmp(type, "reset")) {
474451 inp_type = DILLO_HTML_INPUT_RESET;
475452 init_str = (value) ? value : dStrdup("Reset");
476453 resource = factory->createLabelButtonResource(init_str);
477 // gtk_widget_set_sensitive(widget, FALSE); /* Until end of FORM! */
478454 } else if (!dStrAsciiCasecmp(type, "image")) {
479455 if (URL_FLAGS(html->base_url) & URL_SpamSafe) {
480456 /* Don't request the image; make a text submit button instead */
483459 label = attrbuf ? attrbuf : value ? value : name ? name : "Submit";
484460 init_str = dStrdup(label);
485461 resource = factory->createLabelButtonResource(init_str);
486 // gtk_widget_set_sensitive(widget, FALSE); /* Until end of FORM! */
487462 } else {
488463 inp_type = DILLO_HTML_INPUT_IMAGE;
489464 /* use a dw_image widget */
546521 if (a_Html_get_attr(html, tag, tagsize, "readonly"))
547522 ((EntryResource *) resource)->setEditable(false);
548523
549 // /* Maximum length of the text in the entry */
550 // if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "maxlength")))
551 // gtk_entry_set_max_length(GTK_ENTRY(widget),
552 // strtol(attrbuf, NULL, 10));
524 /* Maximum length of the text in the entry */
525 if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "maxlength"))) {
526 int maxlen = strtol(attrbuf, NULL, 10);
527 ((EntryResource *) resource)->setMaxLength(maxlen);
528 }
553529 }
554530 if (prefs.show_tooltip &&
555531 (attrbuf = a_Html_get_attr(html, tag, tagsize, "title"))) {
606582 html->InFlags &= ~IN_FORM;
607583 }
608584
609 /*
610 * The textarea tag
611 */
612585 void Html_tag_open_textarea(DilloHtml *html, const char *tag, int tagsize)
613586 {
614 const int MAX_COLS=1024, MAX_ROWS=10000;
615
616 char *name;
617 const char *attrbuf;
618 int cols, rows;
619
620587 if (html->InFlags & IN_TEXTAREA) {
621588 BUG_MSG("nested <textarea>\n");
622589 html->ReqTagClose = TRUE;
628595 }
629596
630597 html->InFlags |= IN_TEXTAREA;
598 }
599
600 /*
601 * The textarea tag
602 */
603 void Html_tag_content_textarea(DilloHtml *html, const char *tag, int tagsize)
604 {
605 const int MAX_COLS=1024, MAX_ROWS=10000;
606
607 char *name;
608 const char *attrbuf;
609 int cols, rows;
610
631611 a_Html_stash_init(html);
632612 S_TOP(html)->parse_mode = DILLO_HTML_PARSE_MODE_VERBATIM;
633613
675655 * Close textarea
676656 * (TEXTAREA is parsed in VERBATIM mode, and entities are handled here)
677657 */
678 void Html_tag_close_textarea(DilloHtml *html, int TagIdx)
658 void Html_tag_close_textarea(DilloHtml *html)
679659 {
680660 char *str;
681661 DilloHtmlInput *input;
682662 int i;
683663
684 if (html->InFlags & IN_TEXTAREA) {
664 if (html->InFlags & IN_TEXTAREA && !S_TOP(html)->display_none) {
685665 /* Remove the line ending that follows the opening tag */
686666 if (html->Stash->str[0] == '\r')
687667 dStr_erase(html->Stash, 0, 1);
702682 /* The HTML3.2 spec says it can have "text and character entities". */
703683 str = a_Html_parse_entities(html, html->Stash->str, html->Stash->len);
704684 input = Html_get_current_input(html);
705 input->init_str = str;
706 ((MultiLineTextResource *)input->embed->getResource ())->setText(str);
685 if (input) {
686 input->init_str = str;
687 ((MultiLineTextResource *)input->embed->getResource ())->setText(str);
688 }
707689
708690 html->InFlags &= ~IN_TEXTAREA;
709691 }
743725 type = DILLO_HTML_INPUT_SELECT;
744726 res = factory->createOptionMenuResource ();
745727 } else {
728 ListResource::SelectionMode mode;
729
746730 type = DILLO_HTML_INPUT_SEL_LIST;
747 res = factory->createListResource (multi ?
748 ListResource::SELECTION_MULTIPLE :
749 ListResource::SELECTION_EXACTLY_ONE,
750 rows);
731 mode = multi ? ListResource::SELECTION_MULTIPLE
732 : ListResource::SELECTION_AT_MOST_ONE;
733 res = factory->createListResource (mode, rows);
751734 }
752735 Embed *embed = new Embed(res);
753736
737 if (prefs.show_tooltip &&
738 (attrbuf = a_Html_get_attr(html, tag, tagsize, "title"))) {
739
740 html->styleEngine->setNonCssHint (PROPERTY_X_TOOLTIP, CSS_TYPE_STRING,
741 attrbuf);
742 }
754743 HT2TB(html)->addWidget (embed, html->styleEngine->backgroundStyle ());
755744
756745 Html_add_input(html, type, embed, name, NULL, false);
761750 /*
762751 * ?
763752 */
764 void Html_tag_close_select(DilloHtml *html, int TagIdx)
753 void Html_tag_close_select(DilloHtml *html)
765754 {
766755 if (html->InFlags & IN_SELECT) {
767756 if (html->InFlags & IN_OPTION)
772761 DilloHtmlInput *input = Html_get_current_input(html);
773762 DilloHtmlSelect *select = input->select;
774763
775 // BUG(?): should not do this for MULTI selections
776 select->ensureSelection ();
777
764 if (input->type == DILLO_HTML_INPUT_SELECT) {
765 // option menu interface requires that something be selected */
766 select->ensureSelection ();
767 }
778768 SelectionResource *res = (SelectionResource*)input->embed->getResource();
779769 select->addOptionsTo (res);
780770 }
804794 }
805795
806796 a_Html_stash_init(html);
797 }
798
799 void Html_tag_close_option(DilloHtml *html)
800 {
801 if (html->InFlags & IN_OPTION) {
802 Html_option_finish(html);
803 html->InFlags &= ~IN_OPTION;
804 }
807805 }
808806
809807 /*
846844 /* Render the button */
847845 Widget *page;
848846 Embed *embed;
847 const char *attrbuf;
849848 char *name, *value;
850849
851 /* We used to have Textblock (prefs.limit_text_width) here,
850 if (prefs.show_tooltip &&
851 (attrbuf = a_Html_get_attr(html, tag, tagsize, "title"))) {
852
853 html->styleEngine->setNonCssHint (PROPERTY_X_TOOLTIP, CSS_TYPE_STRING,
854 attrbuf);
855 }
856 /* We used to have Textblock (prefs.limit_text_width, ...) here,
852857 * but it caused 100% CPU usage.
853858 */
854859 page = new Textblock (false);
860865 // a_Dw_button_set_sensitive (DW_BUTTON (button), FALSE);
861866
862867 HT2TB(html)->addParbreak (5, html->styleEngine->wordStyle ());
863 HT2TB(html)->addWidget (embed, html->styleEngine->style ());
868 HT2TB(html)->addWidget (embed, html->styleEngine->backgroundStyle ());
864869 HT2TB(html)->addParbreak (5, html->styleEngine->wordStyle ());
865870
866871 S_TOP(html)->textblock = html->dw = page;
878883 /*
879884 * Handle close <BUTTON>
880885 */
881 void Html_tag_close_button(DilloHtml *html, int TagIdx)
886 void Html_tag_close_button(DilloHtml *html)
882887 {
883888 html->InFlags &= ~IN_BUTTON;
884889 }
962967 }
963968 a_Url_free(url);
964969 }
965 // /* now, make the rendered area have its focus back */
966 // gtk_widget_grab_focus(GTK_BIN(bw->render_main_scroll)->child);
967970 }
968971
969972 /*
10341037 iconv_t char_encoder = (iconv_t) -1;
10351038
10361039 if (submit_charset && dStrAsciiCasecmp(submit_charset, "UTF-8")) {
1037 char_encoder = iconv_open(submit_charset, "UTF-8");
1040 /* Some iconv implementations, given "//TRANSLIT", will do their best to
1041 * transliterate the string. Under the circumstances, doing so is likely
1042 * for the best.
1043 */
1044 char *translit = dStrconcat(submit_charset, "//TRANSLIT", NULL);
1045
1046 char_encoder = iconv_open(translit, "UTF-8");
1047 dFree(translit);
1048
1049 if (char_encoder == (iconv_t) -1)
1050 char_encoder = iconv_open(submit_charset, "UTF-8");
1051
10381052 if (char_encoder == (iconv_t) -1) {
10391053 MSG_WARN("Cannot convert to character encoding '%s'\n",
10401054 submit_charset);
12481262 inLeft--;
12491263 dStr_append_c(output, '?');
12501264 } else if (rc == EINVAL) {
1251 MSG_ERR("Html_decode_text: bad source string\n");
1265 MSG_ERR("Form encode text: bad source string.\n");
12521266 }
12531267 }
12541268
12581272 * it is safe to display the beginning of the string in a message
12591273 * (isn't, e.g., a password).
12601274 */
1261 MSG_WARN("String cannot be converted cleanly.\n");
1275 MSG_WARN("Form encode text: string cannot be converted cleanly.\n");
12621276 }
12631277
12641278 dFree(buffer);
13161330 dStr_append(data, "--");
13171331 dStr_append(data, boundary);
13181332 }
1319 // TODO: encode name, filename
13201333 dStr_sprintfa(data,
13211334 "\r\n"
13221335 "Content-Disposition: form-data; name=\"%s\"; "
13231336 "filename=\"", name);
13241337 /*
1325 * Servers don't seem to like encoded names yet, but let's at least
1326 * replace the characters that are the most likely to damage things.
1338 * Replace the characters that are the most likely to damage things.
1339 * For a while, there was some momentum to standardize on an encoding,
1340 * but HTML5/Ian Hickson/his Google masters are, as of late 2012,
1341 * evidently standing in opposition to all of that for some reason.
13271342 */
13281343 for (int i = 0; char c = filename[i]; i++) {
13291344 if (c == '\"' || c == '\r' || c == '\n')
13561371 dStr_append(data, "--");
13571372 dStr_append(data, boundary);
13581373 }
1359 // TODO: encode name (RFC 2231)
13601374 dStr_sprintfa(data,
13611375 "\r\n"
13621376 "Content-Disposition: form-data; name=\"%s\"\r\n"
17441758 }
17451759 break;
17461760 case DILLO_HTML_INPUT_SELECT:
1761 case DILLO_HTML_INPUT_SEL_LIST:
17471762 if (select != NULL) {
1748 /* this is in reverse order so that, in case more than one was
1749 * selected, we get the last one, which is consistent with handling
1750 * of multiple selected options in the layout code. */
1751 // for (i = select->num_options - 1; i >= 0; i--) {
1752 // if (select->options[i].init_val) {
1753 // gtk_menu_item_activate(GTK_MENU_ITEM
1754 // (select->options[i].menuitem));
1755 // Html_select_set_history(input);
1756 // break;
1757 // }
1758 // }
1759 }
1760 break;
1761 case DILLO_HTML_INPUT_SEL_LIST:
1762 if (!select)
1763 break;
1764 // for (i = 0; i < select->num_options; i++) {
1765 // if (select->options[i].init_val) {
1766 // if (select->options[i].menuitem->state == GTK_STATE_NORMAL)
1767 // gtk_list_select_child(GTK_LIST(select->menu),
1768 // select->options[i].menuitem);
1769 // } else {
1770 // if (select->options[i].menuitem->state==GTK_STATE_SELECTED)
1771 // gtk_list_unselect_child(GTK_LIST(select->menu),
1772 // select->options[i].menuitem);
1773 // }
1774 // }
1763 SelectionResource *sr = (SelectionResource *) embed->getResource();
1764 select->reset(sr);
1765 }
17751766 break;
17761767 case DILLO_HTML_INPUT_TEXTAREA:
17771768 if (init_str != NULL) {
18541845 }
18551846 }
18561847
1848 void DilloHtmlSelect::reset (SelectionResource *res)
1849 {
1850 int size = options->size ();
1851 for (int i = 0; i < size; i++) {
1852 DilloHtmlOption *option = options->get (i);
1853 res->setItem(i, option->selected);
1854 }
1855 }
1856
18571857 void DilloHtmlSelect::appendValuesTo (Dlist *values, SelectionResource *res)
18581858 {
18591859 int size = options->size ();
19011901 */
19021902 static Embed *Html_input_image(DilloHtml *html, const char *tag, int tagsize)
19031903 {
1904 const char *attrbuf;
19051904 DilloImage *Image;
19061905 Embed *button = NULL;
1907 DilloUrl *url = NULL;
1908
1909 if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "src")) &&
1910 (url = a_Html_url_new(html, attrbuf, NULL, 0))) {
1911
1912 html->styleEngine->setPseudoLink ();
1913
1914 /* create new image and add it to the button */
1915 if ((Image = a_Html_image_new(html, tag, tagsize, url))) {
1916 IM2DW(Image)->setStyle (html->styleEngine->backgroundStyle ());
1917 ResourceFactory *factory = HT2LT(html)->getResourceFactory();
1918 ComplexButtonResource *complex_b_r =
1919 factory->createComplexButtonResource(IM2DW(Image), false);
1920 button = new Embed(complex_b_r);
1921 HT2TB(html)->addWidget (button, html->styleEngine->style ());
1922 // gtk_widget_set_sensitive(widget, FALSE); /* Until end of FORM! */
1923
1924 } else {
1925 a_Url_free(url);
1926 }
1906
1907 html->styleEngine->setPseudoLink ();
1908
1909 /* create new image and add it to the button */
1910 a_Html_image_attrs(html, tag, tagsize);
1911 if ((Image = a_Html_image_new(html, tag, tagsize))) {
1912 IM2DW(Image)->setStyle (html->styleEngine->backgroundStyle ());
1913 ResourceFactory *factory = HT2LT(html)->getResourceFactory();
1914 ComplexButtonResource *complex_b_r =
1915 factory->createComplexButtonResource(IM2DW(Image), false);
1916 button = new Embed(complex_b_r);
1917 HT2TB(html)->addWidget (button, html->styleEngine->style ());
19271918 }
19281919 if (!button)
19291920 MSG("Html_input_image: unable to create image submit.\n");
4747 */
4848
4949 void Html_tag_open_form(DilloHtml *html, const char *tag, int tagsize);
50 void Html_tag_close_form(DilloHtml *html, int TagIdx);
50 void Html_tag_close_form(DilloHtml *html);
5151 void Html_tag_open_input(DilloHtml *html, const char *tag, int tagsize);
5252 void Html_tag_open_isindex(DilloHtml *html, const char *tag, int tagsize);
5353 void Html_tag_open_textarea(DilloHtml *html, const char *tag, int tagsize);
54 void Html_tag_close_textarea(DilloHtml *html, int TagIdx);
54 void Html_tag_content_textarea(DilloHtml *html, const char *tag, int tagsize);
55 void Html_tag_close_textarea(DilloHtml *html);
5556 void Html_tag_open_select(DilloHtml *html, const char *tag, int tagsize);
56 void Html_tag_close_select(DilloHtml *html, int TagIdx);
57 void Html_tag_close_select(DilloHtml *html);
5758 void Html_tag_open_option(DilloHtml *html, const char *tag, int tagsize);
59 void Html_tag_close_option(DilloHtml *html);
5860 void Html_tag_open_button(DilloHtml *html, const char *tag, int tagsize);
59 void Html_tag_close_button(DilloHtml *html, int TagIdx);
61 void Html_tag_close_button(DilloHtml *html);
6062
6163 #endif /* __FORM_HH__ */
7878 #define MAX_LWZ_BITS 12
7979
8080
81 typedef struct _DilloGif {
81 typedef struct {
8282 DilloImage *Image;
8383 DilloUrl *url;
8484 int version;
102102 size_t ColorMap_ofs;
103103 uint_t ColorResolution;
104104 uint_t NumColors;
105 #if 0
105106 int Background;
107 #endif
106108 uint_t spill_line_index;
107109 #if 0
108110 uint_t AspectRatio; /* AspectRatio (not used) */
162164 gif->state = 0;
163165 gif->Start_Ofs = 0;
164166 gif->linebuf = NULL;
167 #if 0
165168 gif->Background = -1;
169 #endif
166170 gif->transparent = -1;
167171 gif->num_spill_lines_max = 0;
168172 gif->spill_lines = NULL;
307311 size_t Size = Buf[0] + 2;
308312 uint_t Flags;
309313
310 if (Size > BSize)
314 if (BSize < 6 || Size > BSize)
311315 return 0;
312316 Buf++;
313317 Flags = Buf[0];
770774 if (!mysize)
771775 return 0;
772776 Size += mysize; /* Size of the color table that follows */
773 gif->Background = buf[5];
777 /* gif->Background = buf[5]; */
774778 }
775779 /* gif->Width = LM_to_uint(buf[0], buf[1]);
776780 gif->Height = LM_to_uint(buf[2], buf[3]); */
6868 *---------------------------------------------------------------------------*/
6969 class DilloHtml;
7070 typedef void (*TagOpenFunct) (DilloHtml *html, const char *tag, int tagsize);
71 typedef void (*TagCloseFunct) (DilloHtml *html, int TagIdx);
71 typedef void (*TagCloseFunct) (DilloHtml *html);
7272
7373 typedef enum {
7474 SEEK_ATTR_START,
9797 /*-----------------------------------------------------------------------------
9898 * Forward declarations
9999 *---------------------------------------------------------------------------*/
100 static const char *Html_get_attr2(DilloHtml *html,
101 const char *tag,
102 int tagsize,
103 const char *attrname,
104 int tag_parsing_flags);
105100 static int Html_write_raw(DilloHtml *html, char *buf, int bufsize, int Eof);
106101 static bool Html_load_image(BrowserWindow *bw, DilloUrl *url,
107102 const DilloUrl *requester, DilloImage *image);
118113 char EndTag; /* Is it Required, Optional or Forbidden */
119114 uchar_t TagLevel; /* Used to heuristically parse bad HTML */
120115 TagOpenFunct open; /* Open function */
116 TagOpenFunct content; /* Content function */
121117 TagCloseFunct close; /* Close function */
122118 } TagInfo;
123119 extern const TagInfo Tags[];
161157 const char *suffix = (n_ic) > 1 ? "s" : "";
162158 n_ic_spc = URL_ILLEGAL_CHARS_SPC(url);
163159 if (n_ic == n_ic_spc) {
164 BUG_MSG("URL has %d illegal character%s (%d space%s)\n",
165 n_ic, suffix, n_ic_spc, suffix);
160 BUG_MSG("URL has %d illegal space%s\n", n_ic, suffix);
166161 } else if (n_ic_spc == 0) {
167 BUG_MSG("URL has %d illegal character%s (%d in {00-1F, 7F} range)\n",
168 n_ic, suffix, n_ic);
162 BUG_MSG("URL has %d illegal character%s in {00-1F, 7F} range\n",
163 n_ic, suffix);
169164 } else {
170165 BUG_MSG("URL has %d illegal character%s: "
171166 "%d space%s, and %d in {00-1F, 7F} range\n",
280275 html->links->increase();
281276 html->links->set(nl, (*url) ? *url : NULL);
282277 return nl;
283 }
284
285 /*
286 * Add a new image to our list.
287 * image is NULL if dillo will try to load the image immediately.
288 */
289 static void Html_add_new_htmlimage(DilloHtml *html,
290 DilloUrl **url, DilloImage *image)
291 {
292 DilloHtmlImage *hi = dNew(DilloHtmlImage, 1);
293 hi->url = *url;
294 hi->image = image;
295 a_Image_ref(image);
296
297 int n = html->images->size();
298 html->images->increase();
299 html->images->set(n, hi);
300278 }
301279
302280 /*
429407 stack->getRef(0)->table_mode = DILLO_HTML_TABLE_MODE_NONE;
430408 stack->getRef(0)->table_border_mode = DILLO_HTML_TABLE_BORDER_SEPARATE;
431409 stack->getRef(0)->cell_text_align_set = false;
410 stack->getRef(0)->display_none = false;
432411 stack->getRef(0)->list_type = HTML_LIST_NONE;
433412 stack->getRef(0)->list_number = 0;
434413 stack->getRef(0)->tag_idx = -1; /* MUST not be used */
478457 dReturn_if_fail (dw == NULL);
479458
480459 /* Create the main widget */
481 dw = stack->getRef(0)->textblock = new Textblock (prefs.limit_text_width);
460 dw = stack->getRef(0)->textblock = new Textblock (prefs.limit_text_width);
482461
483462 bw->num_page_bugs = 0;
484463 dStr_truncate(bw->page_bugs, 0);
566545 ofs = CurrTagOfs;
567546 line = OldTagLine;
568547 for (i = OldTagOfs; i < ofs; ++i)
569 if (p[i] == '\n')
548 if (p[i] == '\n' || (p[i] == '\r' && p[i+1] != '\n'))
570549 ++line;
571550 OldTagOfs = CurrTagOfs;
572551 OldTagLine = line;
656635 const DilloUrl *requester = pattern ? NULL : this->page_url;
657636
658637 for (int i = 0; i < images->size(); i++) {
659 if (images->get(i)->image) {
660 if ((!pattern) || (!a_Url_cmp(images->get(i)->url, pattern))) {
661 if (Html_load_image(bw, images->get(i)->url, requester,
662 images->get(i)->image)) {
663 a_Image_unref (images->get(i)->image);
664 images->get(i)->image = NULL; // web owns it now
638 DilloHtmlImage *hi = images->get(i);
639
640 if (hi->image) {
641 assert(hi->url);
642 if ((!pattern) || (!a_Url_cmp(hi->url, pattern))) {
643 if (Html_load_image(bw, hi->url, requester, hi->image)) {
644 a_Image_unref (hi->image);
645 hi->image = NULL; // web owns it now
665646 }
666647 }
667648 }
945926
946927 if (!isocode || errno || isocode > 0xffff) {
947928 /* this catches null bytes, errors and codes >= 0xFFFF */
948 BUG_MSG("numeric character reference out of range\n");
929 BUG_MSG("numeric character reference \"%s\" out of range\n", tok);
949930 isocode = -2;
950931 }
951932
962943 c = *s;
963944 *s = 0;
964945
965 if ((i = Html_entity_search(tok)) == -1) {
966 if ((html->DocType == DT_HTML && html->DocTypeVersion == 4.01f) ||
967 html->DocType == DT_XHTML)
968 BUG_MSG("undefined character entity '%s'\n", tok);
969 isocode = -3;
970 } else
946 if ((i = Html_entity_search(tok)) >= 0) {
971947 isocode = Entities[i].isocode;
972
948 } else {
949 if (html->DocType == DT_XHTML && !strcmp(tok, "apos")) {
950 isocode = 0x27;
951 } else {
952 if ((html->DocType == DT_HTML && html->DocTypeVersion == 4.01f) ||
953 html->DocType == DT_XHTML)
954 BUG_MSG("undefined character entity '%s'\n", tok);
955 isocode = -3;
956 }
957 }
973958 if (c == ';')
974959 s++;
975960 else if (prefs.show_extra_warnings)
10571042 int i, offset;
10581043 DilloHtmlParseMode parse_mode = S_TOP(html)->parse_mode;
10591044
1060 if (parse_mode == DILLO_HTML_PARSE_MODE_STASH) {
1045 if (S_TOP(html)->display_none) {
1046 /* do nothing */
1047 } else if (parse_mode == DILLO_HTML_PARSE_MODE_STASH) {
10611048 html->StashSpace = (html->Stash->len > 0);
10621049
10631050 } else if (parse_mode == DILLO_HTML_PARSE_MODE_VERBATIM) {
11421129 char *Pword;
11431130 DilloHtmlParseMode parse_mode = S_TOP(html)->parse_mode;
11441131
1132 if (S_TOP(html)->display_none)
1133 return;
1134
11451135 if (parse_mode == DILLO_HTML_PARSE_MODE_STASH ||
11461136 parse_mode == DILLO_HTML_PARSE_MODE_STASH_AND_BODY) {
11471137 if (html->StashSpace) {
11571147 dStr_append_l(html->Stash, word, size);
11581148 }
11591149
1160 if (parse_mode == DILLO_HTML_PARSE_MODE_STASH ||
1150 if (parse_mode == DILLO_HTML_PARSE_MODE_STASH ||
11611151 parse_mode == DILLO_HTML_PARSE_MODE_VERBATIM) {
11621152 /* skip until the closing instructions */
11631153
13131303 if (s_sz > idx + 1 && toptag.EndTag != 'O')
13141304 BUG_MSG(" - forcing close of open tag: <%s>\n", toptag.name);
13151305 _MSG("Close: %*s%s\n", size," ", toptag.name);
1316 toptag.close(html, toptag_idx);
1306 if (toptag.close)
1307 toptag.close(html);
13171308 Html_real_pop_tag(html);
13181309 }
13191310 }
14381429 * Parse a color attribute.
14391430 * Return value: parsed color, or default_color (+ error msg) on error.
14401431 */
1441 int32_t a_Html_color_parse(DilloHtml *html,
1442 const char *subtag, int32_t default_color)
1432 int32_t a_Html_color_parse(DilloHtml *html, const char *str,
1433 int32_t default_color)
14431434 {
14441435 int err = 1;
1445 int32_t color = a_Color_parse(subtag, default_color, &err);
1436 int32_t color = a_Color_parse(str, default_color, &err);
14461437
14471438 if (err) {
1448 BUG_MSG("color is not in \"#RRGGBB\" format\n");
1439 BUG_MSG("color \"%s\" is not in \"#RRGGBB\" format\n", str);
14491440 }
14501441 return color;
14511442 }
14651456 break;
14661457
14671458 if (val[i] || !(isascii(val[0]) && isalpha(val[0])))
1468 BUG_MSG("'%s' value is not of the form "
1469 "[A-Za-z][A-Za-z0-9:_.-]*\n", attrname);
1459 BUG_MSG("'%s' value \"%s\" is not of the form "
1460 "[A-Za-z][A-Za-z0-9:_.-]*\n", attrname, val);
14701461
14711462 return !(val[i]);
14721463 }
14941485 {
14951486 static const char HTML_SGML_sig [] = "<!DOCTYPE HTML PUBLIC ";
14961487 static const char HTML5_sig [] = "<!DOCTYPE html>";
1497 static const char HTML20 [] = "-//IETF//DTD HTML 2.0";
1488 static const char HTML20 [] = "-//IETF//DTD HTML";
14981489 static const char HTML32 [] = "-//W3C//DTD HTML 3.2";
14991490 static const char HTML40 [] = "-//W3C//DTD HTML 4.0";
15001491 static const char HTML401 [] = "-//W3C//DTD HTML 4.01";
15791570 /*
15801571 * Handle close HTML element
15811572 */
1582 static void Html_tag_close_html(DilloHtml *html, int TagIdx)
1573 static void Html_tag_close_html(DilloHtml *html)
15831574 {
15841575 /* TODO: may add some checks here */
15851576 if (html->Num_HTML == 1) {
16141605 * twice when the head element is closed implicitly.
16151606 * Note2: HEAD is parsed once completely got.
16161607 */
1617 static void Html_tag_close_head(DilloHtml *html, int TagIdx)
1608 static void Html_tag_close_head(DilloHtml *html)
16181609 {
16191610 if (html->InFlags & IN_HEAD) {
16201611 _MSG("Closing HEAD section\n");
16441635 * Handle close TITLE
16451636 * set page-title in the browser window and in the history.
16461637 */
1647 static void Html_tag_close_title(DilloHtml *html, int TagIdx)
1638 static void Html_tag_close_title(DilloHtml *html)
16481639 {
16491640 if (html->InFlags & IN_HEAD) {
16501641 /* title is only valid inside HEAD */
16511642 a_UIcmd_set_page_title(html->bw, html->Stash->str);
16521643 a_History_set_title_by_url(html->page_url, html->Stash->str);
16531644 } else {
1654 BUG_MSG("the TITLE element must be inside the HEAD section\n");
1645 BUG_MSG("TITLE element must be inside the HEAD section\n");
16551646 }
16561647 }
16571648
16691660 /*
16701661 * Handle close SCRIPT
16711662 */
1672 static void Html_tag_close_script(DilloHtml *html, int TagIdx)
1663 static void Html_tag_close_script(DilloHtml *html)
16731664 {
16741665 /* eventually the stash will be sent to an interpreter for parsing */
16751666 }
17061697 /*
17071698 * Handle close STYLE
17081699 */
1709 static void Html_tag_close_style(DilloHtml *html, int TagIdx)
1700 static void Html_tag_close_style(DilloHtml *html)
17101701 {
17111702 if (prefs.parse_embedded_css && html->loadCssFromStash)
17121703 html->styleEngine->parse(html, NULL, html->Stash->str, html->Stash->len,
17961787 /*
17971788 * BODY
17981789 */
1799 static void Html_tag_close_body(DilloHtml *html, int TagIdx)
1790 static void Html_tag_close_body(DilloHtml *html)
18001791 {
18011792 if (html->Num_BODY == 1) {
18021793 /* some tag soup pages use multiple BODY tags... */
18141805 CssPropertyList props;
18151806
18161807 a_Html_tag_set_align_attr (html, tag, tagsize);
1817 html->styleEngine->inheritBackgroundColor ();
1818 HT2TB(html)->addParbreak (9, html->styleEngine->wordStyle ());
18191808 }
18201809
18211810 /*
18261815 static void Html_tag_open_frame (DilloHtml *html, const char *tag, int tagsize)
18271816 {
18281817 const char *attrbuf;
1829 char *src;
18301818 DilloUrl *url;
1831 Textblock *textblock;
1832 Widget *bullet;
18331819 CssPropertyList props;
1834
1835 textblock = HT2TB(html);
18361820
18371821 if (!(attrbuf = a_Html_get_attr(html, tag, tagsize, "src")))
18381822 return;
18391823
18401824 if (!(url = a_Html_url_new(html, attrbuf, NULL, 0)))
18411825 return;
1842
1843 src = dStrdup(attrbuf);
18441826
18451827 if (a_Capi_get_flags_with_redirection(url) & CAPI_IsCached) {
18461828 /* visited frame */
18521834
18531835 html->styleEngine->setNonCssHint (PROPERTY_X_LINK, CSS_TYPE_INTEGER,
18541836 Html_set_new_link(html,&url));
1837 }
1838
1839 static void
1840 Html_tag_content_frame (DilloHtml *html, const char *tag, int tagsize)
1841 {
1842 const char *attrbuf;
1843 char *src;
1844 Textblock *textblock;
1845 Widget *bullet;
1846
1847 textblock = HT2TB(html);
1848
1849 if (!(attrbuf = a_Html_get_attr(html, tag, tagsize, "src")))
1850 return;
1851
1852 src = dStrdup(attrbuf);
18551853
18561854 textblock->addParbreak (5, html->styleEngine->wordStyle ());
18571855
18841882 * TODO: This is just a temporary fix while real frame support
18851883 * isn't finished. Imitates lynx/w3m's frames.
18861884 */
1887 static void Html_tag_open_frameset (DilloHtml *html,
1885 static void Html_tag_content_frameset (DilloHtml *html,
18881886 const char *tag, int tagsize)
18891887 {
18901888 HT2TB(html)->addParbreak (9, html->styleEngine->wordStyle ());
18971895 */
18981896 static void Html_tag_open_h(DilloHtml *html, const char *tag, int tagsize)
18991897 {
1900 html->styleEngine->inheritBackgroundColor ();
19011898 a_Html_tag_set_align_attr (html, tag, tagsize);
1902
1903 HT2TB(html)->addParbreak (9, html->styleEngine->wordStyle ());
19041899
19051900 a_Html_stash_init(html);
19061901 S_TOP(html)->parse_mode =
19101905 /*
19111906 * <BR>
19121907 */
1913 static void Html_tag_open_br(DilloHtml *html, const char *tag, int tagsize)
1908 static void Html_tag_content_br(DilloHtml *html, const char *tag, int tagsize)
19141909 {
19151910 HT2TB(html)->addLinebreak (html->styleEngine->wordStyle ());
19161911 }
19631958 }
19641959
19651960 /*
1966 * <CENTER>
1967 */
1968 static void Html_tag_open_center(DilloHtml *html, const char *tag, int tagsize)
1969 {
1970 html->styleEngine->inheritBackgroundColor ();
1971 HT2TB(html)->addParbreak (0, html->styleEngine->wordStyle ());
1972 }
1973
1974 /*
1975 * </CENTER>, also used for </TABLE>
1976 */
1977 static void Html_tag_close_center(DilloHtml *html, int TagIdx)
1978 {
1979 HT2TB(html)->addParbreak (0, html->styleEngine->wordStyle ());
1980 }
1981
1982 /*
1983 * <ADDRESS>
1984 */
1985 static void Html_tag_open_address(DilloHtml *html,
1986 const char *tag, int tagsize)
1987 {
1988 html->styleEngine->inheritBackgroundColor ();
1989 HT2TB(html)->addParbreak (9, html->styleEngine->wordStyle ());
1990 }
1991
1992 /*
19931961 * Read image-associated tag attributes and create new image.
19941962 */
1995 DilloImage *a_Html_image_new(DilloHtml *html, const char *tag,
1996 int tagsize, DilloUrl *url)
1997 {
1998 DilloImage *Image;
1999 char *width_ptr, *height_ptr, *alt_ptr;
1963 void a_Html_image_attrs(DilloHtml *html, const char *tag, int tagsize)
1964 {
1965 char *width_ptr, *height_ptr;
20001966 const char *attrbuf;
20011967 CssLength l_w = CSS_CREATE_LENGTH(0.0, CSS_LENGTH_TYPE_AUTO);
20021968 CssLength l_h = CSS_CREATE_LENGTH(0.0, CSS_LENGTH_TYPE_AUTO);
20031969 int space, border, w = 0, h = 0;
2004 bool load_now;
20051970
20061971 if (prefs.show_tooltip &&
20071972 (attrbuf = a_Html_get_attr(html, tag, tagsize, "title"))) {
20081973 html->styleEngine->setNonCssHint(PROPERTY_X_TOOLTIP, CSS_TYPE_STRING,
20091974 attrbuf);
2010 }
2011 alt_ptr = a_Html_get_attr_wdef(html, tag, tagsize, "alt", NULL);
2012 if ((!alt_ptr || !*alt_ptr) && !prefs.load_images) {
2013 dFree(alt_ptr);
2014 alt_ptr = dStrdup("[IMG]"); // Place holder for img_off mode
20151975 }
20161976 width_ptr = a_Html_get_attr_wdef(html, tag, tagsize, "width", NULL);
20171977 height_ptr = a_Html_get_attr_wdef(html, tag, tagsize, "height", NULL);
20422002 dFree(width_ptr);
20432003 dFree(height_ptr);
20442004 width_ptr = height_ptr = NULL;
2045 MSG("a_Html_image_new: suspicious image size request %d x %d\n", w, h);
2005 MSG("a_Html_image_attrs: suspicious image size request %d x %d\n", w, h);
20462006 } else {
20472007 if (CSS_LENGTH_TYPE(l_w) != CSS_LENGTH_TYPE_AUTO)
20482008 html->styleEngine->setNonCssHint (CSS_PROPERTY_WIDTH,
21092069 }
21102070
21112071 /* x_img is an index to a list of {url,image} pairs.
2112 * We know Html_add_new_htmlimage() will use size() as its next index */
2072 * We know a_Html_image_new() will use size() as its next index */
21132073 html->styleEngine->setNonCssHint (PROPERTY_X_IMG, CSS_TYPE_INTEGER,
21142074 html->images->size());
21152075
2116 /* Add a new image widget to this page */
2117 Image = a_Image_new(alt_ptr, 0);
2076
2077 dFree(width_ptr);
2078 dFree(height_ptr);
2079 }
2080
2081 DilloImage *a_Html_image_new(DilloHtml *html, const char *tag, int tagsize)
2082 {
2083 bool load_now;
2084 char *alt_ptr;
2085 const char *attrbuf;
2086 DilloUrl *url;
2087 DilloImage *image;
2088
2089 if (!(attrbuf = a_Html_get_attr(html, tag, tagsize, "src")) ||
2090 !(url = a_Html_url_new(html, attrbuf, NULL, 0)))
2091 return NULL;
2092
2093 alt_ptr = a_Html_get_attr_wdef(html, tag, tagsize, "alt", NULL);
2094 if ((!alt_ptr || !*alt_ptr) && !prefs.load_images) {
2095 dFree(alt_ptr);
2096 alt_ptr = dStrdup("[IMG]"); // Place holder for img_off mode
2097 }
2098
2099 image = a_Image_new(alt_ptr, 0);
2100
21182101 if (HT2TB(html)->getBgColor())
2119 Image->bg_color = HT2TB(html)->getBgColor()->getColor();
2102 image->bg_color = HT2TB(html)->getBgColor()->getColor();
2103
2104 DilloHtmlImage *hi = dNew(DilloHtmlImage, 1);
2105 hi->url = url;
2106 html->images->increase();
2107 html->images->set(html->images->size() - 1, hi);
21202108
21212109 load_now = prefs.load_images ||
21222110 !dStrAsciiCasecmp(URL_SCHEME(url), "data") ||
21232111 (a_Capi_get_flags_with_redirection(url) & CAPI_IsCached);
2124 bool loading = false;
2125 if (load_now)
2126 loading = Html_load_image(html->bw, url, html->page_url, Image);
2127 Html_add_new_htmlimage(html, &url, loading ? NULL : Image);
2128
2129 dFree(width_ptr);
2130 dFree(height_ptr);
2112
2113 if (load_now && Html_load_image(html->bw, url, html->page_url, image)) {
2114 // hi->image is NULL if dillo tries to load the image immediately
2115 hi->image = NULL;
2116 } else {
2117 // otherwise a reference is kept in html->images
2118 hi->image = image;
2119 a_Image_ref(image);
2120 }
2121
21312122 dFree(alt_ptr);
2132 return Image;
2123 return image;
21332124 }
21342125
21352126 /*
21532144 return ClientKey != 0;
21542145 }
21552146
2147 static void Html_tag_open_img(DilloHtml *html, const char *tag, int tagsize)
2148 {
2149 a_Html_image_attrs(html, tag, tagsize);
2150 }
2151
21562152 /*
21572153 * Create a new Image struct and request the image-url to the cache
21582154 * (If it either hits or misses, is not relevant here; that's up to the
21592155 * cache functions)
21602156 */
2161 static void Html_tag_open_img(DilloHtml *html, const char *tag, int tagsize)
2157 static void Html_tag_content_img(DilloHtml *html, const char *tag, int tagsize)
21622158 {
21632159 DilloImage *Image;
2164 DilloUrl *url, *usemap_url;
2160 DilloUrl *usemap_url;
21652161 const char *attrbuf;
21662162
21672163 /* This avoids loading images. Useful for viewing suspicious HTML email. */
21682164 if (URL_FLAGS(html->base_url) & URL_SpamSafe)
21692165 return;
21702166
2171 if (!(attrbuf = a_Html_get_attr(html, tag, tagsize, "src")) ||
2172 !(url = a_Html_url_new(html, attrbuf, NULL, 0)))
2167 Image = a_Html_image_new(html, tag, tagsize);
2168 if (!Image)
21732169 return;
21742170
21752171 usemap_url = NULL;
21772173 /* TODO: usemap URLs outside of the document are not used. */
21782174 usemap_url = a_Html_url_new(html, attrbuf, NULL, 0);
21792175
2180 Image = a_Html_image_new(html, tag, tagsize, url);
21812176 HT2TB(html)->addWidget((Widget*)Image->dw, html->styleEngine->style());
21822177
21832178 /* Image maps */
22012196 /*
22022197 * <map>
22032198 */
2204 static void Html_tag_open_map(DilloHtml *html, const char *tag, int tagsize)
2199 static void Html_tag_content_map(DilloHtml *html, const char *tag, int tagsize)
22052200 {
22062201 char *hash_name;
22072202 const char *attrbuf;
22262221 /*
22272222 * Handle close <MAP>
22282223 */
2229 static void Html_tag_close_map(DilloHtml *html, int TagIdx)
2224 static void Html_tag_close_map(DilloHtml *html)
22302225 {
22312226 /* This is a hack for the perhaps frivolous feature of drawing image map
22322227 * shapes when there is no image to display. If this map is defined after
22752270 /*
22762271 * <AREA>
22772272 */
2278 static void Html_tag_open_area(DilloHtml *html, const char *tag, int tagsize)
2273 static void
2274 Html_tag_content_area(DilloHtml *html, const char *tag, int tagsize)
22792275 {
22802276 enum types {UNKNOWN, RECTANGLE, CIRCLE, POLYGON, BACKGROUND};
22812277 types type;
24142410 {
24152411 _MSG("Registering ANCHOR: %s\n", name);
24162412 if (!HT2TB(html)->addAnchor (name, html->styleEngine->style ()))
2417 BUG_MSG("Anchor names must be unique within the document\n");
2413 BUG_MSG("Anchor names must be unique within the document ('%s')\n",name);
24182414 /*
24192415 * According to Sec. 12.2.1 of the HTML 4.01 spec, "anchor names that
24202416 * differ only in case may not appear in the same document", but
24352431
24362432 /* TODO: add support for MAP with A HREF */
24372433 if (html->InFlags & IN_MAP)
2438 Html_tag_open_area(html, tag, tagsize);
2434 Html_tag_content_area(html, tag, tagsize);
24392435
24402436 if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "href"))) {
24412437 /* if it's a javascript link, extract the reference. */
24962492 /*
24972493 * <A> close function
24982494 */
2499 static void Html_tag_close_a(DilloHtml *html, int TagIdx)
2495 static void Html_tag_close_a(DilloHtml *html)
25002496 {
25012497 html->InVisitedLink = false;
25022498 }
25282524 /*
25292525 * </Q>
25302526 */
2531 static void Html_tag_close_q(DilloHtml *html, int TagIdx)
2527 static void Html_tag_close_q(DilloHtml *html)
25322528 {
25332529 /* Right Double Quotation Mark */
25342530 const char *U201D = "\xe2\x80\x9d";
25612557 CSS_TYPE_ENUM, list_style_type);
25622558 }
25632559
2564 Html_add_textblock(html, 9);
2565
25662560 S_TOP(html)->list_type = HTML_LIST_UNORDERED;
25672561 S_TOP(html)->list_number = 0;
25682562 S_TOP(html)->ref_list_item = NULL;
26192613 CSS_TYPE_ENUM, listStyleType);
26202614 }
26212615
2622 Html_add_textblock(html, 9);
2623
26242616 S_TOP(html)->list_type = HTML_LIST_ORDERED;
26252617
26262618 if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "start")) &&
26382630 static void Html_tag_open_li(DilloHtml *html, const char *tag, int tagsize)
26392631 {
26402632 Style *style = html->styleEngine->style ();
2641 Style *wordStyle = html->styleEngine->wordStyle ();
2642 Widget **ref_list_item;
2643 ListItem *list_item;
26442633 int *list_number;
26452634 const char *attrbuf;
2646 char buf[16];
26472635
26482636 if (S_TOP(html)->list_type == HTML_LIST_NONE)
26492637 BUG_MSG("<li> outside <ul> or <ol>\n");
26522640
26532641 /* Get our parent tag's variables (used as state storage) */
26542642 list_number = &html->stack->getRef(html->stack->size()-2)->list_number;
2655 ref_list_item = &html->stack->getRef(html->stack->size()-2)->ref_list_item;
2656
2657 HT2TB(html)->addParbreak (0, wordStyle);
2658
2659 list_item = new ListItem ((ListItem*)*ref_list_item,prefs.limit_text_width);
2660 HT2TB(html)->addWidget (list_item, style);
2661 HT2TB(html)->addParbreak (0, wordStyle);
2662 *ref_list_item = list_item;
2663 S_TOP(html)->textblock = html->dw = list_item;
2664
2665 if (style->listStyleType == LIST_STYLE_TYPE_NONE) {
2666 // none
2667 } else if (style->listStyleType >= LIST_STYLE_TYPE_DECIMAL) {
2643
2644 if (style->listStyleType >= LIST_STYLE_TYPE_DECIMAL) {
26682645 // ordered
26692646 if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "value")) &&
26702647 (*list_number = strtol(attrbuf, NULL, 10)) < 0) {
26712648 BUG_MSG("illegal negative LIST VALUE attribute; Starting from 0\n");
26722649 *list_number = 0;
26732650 }
2674 numtostr((*list_number)++, buf, 16, style->listStyleType);
2675 list_item->initWithText (buf, wordStyle);
2676 } else {
2677 // unordered
2678 list_item->initWithWidget (new Bullet(), wordStyle);
26792651 }
26802652 }
26812653
26822654 /*
26832655 * Close <LI>
26842656 */
2685 static void Html_tag_close_li(DilloHtml *html, int TagIdx)
2657 static void Html_tag_close_li(DilloHtml *html)
26862658 {
26872659 html->InFlags &= ~IN_LI;
26882660 ((ListItem *)html->dw)->flush ();
26932665 */
26942666 static void Html_tag_open_hr(DilloHtml *html, const char *tag, int tagsize)
26952667 {
2696 Widget *hruler;
26972668 char *width_ptr;
26982669 const char *attrbuf;
26992670 int32_t size = 0;
27412712 size_bottom);
27422713 }
27432714
2715 }
2716
2717 static void Html_tag_content_hr(DilloHtml *html, const char *tag, int tagsize)
2718 {
2719 Widget *hruler;
27442720 HT2TB(html)->addParbreak (5, html->styleEngine->wordStyle ());
27452721
27462722 hruler = new Ruler();
27902766 /*
27912767 * Custom close for <PRE>
27922768 */
2793 static void Html_tag_close_pre(DilloHtml *html, int TagIdx)
2769 static void Html_tag_close_pre(DilloHtml *html)
27942770 {
27952771 html->InFlags &= ~IN_PRE;
2796 HT2TB(html)->addParbreak (9, html->styleEngine->wordStyle ());
27972772 }
27982773
27992774 /*
28152790 if (tag_idx == ei_set[i])
28162791 return 1;
28172792 return 0;
2793 }
2794
2795 /*
2796 * Update the document's content type information based on meta tag data.
2797 */
2798 static void Html_update_content_type(DilloHtml *html, const char *content)
2799 {
2800 const char *new_content = a_Capi_set_content_type(html->page_url, content,
2801 "meta");
2802 /* Cannot ask cache whether the content type was changed, as
2803 * this code in another bw might have already changed it for us.
2804 */
2805 if (a_Misc_content_type_cmp(html->content_type, new_content)) {
2806 html->stop_parser = true; /* The cache buffer is no longer valid */
2807 a_UIcmd_repush(html->bw);
2808 }
28182809 }
28192810
28202811 /*
28402831 " <tr><td bgcolor='#a0a0a0' colspan='2'>The author wanted you to go\n"
28412832 " <a href='%s'>here</a>%s</td></tr></table><br>\n";
28422833
2843 const char *p, *equiv, *content, *new_content;
2834 const char *p, *equiv, *charset, *content;
28442835 char delay_str[64], *mr_url;
28452836 DilloUrl *new_url;
28462837 int delay;
28472838
28482839 /* only valid inside HEAD */
28492840 if (!(html->InFlags & IN_HEAD)) {
2850 BUG_MSG("META elements must be inside the HEAD section\n");
2841 BUG_MSG("META element must be inside the HEAD section\n");
28512842 return;
28522843 }
28532844
29072898 } else if (!dStrAsciiCasecmp(equiv, "content-type") &&
29082899 (content = a_Html_get_attr(html, tag, tagsize, "content"))) {
29092900 _MSG("Html_tag_open_meta: content={%s}\n", content);
2910 /* Cannot ask cache whether the content type was changed, as
2911 * this code in another bw might have already changed it for us.
2912 */
2913 new_content = a_Capi_set_content_type(html->page_url,content,"meta");
2914 if (a_Misc_content_type_cmp(html->content_type, new_content)) {
2915 html->stop_parser = true; /* The cache buffer is no longer valid */
2916 a_UIcmd_repush(html->bw);
2917 }
2918 }
2901 Html_update_content_type(html, content);
2902 }
2903 } else if (html->DocType == DT_HTML && html->DocTypeVersion == 5.0f &&
2904 (charset = a_Html_get_attr(html, tag, tagsize, "charset"))) {
2905 char *content = dStrconcat("text/html; charset=", charset, NULL);
2906
2907 Html_update_content_type(html, content);
2908 dFree(content);
29192909 }
29202910 }
29212911
29742964 ++html->bw->NumPendingStyleSheets;
29752965 a_Bw_add_client(html->bw, ClientKey, 0);
29762966 a_Bw_add_url(html->bw, url);
2977 MSG("NumPendingStyleSheets=%d", html->bw->NumPendingStyleSheets);
2978 }
2979 }
2980 MSG("\n");
2967 MSG("NumPendingStyleSheets=%d\n", html->bw->NumPendingStyleSheets);
2968 }
2969 }
2970 _MSG("\n");
29812971 }
29822972
29832973 /*
30022992
30032993 /* Ignore LINK outside HEAD */
30042994 if (!(html->InFlags & IN_HEAD)) {
3005 BUG_MSG("the LINK element must be inside the HEAD section\n");
2995 BUG_MSG("LINK element must be inside the HEAD section\n");
30062996 return;
30072997 }
30082998 /* Remote stylesheets enabled? */
30283018 html->addCssUrl(url);
30293019 a_Url_free(url);
30303020 }
3031
3032 /*
3033 * Set the history of the menu to be consistent with the active menuitem.
3034 */
3035 //static void Html_select_set_history(DilloHtmlInput *input)
3036 //{
3037 // int i;
3038 //
3039 // for (i = 0; i < input->select->num_options; i++) {
3040 // if (GTK_CHECK_MENU_ITEM(input->select->options[i].menuitem)->active) {
3041 // gtk_option_menu_set_history(GTK_OPTION_MENU(input->widget), i);
3042 // break;
3043 // }
3044 // }
3045 //}
3046
30473021
30483022 /*
30493023 * Set the Document Base URI
30783052 }
30793053
30803054 /*
3055 * <SPAN>
3056 */
3057 static void Html_tag_open_span(DilloHtml *html, const char *tag, int tagsize)
3058 {
3059 const char *attrbuf;
3060
3061 html->styleEngine->inheritBackgroundColor();
3062
3063 if (prefs.show_tooltip &&
3064 (attrbuf = a_Html_get_attr(html, tag, tagsize, "title"))) {
3065
3066 html->styleEngine->setNonCssHint (PROPERTY_X_TOOLTIP, CSS_TYPE_STRING,
3067 attrbuf);
3068 }
3069 }
3070
3071 /*
30813072 * <DIV> (TODO: make a complete implementation)
30823073 */
30833074 static void Html_tag_open_div(DilloHtml *html, const char *tag, int tagsize)
30843075 {
3076 const char *attrbuf;
3077
30853078 a_Html_tag_set_align_attr (html, tag, tagsize);
3086 Html_add_textblock(html, 0);
3087 }
3088
3089 /*
3090 * Default close for most tags.
3091 */
3092 static void Html_tag_close_default(DilloHtml *html, int TagIdx)
3093 {
3079
3080 if (prefs.show_tooltip &&
3081 (attrbuf = a_Html_get_attr(html, tag, tagsize, "title"))) {
3082
3083 html->styleEngine->setNonCssHint (PROPERTY_X_TOOLTIP, CSS_TYPE_STRING,
3084 attrbuf);
3085 }
30943086 }
30953087
30963088 /*
30973089 * Default close for paragraph tags - pop the stack and break.
30983090 */
3099 static void Html_tag_close_par(DilloHtml *html, int TagIdx)
3091 static void Html_tag_close_par(DilloHtml *html)
31003092 {
31013093 HT2TB(html)->addParbreak (9, html->styleEngine->wordStyle ());
31023094 }
31033095
31043096
31053097 /*
3106 * Function index for the open and close functions for each tag
3107 * (Alphabetically sorted for a binary search)
3098 * Function index for the open, content, and close functions for each tag
3099 * (Alphabetically sorted for a binary search).
3100 * The open and close functions are always called. They are used for style
3101 * handling and HTML bug reporting.
3102 * Content creation (e.g. adding new widgets or text) is done in the content
3103 * function, which is not called in the display:none case.
3104 * Note: many tags don't need a content function (e.g. <div>, <span>, ...).
31083105 *
31093106 * Explanation for the 'Flags' field:
31103107 *
31223119 * (flow have both set)
31233120 */
31243121
3125
31263122 const TagInfo Tags[] = {
3127 {"a", B8(010101),'R',2, Html_tag_open_a, Html_tag_close_a},
3128 {"abbr", B8(010101),'R',2, Html_tag_open_abbr, Html_tag_close_default},
3123 {"a", B8(010101),'R',2, Html_tag_open_a, NULL, Html_tag_close_a},
3124 {"abbr", B8(010101),'R',2, Html_tag_open_abbr, NULL, NULL},
31293125 /* acronym 010101 */
3130 {"address", B8(010110),'R',2, Html_tag_open_address, Html_tag_close_par},
3131 {"area", B8(010001),'F',0, Html_tag_open_area, Html_tag_close_default},
3132 {"b", B8(010101),'R',2, Html_tag_open_default, Html_tag_close_default},
3133 {"base", B8(100001),'F',0, Html_tag_open_base, Html_tag_close_default},
3126 {"address", B8(010110),'R',2,Html_tag_open_default, NULL, Html_tag_close_par},
3127 {"area", B8(010001),'F',0, Html_tag_open_default, Html_tag_content_area,
3128 NULL},
3129 {"b", B8(010101),'R',2, Html_tag_open_default, NULL, NULL},
3130 {"base", B8(100001),'F',0, Html_tag_open_base, NULL, NULL},
31343131 /* basefont 010001 */
31353132 /* bdo 010101 */
3136 {"big", B8(010101),'R',2, Html_tag_open_default, Html_tag_close_default},
3137 {"blockquote", B8(011110),'R',2, Html_tag_open_blockquote,
3138 Html_tag_close_default},
3139 {"body", B8(011110),'O',1, Html_tag_open_body, Html_tag_close_body},
3140 {"br", B8(010001),'F',0, Html_tag_open_br, Html_tag_close_default},
3141 {"button", B8(011101),'R',2, Html_tag_open_button, Html_tag_close_button},
3133 {"big", B8(010101),'R',2, Html_tag_open_default, NULL, NULL},
3134 {"blockquote", B8(011110),'R',2, Html_tag_open_blockquote, NULL,
3135 NULL},
3136 {"body", B8(011110),'O',1, Html_tag_open_body, NULL, Html_tag_close_body},
3137 {"br", B8(010001),'F',0, Html_tag_open_default, Html_tag_content_br,
3138 NULL},
3139 {"button", B8(011101),'R',2, Html_tag_open_button,NULL,Html_tag_close_button},
31423140 /* caption */
3143 {"center", B8(011110),'R',2, Html_tag_open_center, Html_tag_close_center},
3144 {"cite", B8(010101),'R',2, Html_tag_open_default, Html_tag_close_default},
3145 {"code", B8(010101),'R',2, Html_tag_open_default, Html_tag_close_default},
3141 {"center", B8(011110),'R',2, Html_tag_open_default, NULL, NULL},
3142 {"cite", B8(010101),'R',2, Html_tag_open_default, NULL, NULL},
3143 {"code", B8(010101),'R',2, Html_tag_open_default, NULL, NULL},
31463144 /* col 010010 'F' */
31473145 /* colgroup */
3148 {"dd", B8(011110),'O',1, Html_tag_open_dd, Html_tag_close_default},
3149 {"del", B8(011101),'R',2, Html_tag_open_default, Html_tag_close_default},
3150 {"dfn", B8(010101),'R',2, Html_tag_open_default, Html_tag_close_default},
3151 {"dir", B8(011010),'R',2, Html_tag_open_dir, Html_tag_close_par},
3146 {"dd", B8(011110),'O',1, Html_tag_open_dd, NULL, NULL},
3147 {"del", B8(011101),'R',2, Html_tag_open_default, NULL, NULL},
3148 {"dfn", B8(010101),'R',2, Html_tag_open_default, NULL, NULL},
3149 {"dir", B8(011010),'R',2, Html_tag_open_dir, NULL, Html_tag_close_par},
31523150 /* TODO: complete <div> support! */
3153 {"div", B8(011110),'R',2, Html_tag_open_div, Html_tag_close_default},
3154 {"dl", B8(011010),'R',2, Html_tag_open_dl, Html_tag_close_par},
3155 {"dt", B8(010110),'O',1, Html_tag_open_dt, Html_tag_close_par},
3156 {"em", B8(010101),'R',2, Html_tag_open_default, Html_tag_close_default},
3151 {"div", B8(011110),'R',2, Html_tag_open_div, NULL, NULL},
3152 {"dl", B8(011010),'R',2, Html_tag_open_dl, NULL, Html_tag_close_par},
3153 {"dt", B8(010110),'O',1, Html_tag_open_dt, NULL, Html_tag_close_par},
3154 {"em", B8(010101),'R',2, Html_tag_open_default, NULL, NULL},
31573155 /* fieldset */
3158 {"font", B8(010101),'R',2, Html_tag_open_font, Html_tag_close_default},
3159 {"form", B8(011110),'R',2, Html_tag_open_form, Html_tag_close_form},
3160 {"frame", B8(010010),'F',0, Html_tag_open_frame, Html_tag_close_default},
3161 {"frameset", B8(011110),'R',2,Html_tag_open_frameset, Html_tag_close_default},
3162 {"h1", B8(010110),'R',2, Html_tag_open_h, Html_tag_close_par},
3163 {"h2", B8(010110),'R',2, Html_tag_open_h, Html_tag_close_par},
3164 {"h3", B8(010110),'R',2, Html_tag_open_h, Html_tag_close_par},
3165 {"h4", B8(010110),'R',2, Html_tag_open_h, Html_tag_close_par},
3166 {"h5", B8(010110),'R',2, Html_tag_open_h, Html_tag_close_par},
3167 {"h6", B8(010110),'R',2, Html_tag_open_h, Html_tag_close_par},
3168 {"head", B8(101101),'O',1, Html_tag_open_head, Html_tag_close_head},
3169 {"hr", B8(010010),'F',0, Html_tag_open_hr, Html_tag_close_default},
3170 {"html", B8(001110),'O',1, Html_tag_open_html, Html_tag_close_html},
3171 {"i", B8(010101),'R',2, Html_tag_open_default, Html_tag_close_default},
3172 {"iframe", B8(011110),'R',2, Html_tag_open_frame, Html_tag_close_default},
3173 {"img", B8(010001),'F',0, Html_tag_open_img, Html_tag_close_default},
3174 {"input", B8(010001),'F',0, Html_tag_open_input, Html_tag_close_default},
3156 {"font", B8(010101),'R',2, Html_tag_open_font, NULL, NULL},
3157 {"form", B8(011110),'R',2, Html_tag_open_form, NULL, Html_tag_close_form},
3158 {"frame", B8(010010),'F',0, Html_tag_open_frame, Html_tag_content_frame,
3159 NULL},
3160 {"frameset", B8(011110),'R',2, Html_tag_open_default,
3161 Html_tag_content_frameset, NULL},
3162 {"h1", B8(010110),'R',2, Html_tag_open_h, NULL, NULL},
3163 {"h2", B8(010110),'R',2, Html_tag_open_h, NULL, NULL},
3164 {"h3", B8(010110),'R',2, Html_tag_open_h, NULL, NULL},
3165 {"h4", B8(010110),'R',2, Html_tag_open_h, NULL, NULL},
3166 {"h5", B8(010110),'R',2, Html_tag_open_h, NULL, NULL},
3167 {"h6", B8(010110),'R',2, Html_tag_open_h, NULL, NULL},
3168 {"head", B8(101101),'O',1, Html_tag_open_head, NULL, Html_tag_close_head},
3169 {"hr", B8(010010),'F',0, Html_tag_open_hr, Html_tag_content_hr,
3170 NULL},
3171 {"html", B8(001110),'O',1, Html_tag_open_html, NULL, Html_tag_close_html},
3172 {"i", B8(010101),'R',2, Html_tag_open_default, NULL, NULL},
3173 {"iframe", B8(011110),'R',2, Html_tag_open_frame, Html_tag_content_frame,
3174 NULL},
3175 {"img", B8(010001),'F',0, Html_tag_open_img, Html_tag_content_img,
3176 NULL},
3177 {"input", B8(010001),'F',0, Html_tag_open_input, NULL, NULL},
31753178 /* ins */
3176 {"isindex", B8(110001),'F',0, Html_tag_open_isindex, Html_tag_close_default},
3177 {"kbd", B8(010101),'R',2, Html_tag_open_default, Html_tag_close_default},
3179 {"isindex", B8(110001),'F',0, Html_tag_open_isindex, NULL, NULL},
3180 {"kbd", B8(010101),'R',2, Html_tag_open_default, NULL, NULL},
31783181 /* label 010101 */
31793182 /* legend 01?? */
3180 {"li", B8(011110),'O',1, Html_tag_open_li, Html_tag_close_li},
3181 {"link", B8(100001),'F',0, Html_tag_open_link, Html_tag_close_default},
3182 {"map", B8(011001),'R',2, Html_tag_open_map, Html_tag_close_map},
3183 {"li", B8(011110),'O',1, Html_tag_open_li, NULL, Html_tag_close_li},
3184 {"link", B8(100001),'F',0, Html_tag_open_link, NULL, NULL},
3185 {"map", B8(011001),'R',2, Html_tag_open_default, Html_tag_content_map,
3186 Html_tag_close_map},
31833187 /* menu 1010 -- TODO: not exactly 1010, it can contain LI and inline */
3184 {"menu", B8(011010),'R',2, Html_tag_open_menu, Html_tag_close_par},
3185 {"meta", B8(100001),'F',0, Html_tag_open_meta, Html_tag_close_default},
3188 {"menu", B8(011010),'R',2, Html_tag_open_menu, NULL, Html_tag_close_par},
3189 {"meta", B8(100001),'F',0, Html_tag_open_meta, NULL, NULL},
31863190 /* noframes 1011 */
31873191 /* noscript 1011 */
3188 {"object", B8(111101),'R',2, Html_tag_open_object, Html_tag_close_default},
3189 {"ol", B8(011010),'R',2, Html_tag_open_ol, Html_tag_close_default},
3192 {"object", B8(111101),'R',2, Html_tag_open_object, NULL, NULL},
3193 {"ol", B8(011010),'R',2, Html_tag_open_ol, NULL, NULL},
31903194 /* optgroup */
3191 {"option", B8(010001),'O',1, Html_tag_open_option, Html_tag_close_default},
3192 {"p", B8(010110),'O',1, Html_tag_open_p, Html_tag_close_par},
3195 {"option", B8(010001),'O',1, Html_tag_open_option,NULL,Html_tag_close_option},
3196 {"p", B8(010110),'O',1, Html_tag_open_p, NULL, NULL},
31933197 /* param 010001 'F' */
3194 {"pre", B8(010110),'R',2, Html_tag_open_pre, Html_tag_close_pre},
3195 {"q", B8(010101),'R',2, Html_tag_open_q, Html_tag_close_q},
3196 {"s", B8(010101),'R',2, Html_tag_open_default, Html_tag_close_default},
3197 {"samp", B8(010101),'R',2, Html_tag_open_default, Html_tag_close_default},
3198 {"script", B8(111001),'R',2, Html_tag_open_script, Html_tag_close_script},
3199 {"select", B8(010101),'R',2, Html_tag_open_select, Html_tag_close_select},
3200 {"small", B8(010101),'R',2, Html_tag_open_default, Html_tag_close_default},
3201 {"span", B8(010101),'R',2, Html_tag_open_default, Html_tag_close_default},
3202 {"strike", B8(010101),'R',2, Html_tag_open_default, Html_tag_close_default},
3203 {"strong", B8(010101),'R',2, Html_tag_open_default, Html_tag_close_default},
3204 {"style", B8(100101),'R',2, Html_tag_open_style, Html_tag_close_style},
3205 {"sub", B8(010101),'R',2, Html_tag_open_default, Html_tag_close_default},
3206 {"sup", B8(010101),'R',2, Html_tag_open_default, Html_tag_close_default},
3207 {"table", B8(011010),'R',5, Html_tag_open_table, Html_tag_close_center},
3198 {"pre", B8(010110),'R',2, Html_tag_open_pre, NULL, Html_tag_close_pre},
3199 {"q", B8(010101),'R',2, Html_tag_open_q, NULL, Html_tag_close_q},
3200 {"s", B8(010101),'R',2, Html_tag_open_default, NULL, NULL},
3201 {"samp", B8(010101),'R',2, Html_tag_open_default, NULL, NULL},
3202 {"script", B8(111001),'R',2, Html_tag_open_script,NULL,Html_tag_close_script},
3203 {"select", B8(010101),'R',2, Html_tag_open_select,NULL,Html_tag_close_select},
3204 {"small", B8(010101),'R',2, Html_tag_open_default, NULL, NULL},
3205 {"span", B8(010101),'R',2, Html_tag_open_span, NULL, NULL},
3206 {"strike", B8(010101),'R',2, Html_tag_open_default, NULL, NULL},
3207 {"strong", B8(010101),'R',2, Html_tag_open_default, NULL, NULL},
3208 {"style", B8(100101),'R',2, Html_tag_open_style, NULL, Html_tag_close_style},
3209 {"sub", B8(010101),'R',2, Html_tag_open_default, NULL, NULL},
3210 {"sup", B8(010101),'R',2, Html_tag_open_default, NULL, NULL},
3211 {"table", B8(011010),'R',5, Html_tag_open_table, Html_tag_content_table,
3212 NULL},
32083213 /* tbody */
3209 {"td", B8(011110),'O',3, Html_tag_open_td, Html_tag_close_default},
3210 {"textarea", B8(010101),'R',2,Html_tag_open_textarea,Html_tag_close_textarea},
3214 {"td", B8(011110),'O',3, Html_tag_open_td, Html_tag_content_td,
3215 NULL},
3216 {"textarea", B8(010101),'R', 2, Html_tag_open_textarea,
3217 Html_tag_content_textarea, Html_tag_close_textarea},
32113218 /* tfoot */
3212 {"th", B8(011110),'O',1, Html_tag_open_th, Html_tag_close_default},
3219 {"th", B8(011110),'O',1, Html_tag_open_th, Html_tag_content_th,
3220 NULL},
32133221 /* thead */
3214 {"title", B8(100101),'R',2, Html_tag_open_title, Html_tag_close_title},
3215 {"tr", B8(011010),'O',4, Html_tag_open_tr, Html_tag_close_default},
3216 {"tt", B8(010101),'R',2, Html_tag_open_default, Html_tag_close_default},
3217 {"u", B8(010101),'R',2, Html_tag_open_default, Html_tag_close_default},
3218 {"ul", B8(011010),'R',2, Html_tag_open_ul, Html_tag_close_default},
3219 {"var", B8(010101),'R',2, Html_tag_open_default, Html_tag_close_default}
3222 {"title", B8(100101),'R',2, Html_tag_open_title, NULL, Html_tag_close_title},
3223 {"tr", B8(011010),'O',4, Html_tag_open_tr, Html_tag_content_tr,
3224 NULL},
3225 {"tt", B8(010101),'R',2, Html_tag_open_default, NULL, NULL},
3226 {"u", B8(010101),'R',2, Html_tag_open_default, NULL, NULL},
3227 {"ul", B8(011010),'R',2, Html_tag_open_ul, NULL, NULL},
3228 {"var", B8(010101),'R',2, Html_tag_open_default, NULL, NULL}
32203229
32213230 };
32223231 #define NTAGS (sizeof(Tags)/sizeof(Tags[0]))
34283437 const char *attrbuf;
34293438
34303439 if (tagsize >= 8 && /* length of "<t id=i>" */
3431 (attrbuf = Html_get_attr2(html, tag, tagsize, "id",
3432 HTML_LeftTrim | HTML_RightTrim))) {
3440 (attrbuf = a_Html_get_attr(html, tag, tagsize, "id"))) {
34333441 /* According to the SGML declaration of HTML 4, all NAME values
34343442 * occuring outside entities must be converted to uppercase
34353443 * (this is what "NAMECASE GENERAL YES" says). But the HTML 4
34433451
34443452 if (tagsize >= 11 && (prefs.parse_embedded_css || prefs.load_stylesheets)) {
34453453 /* length of "<t class=i>" or "<t style=i>" */
3446 attrbuf = Html_get_attr2(html, tag, tagsize, "class",
3447 HTML_LeftTrim | HTML_RightTrim);
3454 attrbuf = a_Html_get_attr(html, tag, tagsize, "class");
34483455 if (attrbuf)
34493456 html->styleEngine->setClass (attrbuf);
34503457
3451 attrbuf = Html_get_attr2(html, tag, tagsize, "style",
3452 HTML_LeftTrim | HTML_RightTrim);
3458 attrbuf = a_Html_get_attr(html, tag, tagsize, "style");
34533459 if (attrbuf)
34543460 html->styleEngine->setStyle (attrbuf);
34553461 }
34563462
3463 /* handle "xml:lang" and "lang" attributes */
3464 int hasXmlLang = 0;
3465 if (tagsize >= 14) {
3466 /* length of "<t xml:lang=i>" */
3467 attrbuf = a_Html_get_attr(html, tag, tagsize, "xml:lang");
3468 if (attrbuf) {
3469 html->styleEngine->setNonCssHint(PROPERTY_X_LANG, CSS_TYPE_STRING,
3470 attrbuf);
3471 hasXmlLang = 1;
3472 }
3473 }
3474 if (!hasXmlLang && tagsize >= 10) { /* 'xml:lang' prevails over 'lang' */
3475 /* length of "<t lang=i>" */
3476 attrbuf = a_Html_get_attr(html, tag, tagsize, "lang");
3477 if (attrbuf)
3478 html->styleEngine->setNonCssHint(PROPERTY_X_LANG, CSS_TYPE_STRING,
3479 attrbuf);
3480 }
3481 }
3482
3483 static void Html_display_block(DilloHtml *html)
3484 {
3485 //HT2TB(html)->addParbreak (5, html->styleEngine->wordStyle ());
3486 Html_add_textblock(html, 0);
3487 }
3488
3489 static void Html_display_listitem(DilloHtml *html)
3490 {
3491 Style *style = html->styleEngine->style ();
3492 Style *wordStyle = html->styleEngine->wordStyle ();
3493 Widget **ref_list_item;
3494 ListItem *list_item;
3495 int *list_number;
3496 char buf[16];
3497
3498 /* Get our parent tag's variables (used as state storage) */
3499 list_number = &html->stack->getRef(html->stack->size()-2)->list_number;
3500 ref_list_item = &html->stack->getRef(html->stack->size()-2)->ref_list_item;
3501
3502 HT2TB(html)->addParbreak (0, wordStyle);
3503
3504 list_item = new ListItem ((ListItem*)*ref_list_item,prefs.limit_text_width);
3505 HT2TB(html)->addWidget (list_item, style);
3506 HT2TB(html)->addParbreak (0, wordStyle);
3507 *ref_list_item = list_item;
3508 S_TOP(html)->textblock = html->dw = list_item;
3509
3510 if (style->listStyleType == LIST_STYLE_TYPE_NONE) {
3511 // none
3512 } else if (style->listStyleType >= LIST_STYLE_TYPE_DECIMAL) {
3513 // ordered
3514 numtostr((*list_number)++, buf, 16, style->listStyleType);
3515 list_item->initWithText (buf, wordStyle);
3516 } else {
3517 // unordered
3518 list_item->initWithWidget (new Bullet(), wordStyle);
3519 }
34573520 }
34583521
34593522 /*
35123575 /* Call the open function for this tag */
35133576 _MSG("Open : %s\n", Tags[ni].name);
35143577 Tags[ni].open (html, tag, tagsize);
3578
3579 if (! S_TOP(html)->display_none) {
3580 switch (html->styleEngine->style ()->display) {
3581 case DISPLAY_BLOCK:
3582 Html_display_block(html);
3583 break;
3584 case DISPLAY_LIST_ITEM:
3585 Html_display_listitem(html);
3586 break;
3587 case DISPLAY_NONE:
3588 S_TOP(html)->display_none = true;
3589 break;
3590 case DISPLAY_INLINE:
3591 case DISPLAY_INLINE_BLOCK: // TODO: implement inline-block
3592 default:
3593 break;
3594 }
3595
3596 if (Tags[ni].content && ! S_TOP(html)->display_none) {
3597 Tags[ni].content (html, tag, tagsize);
3598 }
3599 }
3600
35153601 if (html->stop_parser)
35163602 break;
35173603
35293615 /* Request immediate close for elements with forbidden close tag. */
35303616 /* TODO: XHTML always requires close tags. A simple implementation
35313617 * of the commented clause below will make it work. */
3532 if (/* parsing HTML && */ Tags[ni].EndTag == 'F')
3618 if (/* parsing HTML && */ Tags[ni].EndTag == 'F')
35333619 html->ReqTagClose = true;
35343620
35353621 /* Don't break! Open tags may also close themselves */
38033889 } else if (ch == '<') {
38043890 /* unterminated tag detected */
38053891 p = dStrndup(buf+token_start+1,
3806 strcspn(buf+token_start+1, " <"));
3892 strcspn(buf+token_start+1, " <\n\r\t"));
38073893 BUG_MSG("<%s> element lacks its closing '>'\n", p);
38083894 dFree(p);
38093895 --buf_index;
3333 html->bugMessage(__VA_ARGS__); \
3434 } D_STMT_END
3535
36
3637 /*
3738 * Typedefs
3839 */
39
40 typedef struct _DilloHtmlImage DilloHtmlImage;
41 typedef struct _DilloHtmlState DilloHtmlState;
4240
4341 typedef enum {
4442 DT_NONE,
9290 * Data Structures
9391 */
9492
95 struct _DilloHtmlImage {
93 typedef struct {
9694 DilloUrl *url;
9795 DilloImage *image;
98 };
99
100 struct _DilloHtmlState {
96 } DilloHtmlImage;
97
98 typedef struct {
10199 DilloHtmlParseMode parse_mode;
102100 DilloHtmlTableMode table_mode;
103101 DilloHtmlTableBorderMode table_border_mode;
104102 bool cell_text_align_set;
105
103 bool display_none;
106104 DilloHtmlListMode list_type;
107105 int list_number;
108106
118116 have to be "handed over" (see Html_add_indented and
119117 Html_eventually_pop_dw). */
120118 bool hand_over_break;
121 };
119 } DilloHtmlState;
122120
123121 /*
124122 * Classes
237235 const char *url_str, const char *base_url,
238236 int use_base_url);
239237
240 DilloImage *a_Html_image_new(DilloHtml *html, const char *tag,
241 int tagsize, DilloUrl *url);
238 void a_Html_image_attrs(DilloHtml *html, const char *tag, int tagsize);
239 DilloImage *a_Html_image_new(DilloHtml *html, const char *tag, int tagsize);
242240
243241 char *a_Html_parse_entities(DilloHtml *html, const char *token, int toksize);
244242 void a_Html_pop_tag(DilloHtml *html, int TagIdx);
245243 void a_Html_stash_init(DilloHtml *html);
246 int32_t a_Html_color_parse(DilloHtml *html,
247 const char *subtag, int32_t default_color);
244 int32_t a_Html_color_parse(DilloHtml *html, const char *str,
245 int32_t default_color);
248246 dw::core::style::Length a_Html_parse_length (DilloHtml *html,
249247 const char *attr);
250248 void a_Html_tag_set_align_attr(DilloHtml *html, const char *tag, int tagsize);
4545 DILLO_JPEG_ERROR
4646 } DilloJpegState;
4747
48 typedef struct DilloJpeg DilloJpeg;
49
4850 /* An implementation of a suspending source manager */
4951
5052 typedef struct {
5153 struct jpeg_source_mgr pub; /* public fields */
52 struct DilloJpeg *jpeg; /* a pointer back to the jpeg object */
54 DilloJpeg *jpeg; /* a pointer back to the jpeg object */
5355 } my_source_mgr;
5456
5557 struct my_error_mgr {
5658 struct jpeg_error_mgr pub; /* "public" fields */
5759 jmp_buf setjmp_buffer; /* for return to caller */
5860 };
59 typedef struct my_error_mgr * my_error_ptr;
60
61 typedef struct DilloJpeg {
61 typedef struct my_error_mgr *my_error_ptr;
62
63 struct DilloJpeg {
6264 DilloImage *Image;
6365 DilloUrl *url;
6466 int version;
7375
7476 struct jpeg_decompress_struct cinfo;
7577 struct my_error_mgr jerr;
76 } DilloJpeg;
78 };
7779
7880 /*
7981 * Forward declarations
8082 */
8183 static void Jpeg_write(DilloJpeg *jpeg, void *Buf, uint_t BufSize);
82 METHODDEF(void) Jpeg_errorexit (j_common_ptr cinfo);
8384
8485
8586 /* this is the routine called by libjpeg when it detects an error. */
121121 { "forward" , KEYS_FORWARD , 0 , '.' },
122122 { "goto" , KEYS_GOTO , FL_CTRL , 'l' },
123123 { "home" , KEYS_HOME , FL_CTRL , 'h' },
124 { "view-source" , KEYS_VIEW_SOURCE , FL_CTRL , 'u' },
124125 { "screen-up" , KEYS_SCREEN_UP , 0 , FL_Page_Up },
125126 { "screen-up" , KEYS_SCREEN_UP , 0 , 'b' },
126127 { "screen-down" , KEYS_SCREEN_DOWN , 0 , FL_Page_Down },
148149
149150 // Fill our key bindings list
150151 bindings = dList_new(32);
151 for (uint_t i = 0; i < sizeof(default_keys) / sizeof(KeyBinding_t); i++) {
152 for (uint_t i = 0; i < sizeof(default_keys) / sizeof(default_keys[0]); i++) {
152153 if (default_keys[i].key) {
153154 node = dNew(KeyBinding_t, 1);
154155 node->name = dStrdup(default_keys[i].name);
243244 int Keys::getKeyCode(char *keyName)
244245 {
245246 uint_t i;
246 for (i = 0; i < sizeof(keyNames) / sizeof(Mapping_t); i++) {
247 for (i = 0; i < sizeof(keyNames) / sizeof(keyNames[0]); i++) {
247248 if (!dStrAsciiCasecmp(keyNames[i].name, keyName)) {
248249 return keyNames[i].value;
249250 }
274275 int Keys::getModifier(char *modifierName)
275276 {
276277 uint_t i;
277 for (i = 0; i < sizeof(modifierNames) / sizeof(Mapping_t); i++) {
278 for (i = 0; i < sizeof(modifierNames) / sizeof(modifierNames[0]); i++) {
278279 if (!dStrAsciiCasecmp(modifierNames[i].name, modifierName)) {
279280 return modifierNames[i].value;
280281 }
3636 KEYS_FORWARD,
3737 KEYS_GOTO,
3838 KEYS_HOME,
39 KEYS_VIEW_SOURCE,
3940 KEYS_SCREEN_UP,
4041 KEYS_SCREEN_DOWN,
4142 KEYS_SCREEN_LEFT,
7171 # "file-menu" pops up the file menu.
7272 #<alt>f = file-menu
7373
74 # "view-source" displays the page source.
75 #<ctrl>u = view-source
76
7477 # "goto" goes to the location bar at the top of the window.
7578 #<ctrl>l = goto
7679
77 extern "C" {
88 #endif /* __cplusplus */
99
10 typedef struct _KlistNode KlistNode_t;
11 typedef struct _Klist Klist_t;
12
13 struct _KlistNode {
10 typedef struct {
1411 int Key; /* primary key */
1512 void *Data; /* data reference */
16 };
13 } KlistNode_t;
1714
18 struct _Klist {
15 typedef struct {
1916 Dlist *List;
2017 int Clean; /* check flag */
2118 int Counter; /* counter (for making keys) */
22 };
19 } Klist_t;
2320
2421
2522 /*
1515 */
1616 #define a_List_resize(list,num_items,alloc_step) \
1717 if (!list) { \
18 list = dMalloc(alloc_step * sizeof((*list))); \
18 list = dMalloc(alloc_step * sizeof(*list)); \
1919 } \
2020 if (num_items >= alloc_step){ \
2121 while ( num_items >= alloc_step ) \
2222 alloc_step <<= 1; \
23 list = dRealloc(list, alloc_step * sizeof((*list))); \
23 list = dRealloc(list, alloc_step * sizeof(*list)); \
2424 }
2525
2626
2222 #include "ui.hh" // for (UI *)
2323 #include "keys.hh"
2424 #include "timeout.hh"
25
26 /*
27 * Local data types
28 */
29
30 typedef struct {
31 const char *title;
32 const Fl_Menu_Item *picked;
33 const Fl_Menu_Item *menu;
34 } Menu_popup_data_t;
2535
2636 /*
2737 * Local data
6777 }
6878
6979
70 static void Menu_copy_urlstr_cb(Fl_Widget*, void*)
71 {
72 if (popup_url)
73 a_UIcmd_copy_urlstr(popup_bw, URL_STR(popup_url));
74 }
75
76 static void Menu_link_cb(Fl_Widget*, void *user_data)
77 {
78 DilloUrl *url = (DilloUrl *) user_data ;
79 _MSG("Menu_link_cb: click! :-)\n");
80
81 if (url)
82 a_Menu_link_popup(popup_bw, url);
80 static void Menu_copy_urlstr_cb(Fl_Widget*, void *user_data)
81 {
82 if (user_data) {
83 DilloUrl *url = (DilloUrl *)user_data ;
84 a_UIcmd_copy_urlstr(popup_bw, URL_STR(url));
85 }
8386 }
8487
8588 /*
8689 * Open URL
8790 */
88 static void Menu_open_url_cb(Fl_Widget*, void*)
89 {
91 static void Menu_open_url_cb(Fl_Widget*, void *user_data)
92 {
93 DilloUrl *url = (DilloUrl *)user_data;
9094 _MSG("Open URL cb: click! :-)\n");
91 a_UIcmd_open_url(popup_bw, popup_url);
95 a_UIcmd_open_url(popup_bw, url);
9296 }
9397
9498 /*
9599 * Open URL in new window
96100 */
97 static void Menu_open_url_nw_cb(Fl_Widget*, void*)
98 {
101 static void Menu_open_url_nw_cb(Fl_Widget*, void *user_data)
102 {
103 DilloUrl *url = (DilloUrl *)user_data;
99104 _MSG("Open URL in new window cb: click! :-)\n");
100 a_UIcmd_open_url_nw(popup_bw, popup_url);
105 a_UIcmd_open_url_nw(popup_bw, url);
101106 }
102107
103108 /*
104109 * Open URL in new Tab
105110 */
106 static void Menu_open_url_nt_cb(Fl_Widget*, void*)
107 {
111 static void Menu_open_url_nt_cb(Fl_Widget*, void *user_data)
112 {
113 DilloUrl *url = (DilloUrl *)user_data;
108114 int focus = prefs.focus_new_tab ? 1 : 0;
109115 if (Fl::event_state(FL_SHIFT)) focus = !focus;
110 a_UIcmd_open_url_nt(popup_bw, popup_url, focus);
116 a_UIcmd_open_url_nt(popup_bw, url, focus);
111117 }
112118
113119 /*
114120 * Add bookmark
115121 */
116 static void Menu_add_bookmark_cb(Fl_Widget*, void*)
117 {
118 a_UIcmd_add_bookmark(popup_bw, popup_url);
122 static void Menu_add_bookmark_cb(Fl_Widget*, void *user_data)
123 {
124 DilloUrl *url = (DilloUrl *)user_data;
125 a_UIcmd_add_bookmark(popup_bw, url);
119126 }
120127
121128 /*
129136 /*
130137 * Save link
131138 */
132 static void Menu_save_link_cb(Fl_Widget*, void*)
133 {
134 a_UIcmd_save_link(popup_bw, popup_url);
139 static void Menu_save_link_cb(Fl_Widget*, void *user_data)
140 {
141 DilloUrl *url = (DilloUrl *)user_data;
142 a_UIcmd_save_link(popup_bw, url);
135143 }
136144
137145 /*
145153 /*
146154 * View current page source
147155 */
148 static void Menu_view_page_source_cb(Fl_Widget*, void*)
149 {
150 a_UIcmd_view_page_source(popup_bw, popup_url);
156 static void Menu_view_page_source_cb(Fl_Widget*, void *user_data)
157 {
158 DilloUrl *url = (DilloUrl *)user_data;
159 a_UIcmd_view_page_source(popup_bw, url);
151160 }
152161
153162 /*
287296 * avoid a segfault when a new page replaces the page that issued
288297 * the popup menu.
289298 */
290 static void Menu_popup_cb(void *data)
291 {
292 const Fl_Menu_Item *m = ((Fl_Menu_Item *)data)->popup(popup_x, popup_y);
299 static void Menu_simple_popup_cb(void *data)
300 {
301 const Fl_Menu_Item *m;
302
303 ((UI*)popup_bw->ui)->window()->cursor(FL_CURSOR_DEFAULT);
304
305 m = ((Fl_Menu_Item *)data)->popup(popup_x, popup_y);
293306
294307 if (m && m->callback())
295308 m->do_callback((Fl_Widget *)data);
309 a_Timeout_remove();
310 }
311
312 static void Menu_popup_cb(void *data)
313 {
314 const Fl_Menu_Item *picked;
315 Menu_popup_data_t *d = (Menu_popup_data_t *)data;
316
317 ((UI*)popup_bw->ui)->window()->cursor(FL_CURSOR_DEFAULT);
318
319 picked = d->menu->popup(popup_x, popup_y, d->title, d->picked);
320 if (picked) {
321 d->picked = picked;
322 if (picked->callback())
323 picked->do_callback((Fl_Widget *)(d->menu));
324 }
296325 a_Timeout_remove();
297326 }
298327
317346 {"Save page as...", 0, Menu_save_page_cb,0,0,0,0,0,0},
318347 {0,0,0,0,0,0,0,0,0}
319348 };
349 static Menu_popup_data_t page_data = {"Page menu", NULL, pm};
320350
321351 popup_x = Fl::event_x();
322352 popup_y = Fl::event_y();
329359 if (dStrAsciiCasecmp(URL_SCHEME(url), "dpi") == 0 &&
330360 strncmp(URL_PATH(url), "/vsource/", 9) == 0)
331361 pm[0].deactivate();
332 else
362 else {
333363 pm[0].activate();
364 pm[0].user_data(popup_url);
365 }
334366
335367 if (stylesheets) {
336368 while (stylesheets[j].text) {
347379 memset(stylesheets, '\0', sizeof(Fl_Menu_Item[cssUrls->size() + 1]));
348380
349381 for (j = 0; j < cssUrls->size(); j++) {
350
351 /* may want ability to Load individual unloaded stylesheets as well */
352 const char *action = "View ";
353382 DilloUrl *url = cssUrls->get(j);
354383 const char *url_str = URL_STR(url);
355384 const uint_t head_length = 30, tail_length = 40,
356 url_len = strlen(url_str);;
385 url_len = strlen(url_str);
357386 char *label;
358387
359388 if (url_len > head_length + tail_length + 3) {
360389 /* trim long URLs when making the label */
361390 char *url_head = dStrndup(url_str, head_length);
362391 const char *url_tail = url_str + (url_len - tail_length);
363 label = dStrconcat(action, url_head, "...", url_tail, NULL);
392 label = dStrconcat(url_head, "...", url_tail, NULL);
364393 dFree(url_head);
365394 } else {
366 label = dStrconcat(action, url_str, NULL);
395 label = dStrdup(url_str);
367396 }
368397
369398 stylesheets[j].label(FL_NORMAL_LABEL, label);
375404 } else {
376405 pm[2].deactivate();
377406 }
378
379 a_Timeout_add(0.0, Menu_popup_cb, (void*)pm);
407 pm[3].user_data(popup_url);
408
409 a_Timeout_add(0.0, Menu_popup_cb, (void*)&page_data);
410 }
411
412 static Fl_Menu_Item link_menu[] = {
413 {"Open link in new tab", 0, Menu_open_url_nt_cb,0,0,0,0,0,0},
414 {"Open link in new window", 0, Menu_open_url_nw_cb,0,FL_MENU_DIVIDER,0,0,
415 0,0},
416 {"Bookmark this link", 0, Menu_add_bookmark_cb,0,0,0,0,0,0},
417 {"Copy link location", 0, Menu_copy_urlstr_cb,0,FL_MENU_DIVIDER,0,0,0,0},
418 {"Save link as...", 0, Menu_save_link_cb,0,0,0,0,0,0},
419 {0,0,0,0,0,0,0,0,0}
420 };
421
422 static void Menu_set_link_menu_user_data(void *user_data)
423 {
424 int i;
425
426 for (i = 0; link_menu[i].label(); i++)
427 link_menu[i].user_data(user_data);
380428 }
381429
382430 /*
384432 */
385433 void a_Menu_link_popup(BrowserWindow *bw, const DilloUrl *url)
386434 {
387 static Fl_Menu_Item pm[] = {
388 {"Open link in new tab", 0, Menu_open_url_nt_cb,0,0,0,0,0,0},
389 {"Open link in new window", 0, Menu_open_url_nw_cb,0,FL_MENU_DIVIDER,0,0,
390 0,0},
391 {"Bookmark this link", 0, Menu_add_bookmark_cb,0,0,0,0,0,0},
392 {"Copy link location", 0, Menu_copy_urlstr_cb,0,FL_MENU_DIVIDER,0,0,0,0},
393 {"Save link as...", 0, Menu_save_link_cb,0,0,0,0,0,0},
394 {0,0,0,0,0,0,0,0,0}
395 };
435 static Menu_popup_data_t link_data = {"Link menu", NULL, link_menu};
396436
397437 popup_x = Fl::event_x();
398438 popup_y = Fl::event_y();
400440 a_Url_free(popup_url);
401441 popup_url = a_Url_dup(url);
402442
403 a_Timeout_add(0.0, Menu_popup_cb, (void*)pm);
443 Menu_set_link_menu_user_data(popup_url);
444
445 a_Timeout_add(0.0, Menu_popup_cb, (void*)&link_data);
404446 }
405447
406448 /*
421463 {"Bookmark this image", 0, Menu_add_bookmark_cb,0,0,0,0,0,0},
422464 {"Copy image location", 0,Menu_copy_urlstr_cb,0,FL_MENU_DIVIDER,0,0,0,0},
423465 {"Save image as...", 0, Menu_save_link_cb, 0, FL_MENU_DIVIDER,0,0,0,0},
424 {"Link menu", 0, Menu_link_cb,0,0,0,0,0,0},
466 {"Link menu", 0, Menu_nop_cb, link_menu, FL_SUBMENU_POINTER,0,0,0,0},
425467 {0,0,0,0,0,0,0,0,0}
426468 };
469 static Menu_popup_data_t image_data = {"Image menu", NULL, pm};
427470
428471 popup_x = Fl::event_x();
429472 popup_y = Fl::event_y();
436479 popup_link_url = a_Url_dup(link_url);
437480
438481
482 pm[0].user_data(popup_url);
483 pm[1].user_data(popup_url);
484 pm[2].user_data(popup_url);
485
439486 if (loaded_img) {
440487 pm[3].deactivate();
441488 } else {
443490 pm[3].user_data(popup_page_url);
444491 }
445492
493 pm[4].user_data(popup_url);
494 pm[5].user_data(popup_url);
495 pm[6].user_data(popup_url);
496
446497 if (link_url) {
447498 pm[7].activate();
448 pm[7].user_data(popup_link_url);
499 Menu_set_link_menu_user_data(popup_link_url);
449500 } else {
450501 pm[7].deactivate();
451502 }
452503
453 a_Timeout_add(0.0, Menu_popup_cb, (void*)pm);
504 a_Timeout_add(0.0, Menu_popup_cb, (void*)&image_data);
454505 }
455506
456507 /*
466517 {0, 0, Menu_form_hiddens_cb, &hiddens_visible, 0,0,0,0,0},
467518 {0,0,0,0,0,0,0,0,0}
468519 };
520 static Menu_popup_data_t form_data = {"Form menu", NULL, pm};
469521
470522 popup_x = Fl::event_x();
471523 popup_y = Fl::event_y();
477529 hiddens_visible = hidvis;
478530 pm[2].label(hiddens_visible ? "Hide hiddens": "Show hiddens");
479531
480 a_Timeout_add(0.0, Menu_popup_cb, (void*)pm);
532 a_Timeout_add(0.0, Menu_popup_cb, (void*)&form_data);
481533 }
482534
483535 /*
510562 popup_url = NULL;
511563
512564 //pm->label(wid->visible() ? NULL : "File");
513 a_Timeout_add(0.0, Menu_popup_cb, (void*)pm);
565 a_Timeout_add(0.0, Menu_simple_popup_cb, (void*)pm);
514566 }
515567
516568 /*
532584 a_Url_free(popup_url);
533585 popup_url = a_Url_dup(url);
534586
535 a_Timeout_add(0.0, Menu_popup_cb, (void*)pm);
587 a_Timeout_add(0.0, Menu_simple_popup_cb, (void*)pm);
536588 }
537589
538590 /*
569621 pm[i].label(FL_NORMAL_LABEL, a_History_get_title(history_list[i], 1));
570622 pm[i].callback(Menu_history_cb, INT2VOIDP(i+1));
571623 }
572 a_Timeout_add(0.0, Menu_popup_cb, (void*)pm);
624 a_Timeout_add(0.0, Menu_simple_popup_cb, (void*)pm);
573625 }
574626
575627 /*
9696 }
9797
9898 /* TODO: could use dStr ADT! */
99 typedef struct ContentType_ {
99 typedef struct {
100100 const char *str;
101101 int len;
102102 } ContentType_t;
2626 * For back and forward navigation, each bw keeps an url index,
2727 * and its scroll position.
2828 */
29 typedef struct _nav_stack_item nav_stack_item;
30 struct _nav_stack_item
31 {
29 typedef struct {
3230 int url_idx;
3331 int posx, posy;
34 };
32 } nav_stack_item;
3533
3634
3735
486484 confirmed = 1;
487485 } else if (URL_FLAGS(h_url) & URL_Post) {
488486 /* Attempt to repost data, let's confirm... */
489 choice = a_Dialog_choice5("Repost form data?",
490 "No", "Yes", "Cancel", NULL, NULL);
487 choice = a_Dialog_choice("Dillo: Repost form?",
488 "Repost form data?",
489 "No", "Yes", "Cancel", NULL);
491490 confirmed = (choice == 2); /* "Yes" */
492491 }
493492
589588 }
590589
591590 /*
591 * Wrapper for a_Capi_get_content_type().
592 */
593 const char *a_Nav_get_content_type(const DilloUrl *url)
594 {
595 return a_Capi_get_content_type(url);
596 }
597
598 /*
592599 * Wrapper for a_Capi_set_vsource_url().
593600 */
594601 void a_Nav_set_vsource_url(const DilloUrl *Url)
3434 const DilloUrl *url, const char *filename);
3535 int a_Nav_get_buf(const DilloUrl *Url, char **PBuf, int *BufSize);
3636 void a_Nav_unref_buf(const DilloUrl *Url);
37 const char *a_Nav_get_content_type(const DilloUrl *url);
3738 void a_Nav_set_vsource_url(const DilloUrl *Url);
3839
3940 #ifdef __cplusplus
8282 char *path = dStrconcat(dGethomedir(), "/.dillo/", rcFile, NULL);
8383
8484 if (!(fp = fopen(path, "r"))) {
85 MSG("paths: Cannot open file '%s'\n", path);
85 MSG("paths: Cannot open file '%s': %s\n", path, dStrerror(errno));
8686
8787 char *path2 = dStrconcat(DILLO_SYSCONF, rcFile, NULL);
8888 if (!(fp = fopen(path2, "r"))) {
89 MSG("paths: Cannot open file '%s'\n",path2);
89 MSG("paths: Cannot open file '%s': %s\n", path2, dStrerror(errno));
9090 MSG("paths: Using internal defaults...\n");
9191 } else {
9292 MSG("paths: Using %s\n", path2);
1313
1414 #define PATHS_RC_PREFS "dillorc"
1515 #define PATHS_RC_KEYS "keysrc"
16 #define PATHS_RC_DOMAIN "domainrc"
1617
1718 class Paths {
1819 public:
1212 #ifndef __PIXMAPS_H__
1313 #define __PIXMAPS_H__
1414
15 /* XPM
16 static const char *const history_xpm[] = {
17 "11 20 6 1",
18 " c None",
19 ". c #000000000000",
20 "X c #9658A289BEFB",
21 "O c #FFFF9A690000",
22 "+ c #FFFFFFFF0000",
23 "@ c #FFFFFFFFFFFF",
24 " ",
25 " . ",
26 " .X. ",
27 " .XXX. ",
28 " .XXXXX. ",
29 " .XXXXXXX. ",
30 " ...XXX... ",
31 " .XXX. ",
32 " .XXX. ",
33 " .XXX. ",
34 " OOOOO ",
35 " .XXX. ",
36 " .XXX. ",
37 " ...XXX... ",
38 " .XXXXXXX. ",
39 " .XXXXX. ",
40 " .XXX. ",
41 " .X. ",
42 " . ",
43 " "};
44 */
4515 /* XPM */
4616 static const char *const left_xpm[] = {
4717 "22 22 46 1",
15561526 " 44 "};
15571527
15581528 /* XPM */
1559 static const char *const full_screen_on_xpm[] = {
1560 "13 15 2 1",
1561 " c None",
1562 ". c #000000",
1563 " ",
1564 ".............",
1565 ". . .",
1566 ". ... .",
1567 ". ..... .",
1568 ". ....... .",
1569 ". . .",
1570 ". . .",
1571 ". . .",
1572 ". ....... .",
1573 ". ..... .",
1574 ". ... .",
1575 ". . .",
1576 ".............",
1577 " "};
1578
1579 /* XPM */
1580 static const char *const full_screen_off_xpm[] = {
1581 "13 15 2 1",
1582 " c None",
1583 ". c #000000",
1584 " ",
1585 ".............",
1586 ". . . . . . .",
1587 ".. . . . . ..",
1588 ".............",
1589 ". .",
1590 ". .",
1591 ". .",
1592 ". .",
1593 ". .",
1594 ". .",
1595 ".............",
1596 ". . . . . . .",
1597 ".............",
1598 " "};
1599
1600 /* XPM */
16011529 static const char *const mini_bug_xpm[] = {
16021530 "16 16 7 1",
16031531 " c None",
16491577 " @ "
16501578 };
16511579
1580 #if 0
1581
16521582 /* XPM */
16531583 static const char *const left_i_xpm[] = {
16541584 "22 22 3 1",
18031733 " @@@@@@@@",
18041734 " @@ @ @ ",
18051735 " @ "};
1736 #endif
18061737
18071738 #endif /* __PIXMAPS_H__ */
135135 void DilloPlain::addLine(char *Buf, uint_t BufSize)
136136 {
137137 int len;
138 char buf[128];
138 char buf[129];
139139 char *end = Buf + BufSize;
140140
141141 if (BufSize > 0) {
142142 // Limit word length to avoid X11 coordinate
143143 // overflow with extremely long lines.
144 while ((len = a_Misc_expand_tabs(&Buf, end, buf, sizeof(buf))))
144 while ((len = a_Misc_expand_tabs(&Buf, end, buf, sizeof(buf) - 1))) {
145 assert ((uint_t)len < sizeof(buf));
146 buf[len] = '\0';
145147 DW2TB(dw)->addText(buf, len, widgetStyle);
148 }
146149 } else {
147150 // Add dummy word for empty lines - otherwise the parbreak is ignored.
148151 DW2TB(dw)->addText("", 0, widgetStyle);
5757 * ones for XBM and PNM are.
5858 */
5959
60 typedef
61 struct _DilloPng {
60 typedef struct {
6261 DilloImage *Image; /* Image meta data */
6362 DilloUrl *url; /* Primary Key for the dicache */
6463 int version; /* Secondary Key for the dicache */
6564
66 double display_exponent; /* gamma correction */
6765 png_uint_32 width; /* png image width */
6866 png_uint_32 height; /* png image height */
6967 png_structp png_ptr; /* libpng private data */
7472 int error; /* error flag */
7573 png_uint_32 previous_row;
7674 int rowbytes; /* No. bytes in image row */
77 short passes;
7875 short channels; /* No. image channels */
7976
8077 /*
9794 } DilloPng;
9895
9996 #define DATASIZE (png->ipbufsize - png->ipbufstart)
100 #define BLACK 0
101 #define WHITE 255
10297
10398
10499 static
178173
179174 /* Interlaced */
180175 if (interlace_type != PNG_INTERLACE_NONE) {
181 png->passes = png_set_interlace_handling(png_ptr);
176 png_set_interlace_handling(png_ptr);
182177 }
183178
184179 /* get libpng to update its state */
4040 prefs.buffered_drawing = 1;
4141 prefs.contrast_visited_color = TRUE;
4242 prefs.enterpress_forces_submit = FALSE;
43 prefs.filter_auto_requests = PREFS_FILTER_SAME_DOMAIN;
4443 prefs.focus_new_tab = TRUE;
4544 prefs.font_cursive = dStrdup(PREFS_FONT_CURSIVE);
4645 prefs.font_factor = 1.0;
9695 prefs.show_stop = TRUE;
9796 prefs.show_tools = TRUE;
9897 prefs.show_tooltip = TRUE;
99 prefs.show_url = TRUE;
10098 prefs.small_icons = FALSE;
10199 prefs.start_page = a_Url_new(PREFS_START_PAGE, NULL);
102100 prefs.theme = dStrdup(PREFS_THEME);
101 prefs.ui_button_highlight_color = -1;
102 prefs.ui_fg_color = -1;
103 prefs.ui_main_bg_color = -1;
104 prefs.ui_selection_color = -1;
105 prefs.ui_tab_active_bg_color = -1;
106 prefs.ui_tab_bg_color = -1;
107 prefs.ui_tab_active_fg_color = -1;
108 prefs.ui_tab_fg_color = -1;
109 prefs.ui_text_bg_color = -1;
103110 prefs.w3c_plus_heuristics = TRUE;
111
112 prefs.penalty_hyphen = 100;
113 prefs.penalty_hyphen_2 = 800;
114 prefs.penalty_em_dash_left = 800;
115 prefs.penalty_em_dash_right = 100;
116 prefs.penalty_em_dash_right_2 = 800;
104117 }
105118
106119 /*
2222 #define PREFS_GEOMETRY_DEFAULT_XPOS -9999
2323 #define PREFS_GEOMETRY_DEFAULT_YPOS -9999
2424
25 /* FLTK has free color indices from 16 to 31 */
26 #define PREFS_UI_BUTTON_HIGHLIGHT_COLOR 16
27 #define PREFS_UI_TAB_ACTIVE_BG_COLOR 17
28 #define PREFS_UI_TAB_ACTIVE_FG_COLOR 18
29 #define PREFS_UI_TAB_BG_COLOR 19
30 #define PREFS_UI_TAB_FG_COLOR 20
31
2532 /* Panel sizes */
2633 enum { P_tiny = 0, P_small, P_medium };
2734
28 enum {PREFS_FILTER_ALLOW_ALL,
29 PREFS_FILTER_SAME_DOMAIN};
30
31 typedef struct _DilloPrefs DilloPrefs;
32
33 struct _DilloPrefs {
35 typedef struct {
3436 int width;
3537 int height;
3638 int xpos;
4648 DilloUrl *home;
4749 bool_t allow_white_bg;
4850 int32_t bg_color;
51 int32_t ui_button_highlight_color;
52 int32_t ui_fg_color;
53 int32_t ui_main_bg_color;
54 int32_t ui_selection_color;
55 int32_t ui_tab_active_bg_color;
56 int32_t ui_tab_active_fg_color;
57 int32_t ui_tab_bg_color;
58 int32_t ui_tab_fg_color;
59 int32_t ui_text_bg_color;
4960 bool_t contrast_visited_color;
5061 bool_t show_tooltip;
5162 char *theme;
6778 bool_t show_tools;
6879 bool_t show_filemenu;
6980 bool_t show_clear_url;
70 bool_t show_url;
7181 bool_t show_search;
7282 bool_t show_help;
7383 bool_t show_progress_box;
7686 bool_t load_images;
7787 bool_t load_stylesheets;
7888 bool_t parse_embedded_css;
79 int filter_auto_requests;
8089 int32_t buffered_drawing;
8190 char *font_serif;
8291 char *font_sans_serif;
92101 bool_t show_msg;
93102 bool_t show_extra_warnings;
94103 bool_t middle_click_drags_page;
95 };
104 int penalty_hyphen, penalty_hyphen_2;
105 int penalty_em_dash_left, penalty_em_dash_right, penalty_em_dash_right_2;
106 } DilloPrefs;
96107
97108 /* Global Data */
98109 extern DilloPrefs prefs;
1111 #include <sys/types.h>
1212 #include <stdlib.h>
1313 #include <locale.h> /* for setlocale */
14 #include <math.h> /* for isinf */
15 #include <limits.h>
1416
1517 #include "prefs.h"
1618 #include "misc.h"
2729 PREFS_URL,
2830 PREFS_INT32,
2931 PREFS_DOUBLE,
32 PREFS_FRACTION_100,
3033 PREFS_GEOMETRY,
31 PREFS_FILTER,
3234 PREFS_PANEL_SIZE
3335 } PrefType_t;
3436
35 typedef struct SymNode_ {
37 typedef struct {
3638 const char *name;
3739 void *pref;
3840 PrefType_t type;
5557 { "contrast_visited_color", &prefs.contrast_visited_color, PREFS_BOOL },
5658 { "enterpress_forces_submit", &prefs.enterpress_forces_submit,
5759 PREFS_BOOL },
58 { "filter_auto_requests", &prefs.filter_auto_requests, PREFS_FILTER },
5960 { "focus_new_tab", &prefs.focus_new_tab, PREFS_BOOL },
6061 { "font_cursive", &prefs.font_cursive, PREFS_STRING },
6162 { "font_factor", &prefs.font_factor, PREFS_DOUBLE },
104105 { "show_stop", &prefs.show_stop, PREFS_BOOL },
105106 { "show_tools", &prefs.show_tools, PREFS_BOOL },
106107 { "show_tooltip", &prefs.show_tooltip, PREFS_BOOL },
107 { "show_url", &prefs.show_url, PREFS_BOOL },
108108 { "small_icons", &prefs.small_icons, PREFS_BOOL },
109109 { "start_page", &prefs.start_page, PREFS_URL },
110110 { "theme", &prefs.theme, PREFS_STRING },
111 { "w3c_plus_heuristics", &prefs.w3c_plus_heuristics, PREFS_BOOL }
111 { "ui_button_highlight_color", &prefs.ui_button_highlight_color,
112 PREFS_COLOR },
113 { "ui_fg_color", &prefs.ui_fg_color, PREFS_COLOR },
114 { "ui_main_bg_color", &prefs.ui_main_bg_color, PREFS_COLOR },
115 { "ui_selection_color", &prefs.ui_selection_color, PREFS_COLOR },
116 { "ui_tab_active_bg_color", &prefs.ui_tab_active_bg_color, PREFS_COLOR },
117 { "ui_tab_bg_color", &prefs.ui_tab_bg_color, PREFS_COLOR },
118 { "ui_tab_active_fg_color", &prefs.ui_tab_active_fg_color, PREFS_COLOR },
119 { "ui_tab_fg_color", &prefs.ui_tab_fg_color, PREFS_COLOR },
120 { "ui_text_bg_color", &prefs.ui_text_bg_color, PREFS_COLOR },
121 { "w3c_plus_heuristics", &prefs.w3c_plus_heuristics, PREFS_BOOL },
122 { "penalty_hyphen", &prefs.penalty_hyphen, PREFS_FRACTION_100 },
123 { "penalty_hyphen_2", &prefs.penalty_hyphen_2, PREFS_FRACTION_100 },
124 { "penalty_em_dash_left", &prefs.penalty_em_dash_left,
125 PREFS_FRACTION_100 },
126 { "penalty_em_dash_right", &prefs.penalty_em_dash_right,
127 PREFS_FRACTION_100 },
128 { "penalty_em_dash_right_2", &prefs.penalty_em_dash_right_2,
129 PREFS_FRACTION_100 }
112130 };
113131
114132 node = NULL;
115 for (i = 0; i < sizeof(symbols) / sizeof(SymNode_t); i++) {
133 for (i = 0; i < sizeof(symbols) / sizeof(symbols[0]); i++) {
116134 if (!strcmp(symbols[i].name, name)) {
117135 node = & (symbols[i]);
118136 break;
131149 break;
132150 case PREFS_COLOR:
133151 *(int32_t *)node->pref = a_Color_parse(value, *(int32_t*)node->pref,&st);
134 if (st)
152 if (st == 1)
135153 MSG("prefs: Color '%s' not recognized.\n", value);
136154 break;
137155 case PREFS_STRING:
161179 case PREFS_DOUBLE:
162180 *(double *)node->pref = strtod(value, NULL);
163181 break;
182 case PREFS_FRACTION_100:
183 {
184 double d = strtod (value, NULL);
185 if (isinf(d)) {
186 if (d > 0)
187 *(int*)node->pref = INT_MAX;
188 else
189 *(int*)node->pref = INT_MIN;
190 } else
191 *(int*)node->pref = 100 * d;
192 }
193 break;
164194 case PREFS_GEOMETRY:
165195 a_Misc_parse_geometry(value, &prefs.xpos, &prefs.ypos,
166196 &prefs.width, &prefs.height);
167 break;
168 case PREFS_FILTER:
169 if (!dStrAsciiCasecmp(value, "same_domain"))
170 prefs.filter_auto_requests = PREFS_FILTER_SAME_DOMAIN;
171 else {
172 if (dStrAsciiCasecmp(value, "allow_all"))
173 MSG_WARN("prefs: unrecognized value for filter_auto_requests\n");
174 prefs.filter_auto_requests = PREFS_FILTER_ALLOW_ALL;
175 }
176197 break;
177198 case PREFS_PANEL_SIZE:
178199 if (!dStrAsciiCasecmp(value, "tiny"))
1111 #include "../dlib/dlib.h"
1212 #include "msg.h"
1313 #include "prefs.h"
14 #include "misc.h"
1415 #include "html_common.hh"
1516 #include "styleengine.hh"
1617
2425 doctree = new Doctree ();
2526 stack = new lout::misc::SimpleVector <Node> (1);
2627 cssContext = new CssContext ();
28 buildUserAgentStyle ();
29 buildUserStyle ();
2730 this->layout = layout;
2831 importDepth = 0;
2932
30 stack->increase ();
31 Node *n = stack->getRef (stack->size () - 1);
33 stackPush ();
34 Node *n = stack->getLastRef ();
3235
3336 /* Create a dummy font, attribute, and tag for the bottom of the stack. */
3437 font_attrs.name = prefs.font_sans_serif;
4548 style_attrs.initValues ();
4649 style_attrs.font = Font::create (layout, &font_attrs);
4750 style_attrs.color = Color::create (layout, 0);
48 style_attrs.backgroundColor = Color::create (layout, 0xffffff);
49
50 n->style = Style::create (layout, &style_attrs);
51 n->wordStyle = NULL;
52 n->backgroundStyle = NULL;
53 n->styleAttrProperties = NULL;
54 n->styleAttrPropertiesImportant = NULL;
55 n->nonCssProperties = NULL;
56 n->inheritBackgroundColor = false;
51 style_attrs.backgroundColor = Color::create (layout, prefs.bg_color);
52
53 n->style = Style::create (&style_attrs);
5754 }
5855
5956 StyleEngine::~StyleEngine () {
6057 while (doctree->top ())
6158 endElement (doctree->top ()->element);
62 assert (stack->size () == 1); // dummy node on the bottom of the stack
59
60 stackPop (); // dummy node on the bottom of the stack
61 assert (stack->size () == 0);
62
63 delete stack;
64 delete doctree;
65 delete cssContext;
66 }
67
68 void StyleEngine::stackPush () {
69 static const Node emptyNode = {
70 NULL, NULL, NULL, NULL, NULL, NULL, false, NULL
71 };
72
73 stack->setSize (stack->size () + 1, emptyNode);
74 }
75
76 void StyleEngine::stackPop () {
6377 Node *n = stack->getRef (stack->size () - 1);
78
79 delete n->styleAttrProperties;
80 delete n->styleAttrPropertiesImportant;
81 delete n->nonCssProperties;
6482 if (n->style)
6583 n->style->unref ();
6684 if (n->wordStyle)
6785 n->wordStyle->unref ();
6886 if (n->backgroundStyle)
6987 n->backgroundStyle->unref ();
70 delete stack;
71 delete doctree;
72 delete cssContext;
88 stack->setSize (stack->size () - 1);
7389 }
7490
7591 /**
7692 * \brief tell the styleEngine that a new html element has started.
7793 */
7894 void StyleEngine::startElement (int element) {
79 if (stack->getRef (stack->size () - 1)->style == NULL)
80 style0 (stack->size () - 1);
81
82 stack->increase ();
83 Node *n = stack->getRef (stack->size () - 1);
84 n->styleAttrProperties = NULL;
85 n->styleAttrPropertiesImportant = NULL;
86 n->nonCssProperties = NULL;
87 n->style = NULL;
88 n->wordStyle = NULL;
89 n->backgroundStyle = NULL;
90 n->inheritBackgroundColor = false;
91
95 style (); // ensure that style of current node is computed
96
97 stackPush ();
98 Node *n = stack->getLastRef ();
9299 DoctreeNode *dn = doctree->push ();
100
93101 dn->element = element;
94102 n->doctreeNode = dn;
95103 }
102110 DoctreeNode *dn = doctree->top ();
103111 assert (dn->id == NULL);
104112 dn->id = dStrdup (id);
105 };
113 }
106114
107115 /**
108116 * \brief split a string at sep chars and return a SimpleVector of strings
133141 DoctreeNode *dn = doctree->top ();
134142 assert (dn->klass == NULL);
135143 dn->klass = splitStr (klass, ' ');
136 };
144 }
137145
138146 void StyleEngine::setStyle (const char *styleAttr) {
139147 Node *n = stack->getRef (stack->size () - 1);
147155 n->styleAttrProperties,
148156 n->styleAttrPropertiesImportant);
149157 }
150 };
158 }
151159
152160 /**
153161 * \brief Instruct StyleEngine to use the nonCssHints from parent element
156164 */
157165 void StyleEngine::inheritNonCssHints () {
158166 Node *pn = stack->getRef (stack->size () - 2);
159 Node *n = stack->getRef (stack->size () - 1);
160
161 if (pn->nonCssProperties)
162 n->nonCssProperties = new CssPropertyList (*pn->nonCssProperties, true);
167
168 if (pn->nonCssProperties) {
169 Node *n = stack->getRef (stack->size () - 1);
170 CssPropertyList *origNonCssProperties = n->nonCssProperties;
171
172 n->nonCssProperties = new CssPropertyList(*pn->nonCssProperties, true);
173
174 if (origNonCssProperties) // original nonCssProperties have precedence
175 origNonCssProperties->apply (n->nonCssProperties);
176
177 delete origNonCssProperties;
178 }
163179 }
164180
165181 void StyleEngine::clearNonCssHints () {
166182 Node *n = stack->getRef (stack->size () - 1);
167183
168 if (n->nonCssProperties) {
169 delete n->nonCssProperties;
170 n->nonCssProperties = NULL;
171 }
184 delete n->nonCssProperties;
185 n->nonCssProperties = NULL;
172186 }
173187
174188 /**
214228 void StyleEngine::endElement (int element) {
215229 assert (element == doctree->top ()->element);
216230
217 Node *n = stack->getRef (stack->size () - 1);
218
219 if (n->styleAttrProperties)
220 delete n->styleAttrProperties;
221 if (n->styleAttrPropertiesImportant)
222 delete n->styleAttrPropertiesImportant;
223 if (n->nonCssProperties)
224 delete n->nonCssProperties;
225 if (n->style)
226 n->style->unref ();
227 if (n->wordStyle)
228 n->wordStyle->unref ();
229 if (n->backgroundStyle)
230 n->backgroundStyle->unref ();
231
231 stackPop ();
232232 doctree->pop ();
233 stack->setSize (stack->size () - 1);
234233 }
235234
236235 void StyleEngine::preprocessAttrs (dw::core::style::StyleAttrs *attrs) {
597596 case PROPERTY_X_LINK:
598597 attrs->x_link = p->value.intVal;
599598 break;
599 case PROPERTY_X_LANG:
600 attrs->x_lang[0] = D_ASCII_TOLOWER(p->value.strVal[0]);
601 if (attrs->x_lang[0])
602 attrs->x_lang[1] = D_ASCII_TOLOWER(p->value.strVal[1]);
603 else
604 attrs->x_lang[1] = 0;
605 break;
600606 case PROPERTY_X_IMG:
601607 attrs->x_img = p->value.intVal;
602608 break;
708714
709715 assert (attrs.backgroundColor);
710716 stack->getRef (stack->size () - 1)->backgroundStyle =
711 Style::create (layout, &attrs);
717 Style::create (&attrs);
712718 }
713719 return stack->getRef (stack->size () - 1)->backgroundStyle;
714720 }
750756
751757 postprocessAttrs (&attrs);
752758
753 stack->getRef (i)->style = Style::create (layout, &attrs);
759 stack->getRef (i)->style = Style::create (&attrs);
754760
755761 return stack->getRef (i)->style;
756762 }
764770
765771 attrs.valign = style ()->valign;
766772
767 stack->getRef(stack->size() - 1)->wordStyle = Style::create(layout, &attrs);
773 stack->getRef(stack->size() - 1)->wordStyle = Style::create(&attrs);
768774 return stack->getRef (stack->size () - 1)->wordStyle;
769775 }
770776
806812 CssParser::parse (html, url, cssContext, buf, buflen, origin);
807813 importDepth--;
808814 }
815
816 /**
817 * \brief Create the user agent style.
818 *
819 * The user agent style defines how dillo renders HTML in the absence of
820 * author or user styles.
821 */
822 void StyleEngine::buildUserAgentStyle () {
823 const char *cssBuf =
824 "body {margin: 5px}"
825 "big {font-size: 1.17em}"
826 "blockquote, dd {margin-left: 40px; margin-right: 40px}"
827 "center {text-align: center}"
828 "dt {font-weight: bolder}"
829 ":link {color: blue; text-decoration: underline; cursor: pointer}"
830 ":visited {color: #800080; text-decoration: underline; cursor: pointer}"
831 "h1, h2, h3, h4, h5, h6, b, strong {font-weight: bolder}"
832 "address, center, div, h1, h2, h3, h4, h5, h6, ol, p, ul, pre {display: block}"
833 "i, em, cite, address, var {font-style: italic}"
834 ":link img, :visited img {border: 1px solid}"
835 "frameset, ul, ol, dir {margin-left: 40px}"
836 /* WORKAROUND: It should be margin: 1em 0
837 * but as we don't collapse these margins yet, it
838 * look better like this.
839 */
840 "p {margin: 0.5em 0}"
841 "h1 {font-size: 2em; margin-top: .67em; margin-bottom: 0}"
842 "h2 {font-size: 1.5em; margin-top: .75em; margin-bottom: 0}"
843 "h3 {font-size: 1.17em; margin-top: .83em; margin-bottom: 0}"
844 "h4 {margin-top: 1.12em; margin-bottom: 0}"
845 "h5 {font-size: 0.83em; margin-top: 1.5em; margin-bottom: 0}"
846 "h6 {font-size: 0.75em; margin-top: 1.67em; margin-bottom: 0}"
847 "hr {width: 100%; border: 1px inset}"
848 "li {margin-top: 0.1em; display: list-item}"
849 "pre {white-space: pre}"
850 "ol {list-style-type: decimal}"
851 "ul {list-style-type: disc}"
852 "ul ul {list-style-type: circle}"
853 "ul ul ul {list-style-type: square}"
854 "ul ul ul ul {list-style-type: disc}"
855 "u {text-decoration: underline}"
856 "small, sub, sup {font-size: 0.83em}"
857 "sub {vertical-align: sub}"
858 "sup {vertical-align: super}"
859 "s, strike, del {text-decoration: line-through}"
860 "table {border-spacing: 2px}"
861 "td, th {padding: 2px}"
862 "thead, tbody, tfoot {vertical-align: middle}"
863 "th {font-weight: bolder; text-align: center}"
864 "code, tt, pre, samp, kbd {font-family: monospace}"
865 /* WORKAROUND: Reset font properties in tables as some
866 * pages rely on it (e.g. gmail).
867 * http://developer.mozilla.org/En/Fixing_Table_Inheritance_in_Quirks_Mode
868 * has a detailed description of the issue.
869 */
870 "table, caption {font-size: medium; font-weight: normal}";
871
872 CssParser::parse (NULL, NULL, cssContext, cssBuf, strlen (cssBuf),
873 CSS_ORIGIN_USER_AGENT);
874 }
875
876 void StyleEngine::buildUserStyle () {
877 Dstr *style;
878 char *filename = dStrconcat(dGethomedir(), "/.dillo/style.css", NULL);
879
880 if ((style = a_Misc_file2dstr(filename))) {
881 CssParser::parse (NULL,NULL,cssContext,style->str, style->len,CSS_ORIGIN_USER);
882 dStr_free (style, 1);
883 }
884 dFree (filename);
885 }
3535 Doctree *doctree;
3636 int importDepth;
3737
38 void stackPush ();
39 void stackPop ();
40 void buildUserAgentStyle ();
41 void buildUserStyle ();
3842 dw::core::style::Style *style0 (int i);
3943 dw::core::style::Style *wordStyle0 ();
4044 inline void setNonCssHint(CssPropertyName name, CssValueType type,
2929
3030 static void Html_tag_open_table_cell(DilloHtml *html,
3131 const char *tag, int tagsize,
32 dw::core::style::TextAlignType text_align);
32 dw::core::style::TextAlignType text_align);
33 static void Html_tag_content_table_cell(DilloHtml *html,
34 const char *tag, int tagsize);
3335
3436 /*
3537 * <TABLE>
3638 */
3739 void Html_tag_open_table(DilloHtml *html, const char *tag, int tagsize)
3840 {
39 dw::core::Widget *table;
4041 const char *attrbuf;
4142 int32_t border = -1, cellspacing = -1, cellpadding = -1, bgcolor = -1;
4243 CssLength cssLength;
9899 CSS_TYPE_COLOR, bgcolor);
99100 }
100101
101 HT2TB(html)->addParbreak (0, html->styleEngine->wordStyle ());
102 html->styleEngine->style (); // evaluate now, so we can build non-css hints for the cells
102103
103104 /* The style for the cells */
104105 html->styleEngine->clearNonCssHints ();
134135 CSS_TYPE_LENGTH_PERCENTAGE, cssLength);
135136 }
136137
138 }
139 void Html_tag_content_table(DilloHtml *html, const char *tag, int tagsize)
140 {
141 dw::core::Widget *table;
142
143 HT2TB(html)->addParbreak (0, html->styleEngine->wordStyle ());
137144 table = new dw::Table(prefs.limit_text_width);
138145 HT2TB(html)->addWidget (table, html->styleEngine->style ());
146 HT2TB(html)->addParbreak (0, html->styleEngine->wordStyle ());
139147
140148 S_TOP(html)->table_mode = DILLO_HTML_TABLE_MODE_TOP;
141149 S_TOP(html)->table_border_mode = DILLO_HTML_TABLE_BORDER_SEPARATE;
142150 S_TOP(html)->cell_text_align_set = FALSE;
143151 S_TOP(html)->table = table;
152
144153 }
145154
146155 /*
176185
177186 html->styleEngine->inheritBackgroundColor ();
178187
179 ((dw::Table*)S_TOP(html)->table)->addRow (html->styleEngine->style ());
180
181188 if (bgcolor != -1) {
182189 html->styleEngine->setNonCssHint(CSS_PROPERTY_BACKGROUND_COLOR,
183190 CSS_TYPE_COLOR, bgcolor);
187194 default:
188195 break;
189196 }
197 }
198
199 void Html_tag_content_tr(DilloHtml *html, const char *tag, int tagsize)
200 {
201 switch (S_TOP(html)->table_mode) {
202 case DILLO_HTML_TABLE_MODE_NONE:
203 return;
204 case DILLO_HTML_TABLE_MODE_TOP:
205 case DILLO_HTML_TABLE_MODE_TR:
206 case DILLO_HTML_TABLE_MODE_TD:
207 ((dw::Table*)S_TOP(html)->table)->addRow (html->styleEngine->style ());
208 default:
209 break;
210 }
190211
191212 S_TOP(html)->table_mode = DILLO_HTML_TABLE_MODE_TR;
192213 }
200221 dw::core::style::TEXT_ALIGN_LEFT);
201222 }
202223
224 void Html_tag_content_td(DilloHtml *html, const char *tag, int tagsize)
225 {
226 Html_tag_content_table_cell (html, tag, tagsize);
227 }
228
203229 /*
204230 * <TH>
205231 */
207233 {
208234 Html_tag_open_table_cell (html, tag, tagsize,
209235 dw::core::style::TEXT_ALIGN_CENTER);
236 }
237
238 void Html_tag_content_th(DilloHtml *html, const char *tag, int tagsize)
239 {
240 Html_tag_content_table_cell (html, tag, tagsize);
210241 }
211242
212243 /*
265296 collapseCellAttrs.borderWidth.bottom = borderWidth;
266297 collapseCellAttrs.hBorderSpacing = 0;
267298 collapseCellAttrs.vBorderSpacing = 0;
268 collapseStyle = Style::create(HT2LT(html), &collapseCellAttrs);
299 collapseStyle = Style::create(&collapseCellAttrs);
269300 col_tb->setStyle (collapseStyle);
270301
271302 if (Html_table_get_border_model(html) != DILLO_HTML_TABLE_BORDER_COLLAPSE) {
282313 collapseTableAttrs.borderStyle = collapseCellAttrs.borderStyle;
283314 /* CSS2 17.6.2: table does not have padding (in collapsing mode) */
284315 collapseTableAttrs.padding.setVal (0);
285 collapseStyle = Style::create(HT2LT(html), &collapseTableAttrs);
316 collapseStyle = Style::create(&collapseTableAttrs);
286317 ((dw::Table*)S_TOP(html)->table)->setStyle (collapseStyle);
287318 }
288319 }
299330 separateCellAttrs = *(html->styleEngine->style ());
300331 /* CSS2 17.5: Internal table elements do not have margins */
301332 separateCellAttrs.margin.setVal (0);
302 separateStyle = Style::create(HT2LT(html), &separateCellAttrs);
333 separateStyle = Style::create(&separateCellAttrs);
303334 col_tb->setStyle (separateStyle);
304335 }
305336
310341 const char *tag, int tagsize,
311342 dw::core::style::TextAlignType text_align)
312343 {
313 Widget *col_tb;
344 const char *attrbuf;
345 int32_t bgcolor;
346
347 html->styleEngine->inheritNonCssHints ();
348
349 switch (S_TOP(html)->table_mode) {
350 case DILLO_HTML_TABLE_MODE_NONE:
351 return;
352
353 case DILLO_HTML_TABLE_MODE_TOP:
354 /* a_Dw_table_add_cell takes care that dillo does not crash. */
355 /* continues */
356 case DILLO_HTML_TABLE_MODE_TR:
357 case DILLO_HTML_TABLE_MODE_TD:
358 /* text style */
359 if (!S_TOP(html)->cell_text_align_set) {
360 html->styleEngine->setNonCssHint (CSS_PROPERTY_TEXT_ALIGN,
361 CSS_TYPE_ENUM, text_align);
362 }
363 if (a_Html_get_attr(html, tag, tagsize, "nowrap"))
364 html->styleEngine->setNonCssHint(CSS_PROPERTY_WHITE_SPACE,
365 CSS_TYPE_ENUM, WHITE_SPACE_NOWRAP);
366
367 a_Html_tag_set_align_attr (html, tag, tagsize);
368
369 if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "width"))) {
370 html->styleEngine->setNonCssHint (CSS_PROPERTY_WIDTH,
371 CSS_TYPE_LENGTH_PERCENTAGE,
372 a_Html_parse_length (html, attrbuf));
373 }
374
375 a_Html_tag_set_valign_attr (html, tag, tagsize);
376
377 if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "bgcolor"))) {
378 bgcolor = a_Html_color_parse(html, attrbuf, -1);
379 if (bgcolor != -1)
380 html->styleEngine->setNonCssHint (CSS_PROPERTY_BACKGROUND_COLOR,
381 CSS_TYPE_COLOR, bgcolor);
382 }
383
384 default:
385 /* compiler happiness */
386 break;
387 }
388 }
389
390 static void Html_tag_content_table_cell(DilloHtml *html,
391 const char *tag, int tagsize)
392 {
314393 int colspan = 1, rowspan = 1;
315394 const char *attrbuf;
316 int32_t bgcolor;
317
318 html->styleEngine->inheritNonCssHints ();
395 Widget *col_tb;
319396
320397 switch (S_TOP(html)->table_mode) {
321398 case DILLO_HTML_TABLE_MODE_NONE:
322 BUG_MSG("<td> or <th> outside <table>\n");
399 BUG_MSG("<t%c> outside <table>\n",
400 (tagsize >=3 && (D_ASCII_TOLOWER(tag[2]) == 'd')) ? 'd' : 'h');
323401 return;
324402
325403 case DILLO_HTML_TABLE_MODE_TOP:
326 BUG_MSG("<td> or <th> outside <tr>\n");
404 BUG_MSG("<t%c> outside <tr>\n",
405 (tagsize >=3 && (D_ASCII_TOLOWER(tag[2]) == 'd')) ? 'd' : 'h');
327406 /* a_Dw_table_add_cell takes care that dillo does not crash. */
328407 /* continues */
329408 case DILLO_HTML_TABLE_MODE_TR:
337416 /* TODO: check errors? */
338417 if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "rowspan")))
339418 rowspan = MAX(1, strtol (attrbuf, NULL, 10));
340
341 /* text style */
342 if (!S_TOP(html)->cell_text_align_set) {
343 html->styleEngine->setNonCssHint (CSS_PROPERTY_TEXT_ALIGN,
344 CSS_TYPE_ENUM, text_align);
345 }
346 if (a_Html_get_attr(html, tag, tagsize, "nowrap"))
347 html->styleEngine->setNonCssHint(CSS_PROPERTY_WHITE_SPACE,
348 CSS_TYPE_ENUM, WHITE_SPACE_NOWRAP);
349
350 a_Html_tag_set_align_attr (html, tag, tagsize);
351
352 if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "width"))) {
353 html->styleEngine->setNonCssHint (CSS_PROPERTY_WIDTH,
354 CSS_TYPE_LENGTH_PERCENTAGE,
355 a_Html_parse_length (html, attrbuf));
356 }
357
358 a_Html_tag_set_valign_attr (html, tag, tagsize);
359
360 if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "bgcolor"))) {
361 bgcolor = a_Html_color_parse(html, attrbuf, -1);
362 if (bgcolor != -1)
363 html->styleEngine->setNonCssHint (CSS_PROPERTY_BACKGROUND_COLOR,
364 CSS_TYPE_COLOR, bgcolor);
365 }
366
367419 if (html->styleEngine->style ()->textAlign
368420 == TEXT_ALIGN_STRING)
369421 col_tb = new dw::TableCell (
1111 */
1212
1313 void Html_tag_open_table(DilloHtml *html, const char *tag, int tagsize);
14 void Html_tag_content_table(DilloHtml *html, const char *tag, int tagsize);
1415 void Html_tag_open_tr(DilloHtml *html, const char *tag, int tagsize);
16 void Html_tag_content_tr(DilloHtml *html, const char *tag, int tagsize);
1517 void Html_tag_open_td(DilloHtml *html, const char *tag, int tagsize);
18 void Html_tag_content_td(DilloHtml *html, const char *tag, int tagsize);
1619 void Html_tag_open_th(DilloHtml *html, const char *tag, int tagsize);
20 void Html_tag_content_th(DilloHtml *html, const char *tag, int tagsize);
1721
1822 #endif /* __TABLE_HH__ */
0 /*
1 * File: tipwin.cc
2 *
3 * Copyright 2012 Jorge Arellano Cid <jcid@dillo.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * The tipwin idea was derived from the Fl_Slider example [1]
11 * by Greg Ercolano, which is in public domain.
12 *
13 * [1] http://seriss.com/people/erco/fltk/#SliderTooltip
14 */
15
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <FL/fl_draw.H>
21 #include <FL/Fl.H>
22 #include <FL/Fl_Group.H>
23 #include <FL/Fl_Menu_Window.H>
24 #include <FL/Fl_Tooltip.H>
25 #include <FL/Fl_Button.H>
26
27 #include "prefs.h"
28 #include "tipwin.hh"
29
30 /*
31 * Forward declarations
32 */
33 static void show_timeout(void*);
34 static void recent_timeout(void*);
35
36 /*
37 * Custom tooltip window
38 */
39 TipWin::TipWin() : Fl_Menu_Window(1, 1) // will autosize
40 {
41 bgcolor = fl_color_cube(FL_NUM_RED - 1, FL_NUM_GREEN - 1, FL_NUM_BLUE - 2);
42 recent = 0;
43 strcpy(tip, "");
44 cur_widget = NULL;
45 set_override(); // no border
46 end();
47 }
48
49 void TipWin::draw()
50 {
51 draw_box(FL_BORDER_BOX, 0, 0, w(), h(), bgcolor);
52 fl_color(FL_BLACK);
53 fl_font(labelfont(), labelsize());
54 fl_draw(tip, 3, 3, w() - 6, h() - 6,
55 //Fl_Align(FL_ALIGN_LEFT | FL_ALIGN_WRAP));
56 Fl_Align(FL_ALIGN_LEFT));
57 }
58
59 void TipWin::value(const char *s) {
60 // Recalc size of window
61 snprintf(tip, sizeof(tip) - 1, "%s", s);
62 fl_font(labelfont(), labelsize());
63 int W = w(), H = h();
64 W = 0;
65 fl_measure(tip, W, H, 0);
66 W += 8; H += 8;
67 size(W, H);
68 redraw();
69 }
70
71 void TipWin::do_show(void *wid) {
72 cur_widget = wid; // Keep track of requesting widget
73 if (prefs.show_tooltip) {
74 Fl::add_timeout(recent ? 0.2f : 0.8f, show_timeout);
75 }
76 }
77
78 void TipWin::do_hide() {
79 Fl::remove_timeout(show_timeout);
80 if (shown()) {
81 hide();
82 recent = 1;
83 Fl::add_timeout(0.8f, recent_timeout);
84 }
85 }
86
87 void TipWin::recent_tooltip(int val) {
88 recent = val;
89 }
90
91 //--------------------------------------------------------------------------
92
93 TipWin *my_tipwin(void)
94 {
95 static TipWin *tw = NULL;
96
97 if (!tw) {
98 Fl_Group *save = Fl_Group::current(); // save current widget..
99 tw = new TipWin(); // ..because this trashes it
100 tw->hide(); // start hidden
101 Fl_Group::current(save); // ..then back to previous.
102 }
103 return tw;
104 }
105
106 static void show_timeout(void*) {
107 // if offscreen, move tip ABOVE mouse instead
108 int scr_x, scr_y, scr_w, scr_h;
109 Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h);
110 int ty = Fl::event_y_root() + 20;
111 if (ty + my_tipwin()->h() > scr_h)
112 ty = Fl::event_y_root() - 20 - my_tipwin()->h();
113 if (ty < 0) ty = 0;
114
115 my_tipwin()->position(Fl::event_x_root(), ty);
116 my_tipwin()->show();
117 my_tipwin()->recent_tooltip(0);
118 }
119
120 static void recent_timeout(void*) {
121 my_tipwin()->recent_tooltip(0);
122 }
123
124
125 //---------------------------------------------------------------------------
126
127 /*
128 * A Button sharing a custom tooltip window
129 */
130 TipWinButton::TipWinButton(int x, int y, int w, int h, const char *l) :
131 Fl_Button(x, y, w, h, l)
132 {
133 tipwin = my_tipwin();
134 mytooltip = strdup("empty");
135 }
136
137 TipWinButton::~TipWinButton(void)
138 {
139 tipwin->cancel(this); // cancel tooltip if shown
140 free(mytooltip);
141 }
142
143 int TipWinButton::handle(int e)
144 {
145 switch (e) {
146 case FL_ENTER:
147 tipwin->value(mytooltip);
148 tipwin->do_show(this);
149 break;
150 case FL_PUSH: // push mouse
151 case FL_RELEASE: // release mouse
152 case FL_HIDE: // widget goes away
153 case FL_LEAVE: // leave focus
154 tipwin->do_hide();
155 break;
156 }
157 return (Fl_Button::handle(e));
158 }
159
160 void TipWinButton::set_tooltip(const char *s)
161 {
162 free(mytooltip);
163 mytooltip = strdup(s);
164 }
165
166
167 //---------------------------------------------------------------------------
168
169 /*
170 * A Light Button sharing a custom tooltip window
171 */
172 CustButton::CustButton(int x, int y, int w, int h, const char *l) :
173 TipWinButton(x,y,w,h,l)
174 {
175 norm_color = color();
176 light_color = PREFS_UI_BUTTON_HIGHLIGHT_COLOR;
177 }
178
179 int CustButton::handle(int e)
180 {
181 if (active()) {
182 if (e == FL_ENTER) {
183 color(light_color);
184 redraw();
185 } else if (e == FL_LEAVE || e == FL_RELEASE || e == FL_HIDE) {
186 color(norm_color);
187 redraw();
188 }
189 } else if (e == FL_DEACTIVATE && color() != norm_color) {
190 color(norm_color);
191 redraw();
192 }
193 return TipWinButton::handle(e);
194 }
195
196 void CustButton::hl_color(Fl_Color col)
197 {
198 light_color = col;
199 }
200
201
202 //---------------------------------------------------------------------------
203
204 /*
205 * An Input with custom tooltip window
206 */
207 TipWinInput::TipWinInput (int x, int y, int w, int h, const char *l) :
208 Fl_Input(x,y,w,h,l)
209 {
210 tipwin = my_tipwin();
211 mytooltip = strdup("empty");
212 }
213
214 TipWinInput::~TipWinInput(void)
215 {
216 tipwin->cancel(this); // cancel tooltip if shown
217 free(mytooltip);
218 }
219
220 int TipWinInput::handle(int e)
221 {
222 switch (e) {
223 case FL_ENTER:
224 tipwin->value(mytooltip);
225 tipwin->do_show(this);
226 break;
227 case FL_PUSH: // push mouse
228 case FL_RELEASE: // release mouse
229 case FL_HIDE: // widget goes away
230 case FL_LEAVE: // leave focus
231 case FL_KEYBOARD: // key press
232 tipwin->do_hide();
233 break;
234 }
235 return (Fl_Input::handle(e));
236 }
237
238 void TipWinInput::set_tooltip(const char *s)
239 {
240 free(mytooltip);
241 mytooltip = strdup(s);
242 }
243
0 #ifndef __TIPWIN_HH__
1 #define __TIPWIN_HH__
2
3 #include <FL/Fl_Menu_Window.H>
4 #include <FL/Fl_Button.H>
5 #include <FL/Fl_Input.H>
6
7
8 /*
9 * Custom tooltip window
10 */
11 class TipWin : public Fl_Menu_Window {
12 char tip[256];
13 int bgcolor, recent;
14 void *cur_widget;
15 public:
16 TipWin();
17 void draw();
18 void value(const char *s);
19 void do_show(void *wid);
20 void do_hide();
21 void recent_tooltip(int val);
22
23 void cancel(void *wid) {
24 if (wid == cur_widget) { cur_widget = NULL; do_hide(); }
25 }
26 };
27
28 extern TipWin *my_tipwin(void);
29
30
31 /*
32 * A Button sharing a custom tooltip window
33 */
34 class TipWinButton : public Fl_Button {
35 char *mytooltip;
36 TipWin *tipwin;
37 public:
38 TipWinButton(int x, int y, int w, int h, const char *l = 0);
39 ~TipWinButton();
40 virtual int handle(int e);
41
42 void set_tooltip(const char *s);
43 };
44
45 /*
46 * A button that highlights on mouse over
47 */
48 class CustButton : public TipWinButton {
49 Fl_Color norm_color, light_color;
50 public:
51 CustButton(int x, int y, int w, int h, const char *l=0);
52 virtual int handle(int e);
53 void hl_color(Fl_Color col);
54 };
55
56
57 /*
58 * An Input with custom tooltip window
59 */
60 class TipWinInput : public Fl_Input {
61 char *mytooltip;
62 TipWin *tipwin;
63 public:
64 TipWinInput (int x, int y, int w, int h, const char* l=0);
65 ~TipWinInput(void);
66 virtual int handle(int e);
67
68 void set_tooltip(const char *s);
69 };
70
71
72 #endif // __TIPWIN_HH__
73
1818 #include "msg.h"
1919 #include "timeout.hh"
2020 #include "utf8.hh"
21 #include "tipwin.hh"
2122
2223 #include <FL/Fl.H>
2324 #include <FL/Fl_Pixmap.H>
2728 // Include image data
2829 #include "pixmaps.h"
2930 #include "uicmd.hh"
31 #include "history.h"
32 #include "nav.h"
3033
3134 struct iconset {
3235 Fl_Image *ImgMeterOK, *ImgMeterBug,
4750 new Fl_Pixmap(search_xpm),
4851 new Fl_Pixmap(help_xpm),
4952 new Fl_Pixmap(left_xpm),
50 new Fl_Pixmap(left_i_xpm),
53 NULL,
5154 new Fl_Pixmap(right_xpm),
52 new Fl_Pixmap(right_i_xpm),
55 NULL,
5356 new Fl_Pixmap(stop_xpm),
54 new Fl_Pixmap(stop_i_xpm),
57 NULL,
5558 };
5659
5760 static struct iconset small_icons = {
6669 standard_icons.ImgSearch,
6770 standard_icons.ImgHelp,
6871 new Fl_Pixmap(left_s_xpm),
69 new Fl_Pixmap(left_si_xpm),
72 NULL,
7073 new Fl_Pixmap(right_s_xpm),
71 new Fl_Pixmap(right_si_xpm),
74 NULL,
7275 new Fl_Pixmap(stop_s_xpm),
73 new Fl_Pixmap(stop_si_xpm),
76 NULL,
7477 };
7578
7679
8588 /*
8689 * (Used to avoid certain shortcuts in the location bar)
8790 */
88 class CustInput : public Fl_Input {
91 class CustInput : public TipWinInput {
8992 public:
9093 CustInput (int x, int y, int w, int h, const char* l=0) :
91 Fl_Input(x,y,w,h,l) {};
92 int handle(int e);
94 TipWinInput(x,y,w,h,l) {};
95 virtual int handle(int e);
9396 };
9497
9598 /*
145148 return 0;
146149 }
147150 }
148 }
149
150 return Fl_Input::handle(e);
151 if (k == FL_Page_Down || k == FL_Page_Up) {
152 // These do nothing of interest when FL_MULTILINE_INPUT isn't set.
153 // Let them through for key commands.
154 return 0;
155 }
156 }
157
158 return TipWinInput::handle(e);
151159 }
152160
153161 //----------------------------------------------------------------------------
155163 /*
156164 * Used to handle "paste" within the toolbar's Clear button.
157165 */
158 class CustPasteButton : public CustLightButton {
166 class CustPasteButton : public CustButton {
159167 public:
160168 CustPasteButton(int x, int y, int w, int h, const char *l=0) :
161 CustLightButton(x,y,w,h,l) {};
169 CustButton(x,y,w,h,l) {};
162170 int handle(int e);
163171 };
164172
172180 return 1;
173181 }
174182 }
175 return CustLightButton::handle(e);
183 return CustButton::handle(e);
176184 }
177185
178186 //----------------------------------------------------------------------------
218226
219227 if (b == FL_LEFT_MOUSE) {
220228 a_UIcmd_search_dialog(a_UIcmd_get_bw_by_widget(wid));
221 } else if (b == FL_MIDDLE_MOUSE) {
222 ((UI*)data)->color_change_cb_i();
223 } else if (b == FL_RIGHT_MOUSE) {
224 // nothing ATM
225229 }
226230 }
227231
376380 /*
377381 * Make a generic navigation button
378382 */
379 Fl_Button *UI::make_button(const char *label, Fl_Image *img, Fl_Image *deimg,
380 int b_n, int start)
383 CustButton *UI::make_button(const char *label, Fl_Image *img, Fl_Image *deimg,
384 int b_n, int start)
381385 {
382386 if (start)
383387 p_xpos = 0;
384388
385 Fl_Button *b = new CustLightButton(p_xpos, 0, bw, bh, (lbl) ? label : NULL);
389 CustButton *b = new CustButton(p_xpos, 0, bw, bh, (lbl) ? label : NULL);
386390 if (img)
387391 b->image(img);
388392 if (deimg)
401405 */
402406 void UI::make_toolbar(int tw, int th)
403407 {
408 if (!icons->ImgLeftIn) {
409 icons->ImgLeftIn = icons->ImgLeft->copy();
410 icons->ImgLeftIn->desaturate();
411 icons->ImgLeftIn->color_average(FL_BACKGROUND_COLOR, .14f);
412 }
413 if (!icons->ImgRightIn) {
414 icons->ImgRightIn = icons->ImgRight->copy();
415 icons->ImgRightIn->desaturate();
416 icons->ImgRightIn->color_average(FL_BACKGROUND_COLOR, .14f);
417 }
418 if (!icons->ImgStopIn) {
419 icons->ImgStopIn = icons->ImgStop->copy();
420 icons->ImgStopIn->desaturate();
421 icons->ImgStopIn->color_average(FL_BACKGROUND_COLOR, .14f);
422 }
404423 Back = make_button("Back", icons->ImgLeft, icons->ImgLeftIn, UI_BACK, 1);
405424 Forw = make_button("Forw", icons->ImgRight, icons->ImgRightIn, UI_FORW);
406425 Home = make_button("Home", icons->ImgHome, NULL, UI_HOME);
410429 Bookmarks = make_button("Book", icons->ImgBook, NULL, UI_BOOK);
411430 Tools = make_button("Tools", icons->ImgTools, NULL, UI_TOOLS);
412431
413 Back->tooltip("Previous page");
414 Forw->tooltip("Next page");
415 Home->tooltip("Go to the Home page");
416 Reload->tooltip("Reload");
417 Save->tooltip("Save this page");
418 Stop->tooltip("Stop loading");
419 Bookmarks->tooltip("View bookmarks");
420 Tools->tooltip("Settings");
432 Back->set_tooltip("Previous page");
433 Forw->set_tooltip("Next page");
434 Home->set_tooltip("Go to the Home page");
435 Reload->set_tooltip("Reload");
436 Save->set_tooltip("Save this page");
437 Stop->set_tooltip("Stop loading");
438 Bookmarks->set_tooltip("View bookmarks");
439 Tools->set_tooltip("Settings");
421440 }
422441
423442 /*
425444 */
426445 void UI::make_location(int ww)
427446 {
428 Fl_Button *b;
429
430 Clear = b = new CustPasteButton(p_xpos,0,16,lh,0);
447 CustButton *b;
448
449 b = Clear = (CustButton*) new CustPasteButton(p_xpos,0,16,lh,0);
431450 b->image(icons->ImgClear);
432451 b->callback(clear_cb, this);
433452 b->clear_visible_focus();
434453 b->box(FL_THIN_UP_BOX);
435 b->tooltip("Clear the URL box.\nMiddle-click to paste a URL.");
454 b->set_tooltip("Clear the URL box.\nMiddle-click to paste a URL.");
436455 p_xpos += b->w();
437456
438 Fl_Input *i = Location = new CustInput(p_xpos,0,ww-p_xpos-32,lh,0);
439 i->color(CuteColor);
457 CustInput *i = new CustInput(p_xpos,0,ww-p_xpos-32,lh,0);
458 Location = i;
440459 i->when(FL_WHEN_ENTER_KEY);
441460 i->callback(location_cb, this);
442 i->tooltip("Location");
461 i->set_tooltip("Location");
443462 p_xpos += i->w();
444463
445 Search = b = new CustLightButton(p_xpos,0,16,lh,0);
464 Search = b = new CustButton(p_xpos,0,16,lh,0);
446465 b->image(icons->ImgSearch);
447466 b->callback(search_cb, this);
448467 b->clear_visible_focus();
449468 b->box(FL_THIN_UP_BOX);
450 b->tooltip("Search the Web");
469 b->set_tooltip("Search the Web");
451470 p_xpos += b->w();
452471
453 Help = b = new CustLightButton(p_xpos,0,16,lh,0);
472 Help = b = new CustButton(p_xpos,0,16,lh,0);
454473 b->image(icons->ImgHelp);
455474 b->callback(help_cb, this);
456475 b->clear_visible_focus();
457476 b->box(FL_THIN_UP_BOX);
458 b->tooltip("Help");
477 b->set_tooltip("Help");
459478 p_xpos += b->w();
460479
461480 }
469488 IProg = new CustProgressBox(p_xpos,p_ypos,pw,bh);
470489 IProg->labelsize(12);
471490 IProg->box(thin_up ? FL_THIN_UP_BOX : FL_EMBOSSED_BOX);
472 IProg->labelcolor(FL_GRAY_RAMP + 2);
473491 IProg->update_label(wide ? "Images\n0 of 0" : "0 of 0");
474492 p_xpos += pw;
475493 // Page
476494 PProg = new CustProgressBox(p_xpos,p_ypos,pw,bh);
477495 PProg->labelsize(12);
478496 PProg->box(thin_up ? FL_THIN_UP_BOX : FL_EMBOSSED_BOX);
479 PProg->labelcolor(FL_GRAY_RAMP + 2);
480 PProg->update_label(wide ? "Page\n0.0KB" : "0.0KB");
497 PProg->update_label(wide ? "Page\n0.0 KB" : "0.0 KB");
481498 }
482499
483500 /*
486503 */
487504 Fl_Widget *UI::make_filemenu_button()
488505 {
489 Fl_Button *btn;
506 CustButton *btn;
490507 int w = 0, h = 0, padding;
491508
492 FileButton = btn = new Fl_Button(p_xpos,0,bw,bh,"W");
509 FileButton = btn = new CustButton(p_xpos,0,bw,bh,"W");
493510 btn->labeltype(FL_FREE_LABELTYPE);
494511 btn->measure_label(w, h);
495512 padding = w;
501518 _MSG("UI::make_filemenu_button w=%d h=%d padding=%d\n", w, h, padding);
502519 btn->box(FL_THIN_UP_BOX);
503520 btn->callback(filemenu_cb, this);
504 btn->tooltip("File menu");
521 btn->set_tooltip("File menu");
505522 btn->clear_visible_focus();
506523 if (!prefs.show_filemenu)
507524 btn->hide();
604621 StatusOutput->labelsize(8);
605622 StatusOutput->box(FL_THIN_DOWN_BOX);
606623 StatusOutput->clear_visible_focus();
607 StatusOutput->color(FL_GRAY_RAMP + 18);
624 StatusOutput->color(FL_BACKGROUND_COLOR);
608625
609626 // Bug Meter
610 BugMeter = new CustLightButton(ww-bm_w,wh-sh,bm_w,sh);
627 BugMeter = new CustButton(ww-bm_w,wh-sh,bm_w,sh);
611628 BugMeter->image(icons->ImgMeterOK);
612629 BugMeter->box(FL_THIN_DOWN_BOX);
613630 BugMeter->align(FL_ALIGN_INSIDE | FL_ALIGN_TEXT_NEXT_TO_IMAGE);
614 BugMeter->tooltip("Show HTML bugs\n(right-click for menu)");
631 BugMeter->set_tooltip("Show HTML bugs\n(right-click for menu)");
615632 BugMeter->callback(bugmeter_cb, this);
616633 BugMeter->clear_visible_focus();
617634
629646 LocBar = NavBar = StatusBar = NULL;
630647
631648 Tabs = NULL;
632 TabTooltip = NULL;
633649 TopGroup = this;
634650 TopGroup->box(FL_NO_BOX);
635651 clear_flag(SHORTCUT_LABEL);
637653 PanelTemporary = false;
638654 if (cur_ui) {
639655 PanelSize = cur_ui->PanelSize;
640 CuteColor = cur_ui->CuteColor;
641656 Small_Icons = cur_ui->Small_Icons;
642657 Panelmode = cur_ui->Panelmode;
643658 } else {
644659 // Set some default values
645660 PanelSize = prefs.panel_size;
646661 Small_Icons = prefs.small_icons;
647 CuteColor = 206;
648662 Panelmode = (prefs.fullwindow_start) ? UI_HIDDEN : UI_NORMAL;
649663 }
650664
656670 Main = new Fl_Group(0,0,0,0,"Welcome..."); // size is set by rearrange()
657671 Main->align(FL_ALIGN_CENTER|FL_ALIGN_INSIDE);
658672 Main->box(FL_FLAT_BOX);
659 Main->color(FL_GRAY_RAMP + 3);
660673 Main->labelfont(FL_HELVETICA_BOLD_ITALIC);
661674 Main->labelsize(36);
662675 Main->labeltype(FL_SHADOW_LABEL);
663 Main->labelcolor(FL_WHITE);
664676 TopGroup->add(Main);
665677 TopGroup->resizable(Main);
666678 MainIdx = TopGroup->find(Main);
675687 TopGroup->end();
676688 TopGroup->rearrange();
677689
678 customize(0);
690 customize();
679691
680692 if (Panelmode == UI_HIDDEN) {
681693 panels_toggle();
688700 UI::~UI()
689701 {
690702 _MSG("UI::~UI()\n");
691 dFree(TabTooltip);
692703 }
693704
694705 /*
700711
701712 int ret = 0;
702713 if (event == FL_KEYBOARD) {
703 /* WORKAROUND: remove the Panel's fltk-tooltip.
704 * Although the expose event is delivered, it has an offset. This
705 * extra call avoids the lingering tooltip. */
706 if (!Fl::event_inside(Main) &&
707 (Fl::event_inside((Fl_Widget*)tabs()) ||
708 Fl::event_inside(NavBar) ||
709 (LocBar && Fl::event_inside(LocBar)) ||
710 (StatusBar && Fl::event_inside(StatusBar))))
711 window()->damage(FL_DAMAGE_EXPOSE,0,0,1,1);
712
713714 return 0; // Receive as shortcut
714715 } else if (event == FL_SHORTCUT) {
715716 KeysCommand_t cmd = Keys::getKeyCmd();
738739 a_UIcmd_search_dialog(a_UIcmd_get_bw_by_widget(this));
739740 ret = 1;
740741 } else if (cmd == KEYS_GOTO) {
741 if (Panelmode == UI_HIDDEN) {
742 panels_toggle();
743 temporaryPanels(true);
744 }
745742 focus_location();
746743 ret = 1;
747744 } else if (cmd == KEYS_HIDE_PANELS) {
766763 ret = 1;
767764 } else if (cmd == KEYS_FILE_MENU) {
768765 a_UIcmd_file_popup(a_UIcmd_get_bw_by_widget(this), FileButton);
766 ret = 1;
767 } else if (cmd == KEYS_VIEW_SOURCE) {
768 BrowserWindow *bw = a_UIcmd_get_bw_by_widget(this);
769 const DilloUrl *url = a_History_get_url(NAV_TOP_UIDX(bw));
770 a_UIcmd_view_page_source(bw, url);
769771 ret = 1;
770772 }
771773 } else if (event == FL_RELEASE) {
818820 */
819821 void UI::focus_location()
820822 {
823 if (Panelmode == UI_HIDDEN) {
824 panels_toggle();
825 temporaryPanels(true);
826 }
821827 Location->take_focus();
822828 // Make text selected when already focused.
823829 Location->position(Location->size(), 0);
852858 } else {
853859 PProg->activate();
854860 if (cmd == 1) {
855 snprintf(str, 32, "%s%.1f KB",
856 (PanelSize == 0) ? "" : "Page\n", nbytes/1024.0);
861 char prefix;
862 float magnitude;
863
864 if (nbytes >= 1024 * 1024) {
865 prefix = 'M';
866 magnitude = nbytes / (1024 * 1024.0);
867 } else {
868 prefix = 'K';
869 magnitude = nbytes / 1024.0;
870 }
871 snprintf(str, 32, "%s%.1f %cB",
872 (PanelSize == 0) ? "" : "Page\n", magnitude, prefix);
857873 } else if (cmd == 2) {
858874 str[0] = '\0';
859875 }
908924 /*
909925 * Customize the UI's panel (show/hide buttons)
910926 */
911 void UI::customize(int flags)
912 {
913 // flags argument not currently used
914
927 void UI::customize()
928 {
915929 if ( !prefs.show_back )
916930 Back->hide();
917931 if ( !prefs.show_forw )
930944 Tools->hide();
931945 if ( !prefs.show_clear_url )
932946 Clear->hide();
933 if ( !prefs.show_url )
934 Location->hide();
935947 if ( !prefs.show_search )
936948 Search->hide();
937949 if ( !prefs.show_help )
952964 */
953965 void UI::change_panel(int new_size, int small_icons)
954966 {
967 char *loc_text = dStrdup(Location->value());
968
955969 // Remove current panel's bars
956970 init_sizes();
957971 TopGroup->remove(LocBar);
966980
967981 // make a new panel
968982 make_panel(TopGroup->w());
969 customize(0);
983 customize();
970984 a_UIcmd_set_buttons_sens(a_UIcmd_get_bw_by_widget(this));
971985
972986 TopGroup->rearrange();
987 Location->value(loc_text);
973988 Location->take_focus();
974 }
975
976 /*
977 * On-the-fly color style change
978 */
979 void UI::color_change_cb_i()
980 {
981 const int cols[] = {7,17,26,51,140,156,205,206,215,-1};
982 static int ncolor = 0;
983
984 ncolor = (cols[ncolor+1] < 0) ? 0 : ncolor + 1;
985 CuteColor = cols[ncolor];
986 MSG("Location color %d\n", CuteColor);
987 Location->color(CuteColor);
988 Location->redraw();
989
990 dFree(loc_text);
989991 }
990992
991993 /*
10801082 hide ? NavBar->hide() : NavBar->show();
10811083 }
10821084 if (StatusBar) {
1083 hide ? StatusBar->size(0,0) : StatusBar->size(w(),sh);;
1084 hide ? StatusBar->hide() : StatusBar->show();;
1085 hide ? StatusBar->size(0,0) : StatusBar->size(w(),sh);
1086 hide ? StatusBar->hide() : StatusBar->show();
10851087 StatusBar->rearrange();
10861088 }
10871089
1010 #include <FL/Fl_Image.H>
1111 #include <FL/Fl_Tabs.H>
1212
13 #include "tipwin.hh"
1314 #include "findbar.hh"
1415
1516 typedef enum {
114115 }
115116 };
116117
117 /*
118 * A button that highlights on mouse over
119 */
120 class CustLightButton : public Fl_Button {
121 Fl_Color norm_color, light_color;
122 public:
123 CustLightButton(int x, int y, int w, int h, const char *l=0) :
124 Fl_Button(x,y,w,h,l) { norm_color = color(); light_color = 51; };
125 virtual int handle(int e)
126 {
127 if (active()) {
128 if (e == FL_ENTER) {
129 color(light_color); // {17,26,51}
130 redraw();
131 } else if (e == FL_LEAVE || e == FL_RELEASE || e == FL_HIDE) {
132 color(norm_color);
133 redraw();
134 }
135 } else if (e == FL_DEACTIVATE && color() != norm_color) {
136 color(norm_color);
137 redraw();
138 }
139 return Fl_Button::handle(e);
140 }
141 void hl_color(Fl_Color col) { light_color = col; };
142 };
143118
144119 //
145120 // UI class definition -------------------------------------------------------
146121 //
147122 class UI : public CustGroupVertical {
148123 CustTabs *Tabs;
149 char *TabTooltip;
150124
151125 CustGroupVertical *TopGroup;
152 Fl_Button *Back, *Forw, *Home, *Reload, *Save, *Stop, *Bookmarks, *Tools,
153 *Clear, *Search, *Help, *BugMeter, *FileButton;
126 CustButton *Back, *Forw, *Home, *Reload, *Save, *Stop, *Bookmarks,
127 *Tools, *Clear, *Search, *Help, *BugMeter, *FileButton;
154128 CustGroupHorizontal *LocBar, *NavBar, *StatusBar;
155 Fl_Input *Location;
129 Fl_Input *Location;
156130 CustProgressBox *PProg, *IProg;
157131 Fl_Group *Panel, *Main;
158132 Fl_Output *StatusOutput;
160134
161135 int MainIdx;
162136 // Panel customization variables
163 int PanelSize, CuteColor, Small_Icons;
137 int PanelSize, Small_Icons;
164138 int p_xpos, p_ypos, bw, bh, mh, lh, nh, fh, sh, pw, lbl;
165139 bool PanelTemporary;
166140
167141 UIPanelmode Panelmode;
168 Fl_Button *make_button(const char *label, Fl_Image *img,
169 Fl_Image*deimg, int b_n, int start = 0);
142 CustButton *make_button(const char *label, Fl_Image *img, Fl_Image*deimg,
143 int b_n, int start = 0);
170144 void make_toolbar(int tw, int th);
171145 void make_location(int ww);
172146 void make_progress_bars(int wide, int thin_up);
192166 void set_img_prog(int n_img, int t_img, int cmd);
193167 void set_bug_prog(int n_bug);
194168 void set_render_layout(Fl_Group *nw);
195 void customize(int flags);
169 void customize();
196170 void button_set_sens(UIButton btn, int sens);
197171 void paste_url();
198172 int get_panelsize() { return PanelSize; }
1111 // Functions/Methods for commands triggered from the UI
1212
1313
14 #include <string.h>
1415 #include <stdio.h>
1516 #include <stdarg.h>
17 #include <stdlib.h> /* for qsort */
1618 #include <math.h> /* for rint */
19 #include <limits.h> /* for UINT_MAX */
20 #include <sys/stat.h>
1721
1822 #include <FL/Fl.H>
1923 #include <FL/Fl_Widget.H>
5862 /*
5963 * Local data
6064 */
61 static char *save_dir = NULL;
65 static const char *save_dir = "";
6266
6367 /*
6468 * Forward declarations
7781 */
7882 class CustTabButton : public Fl_Button {
7983 UI *ui_;
84 uint_t focus_num_; // Used to choose which tab to focus when closing the
85 // active one (the highest numbered gets focus).
8086 public:
8187 CustTabButton (int x,int y,int w,int h, const char* label = 0) :
82 Fl_Button (x,y,w,h,label) { ui_ = NULL; };
88 Fl_Button (x,y,w,h,label) { ui_ = NULL; focus_num_ = 0; };
8389 void ui(UI *pui) { ui_ = pui; }
8490 UI *ui(void) { return ui_; }
91 void focus_num(uint_t fn) { focus_num_ = fn; }
92 uint_t focus_num(void) { return focus_num_; }
8593 };
8694
95 static int btn_cmp(const void *p1, const void *p2)
96 {
97 return ((*(CustTabButton * const *)p1)->focus_num() -
98 (*(CustTabButton * const *)p2)->focus_num() );
99 }
100
87101 /*
88102 * Allows fine control of the tabbed interface
89103 */
90104 class CustTabs : public Fl_Group {
105 uint_t focus_counter; // An increasing counter
91106 int tab_w, tab_h, ctab_h, btn_w, ctl_w;
92107 Fl_Wizard *Wizard;
93108 Fl_Scroll *Scroll;
94109 Fl_Pack *Pack;
95110 Fl_Group *Control;
96 CustLightButton *CloseBtn;
97 int tabcolor_inactive, tabcolor_active;
111 CustButton *CloseBtn;
98112
99113 void update_pack_offset(void);
100114 void resize(int x, int y, int w, int h)
101115 { Fl_Group::resize(x,y,w,h); update_pack_offset(); }
102116 int get_btn_idx(UI *ui);
117 void increase_focus_counter() {
118 if (focus_counter < UINT_MAX) /* check for overflow */
119 ++focus_counter;
120 else {
121 /* wrap & normalize old numbers here */
122 CustTabButton **btns = dNew(CustTabButton*, num_tabs());
123 for (int i = 0; i < num_tabs(); ++i)
124 btns[i] = (CustTabButton*)Pack->child(i);
125 qsort(btns, num_tabs(), sizeof(CustTabButton *), btn_cmp);
126 focus_counter = 0;
127 for (int i = 0; i < num_tabs(); ++i)
128 btns[i]->focus_num(focus_counter++);
129 dFree(btns);
130 }
131 }
103132
104133 public:
105134 CustTabs (int ww, int wh, int th, const char *lbl=0) :
106135 Fl_Group(0,0,ww,th,lbl) {
107136 Pack = NULL;
137 focus_counter = 0;
108138 tab_w = 50, tab_h = th, ctab_h = 1, btn_w = 20, ctl_w = 1*btn_w+2;
109 tabcolor_active = 0x87aca700; tabcolor_inactive = 0xb7beb700;
110139 resize(0,0,ww,ctab_h);
111140 /* tab buttons go inside a pack within a scroll */
112141 Scroll = new Fl_Scroll(0,0,ww-ctl_w,ctab_h);
121150
122151 /* control buttons go inside a group */
123152 Control = new Fl_Group(ww-ctl_w,0,ctl_w,ctab_h);
124 CloseBtn = new CustLightButton(ww-ctl_w+2,0,btn_w,ctab_h, "X");
153 CloseBtn = new CustButton(ww-ctl_w+2,0,btn_w,ctab_h, "X");
125154 CloseBtn->box(FL_THIN_UP_BOX);
126 CloseBtn->labelcolor(0x00641000);
127 CloseBtn->hl_color(FL_WHITE);
128155 CloseBtn->clear_visible_focus();
129 CloseBtn->tooltip(prefs.right_click_closes_tab ?
156 CloseBtn->set_tooltip(prefs.right_click_closes_tab ?
130157 "Close current tab.\nor Right-click tab label to close." :
131158 "Close current tab.\nor Middle-click tab label to close.");
132159 CloseBtn->callback(close_tab_btn_cb, this);
252279 btn->copy_label(DEFAULT_TAB_LABEL);
253280 btn->clear_visible_focus();
254281 btn->box(FL_GTK_THIN_UP_BOX);
255 btn->color(focus ? tabcolor_active : tabcolor_inactive);
282 btn->color(focus ? PREFS_UI_TAB_ACTIVE_BG_COLOR : PREFS_UI_TAB_BG_COLOR);
283 btn->labelcolor(focus ? PREFS_UI_TAB_ACTIVE_FG_COLOR:PREFS_UI_TAB_FG_COLOR);
256284 btn->ui(new_ui);
257285 btn->callback(tab_btn_cb, this);
258286 Pack->add(btn); // append
259287
260288 if (focus) {
261289 switch_tab(btn);
262 } else if (num_tabs() == 2) {
263 // no focus and tabbar added: redraw current page
264 Wizard->redraw();
290 } else { // no focus
291 // set focus counter
292 increase_focus_counter();
293 btn->focus_num(focus_counter);
294
295 if (num_tabs() == 2) {
296 // tabbar added: redraw current page
297 Wizard->redraw();
298 }
265299 }
266300 if (num_tabs() == 1)
267301 btn->hide();
284318 btn = (CustTabButton*)Pack->child(rm_idx);
285319
286320 if (act_idx == rm_idx) {
287 // Active tab is being closed, switch to another one
288 rm_idx > 0 ? prev_tab() : next_tab();
321 // Active tab is being closed, switch to the "previous" one
322 CustTabButton *fbtn = NULL;
323 for (int i = 0; i < num_tabs(); ++i) {
324 if (i != rm_idx) {
325 if (!fbtn)
326 fbtn = (CustTabButton*)Pack->child(i);
327 CustTabButton *btn = (CustTabButton*)Pack->child(i);
328 if (btn->focus_num() > fbtn->focus_num())
329 fbtn = btn;
330 }
331 }
332 switch_tab(fbtn);
289333 }
290334 Pack->remove(rm_idx);
291335 update_pack_offset();
360404 BrowserWindow *bw;
361405 UI *old_ui = (UI*)Wizard->value();
362406
363 if (cbtn->ui() != old_ui) {
407 if (cbtn && cbtn->ui() != old_ui) {
364408 // Set old tab label to normal color
365409 if ((idx = get_btn_idx(old_ui)) != -1) {
366410 btn = (CustTabButton*)Pack->child(idx);
367 btn->color(tabcolor_inactive);
411 btn->color(PREFS_UI_TAB_BG_COLOR);
412 btn->labelcolor(PREFS_UI_TAB_FG_COLOR);
368413 btn->redraw();
369414 }
415 /* We make a point of calling show() before value() is changed because
416 * the wizard may hide the old one before showing the new one. In that
417 * case, the new UI gets focus with Fl::e_keysym set to whatever
418 * triggered the switch, and this is a problem when it's Tab/Left/Right/
419 * Up/Down because some widgets (notably Fl_Group and Fl_Input) exhibit
420 * unwelcome behaviour in that case. If the new widgets are already
421 * shown, fl_fix_focus will fix everything with Fl::e_keysym temporarily
422 * cleared.
423 */
424 cbtn->ui()->show();
370425 Wizard->value(cbtn->ui());
371 cbtn->color(tabcolor_active);
426 cbtn->color(PREFS_UI_TAB_ACTIVE_BG_COLOR);
427 cbtn->labelcolor(PREFS_UI_TAB_ACTIVE_FG_COLOR);
372428 cbtn->redraw();
373429 update_pack_offset();
374430
377433 const char *title = (cbtn->ui())->label();
378434 cbtn->window()->copy_label(title ? title : "");
379435 }
436 // Update focus priority
437 increase_focus_counter();
438 cbtn->focus_num(focus_counter);
380439 }
381440 }
382441
432491 CustTabs *tabs = (CustTabs*) cb_data;
433492 int choice = 1, ntabs = tabs->num_tabs();
434493
494 if (Fl::event_key() == FL_Escape) {
495 // Don't let FLTK close a browser window due to unhandled Escape
496 // (most likely with modifiers).
497 return;
498 }
499
435500 if (prefs.show_quit_dialog && ntabs > 1)
436 choice = a_Dialog_choice5("Window contains more than one tab.",
437 "Close", "Cancel", NULL, NULL, NULL);
501 choice = a_Dialog_choice("Dillo: Close window?",
502 "Window contains more than one tab.",
503 "Close", "Cancel", NULL);
438504 if (choice == 1)
439505 while (ntabs-- > 0)
440506 a_UIcmd_close_bw(a_UIcmd_get_bw_by_widget(tabs->wizard()->value()));
573639 int choice = 1;
574640
575641 if (prefs.show_quit_dialog && a_Bw_num() > 1)
576 choice = a_Dialog_choice5("More than one open tab or window.",
577 "Quit", "Cancel", NULL, NULL, NULL);
642 choice = a_Dialog_choice("Dillo: Quit?",
643 "More than one open tab or window.",
644 "Quit", "Cancel", NULL);
578645 if (choice == 1)
579646 while ((bw = a_Bw_get(0)))
580647 a_UIcmd_close_bw((void*)bw);
642709 */
643710 if (url) {
644711 a_Nav_push(new_bw, url, NULL);
712 a_UIcmd_set_location_text(new_bw, URL_STR(url));
645713 BW2UI(new_bw)->focus_main();
646714 } else {
647715 BW2UI(new_bw)->focus_location();
741809 /*
742810 * Return a suitable filename for a given URL path.
743811 */
744 static char *UIcmd_make_save_filename(const char *pathstr)
812 static char *UIcmd_make_save_filename(const DilloUrl *url)
745813 {
746814 size_t MaxLen = 64;
747 char *FileName, *newname, *o, *n;
748 const char *name, *dir = a_UIcmd_get_save_dir();
749
750 if ((name = strrchr(pathstr, '/'))) {
751 if (strlen(++name) > MaxLen) {
752 name = name + strlen(name) - MaxLen;
815 const char *dir = save_dir, *path, *path2, *query;
816 char *name, *free1, *free2, *n1, *n2;
817
818 free1 = free2 = NULL;
819
820 /* get the last component of the path */
821 path = URL_PATH(url);
822 path2 = strrchr(path, '/');
823 path = path2 ? path2 + 1 : path;
824
825 /* truncate the path if necessary */
826 if (strlen(path) > MaxLen) {
827 path = free1 = dStrndup(path, MaxLen);
828 }
829
830 /* is there a query? */
831 query = URL_QUERY(url);
832 if (*query) {
833 /* truncate the query if necessary */
834 if (strlen(query) > MaxLen) {
835 query = free2 = dStrndup(query, MaxLen);
753836 }
754 /* Replace %20 and ' ' with '_' in Filename */
755 o = n = newname = dStrdup(name);
756 for (int i = 0; o[i]; i++) {
757 *n++ = (o[i] == ' ') ? '_' :
758 (o[i] == '%' && o[i+1] == '2' && o[i+2] == '0') ?
759 i+=2, '_' : o[i];
837 name = dStrconcat(dir, path, "?", query, NULL);
838 } else {
839 name = dStrconcat(dir, path, NULL);
840 }
841
842 dFree(free1);
843 dFree(free2);
844
845 /* Replace %20 and ' ' with '_' */
846 for (n1 = n2 = name; *n1; n1++, n2++) {
847 *n2 =
848 (n1[0] == ' ')
849 ? '_' :
850 (n1[0] == '%' && n1[1] == '2' && n1[2] == '0')
851 ? (n1 += 2, '_') :
852 n1[0];
853 }
854 *n2 = 0;
855
856 return name;
857 }
858
859 /*
860 * Set the default directory for saving files.
861 */
862 void a_UIcmd_init(void)
863 {
864 const char *dir = prefs.save_dir;
865
866 if (dir && *dir) {
867 // assert a trailing '/'
868 save_dir =
869 (dir[strlen(dir)-1] == '/')
870 ? dStrdup(dir)
871 : dStrconcat(dir, "/", NULL);
872 }
873 }
874
875 /*
876 * Check a file to save to.
877 */
878 static int UIcmd_save_file_check(const char *name)
879 {
880 struct stat ss;
881 if (stat(name, &ss) == 0) {
882 Dstr *ds;
883 int ch;
884 ds = dStr_sized_new(128);
885 dStr_sprintf(ds,
886 "The file:\n %s (%d Bytes)\nalready exists. What do we do?",
887 name, (int)ss.st_size);
888 ch = a_Dialog_choice("Dillo Save: File exists!", ds->str,
889 "Abort", "Continue", "Rename", NULL);
890 dStr_free(ds, 1);
891 return ch;
892 } else {
893 return 2; /* assume the file does not exist, so Continue */
894 }
895 }
896
897 /*
898 * Save a URL
899 */
900 static void UIcmd_save(BrowserWindow *bw, const DilloUrl *url,
901 const char *title)
902 {
903 char *SuggestedName = UIcmd_make_save_filename(url);
904
905 while (1) {
906 const char *name = a_Dialog_save_file(title, NULL, SuggestedName);
907 dFree(SuggestedName);
908
909 if (name) {
910 switch (UIcmd_save_file_check(name)) {
911 case 0:
912 case 1:
913 /* Abort */
914 return;
915 case 2:
916 /* Continue */
917 MSG("UIcmd_save: %s\n", name);
918 a_Nav_save_url(bw, url, name);
919 return;
920 default:
921 /* Rename */
922 break; /* prompt again */
923 }
924 } else {
925 return; /* no name, so Abort */
760926 }
761 *n = 0;
762 FileName = dStrconcat(dir ? dir : "", newname, NULL);
763 dFree(newname);
764 } else {
765 FileName = dStrconcat(dir ? dir : "", pathstr, NULL);
766 }
767 return FileName;
768 }
769
770 /*
771 * Get the default directory for saving files.
772 */
773 const char *a_UIcmd_get_save_dir()
774 {
775 return save_dir;
776 }
777
778 /*
779 * Set the default directory for saving files.
780 */
781 void a_UIcmd_set_save_dir(const char *dir)
782 {
783 const char *p;
784
785 if (dir && (p = strrchr(dir, '/'))) {
786 dFree(save_dir);
787 // assert a trailing '/'
788 save_dir = dStrconcat(dir, (p[1] != 0) ? "/" : "", NULL);
927
928 SuggestedName = dStrdup(name);
789929 }
790930 }
791931
794934 */
795935 void a_UIcmd_save(void *vbw)
796936 {
797 const char *name;
798 char *SuggestedName;
799937 BrowserWindow *bw = (BrowserWindow *)vbw;
800938 const DilloUrl *url = a_History_get_url(NAV_TOP_UIDX(bw));
801939
802940 if (url) {
803 a_UIcmd_set_save_dir(prefs.save_dir);
804 SuggestedName = UIcmd_make_save_filename(URL_PATH(url));
805 name = a_Dialog_save_file("Save Page as File", NULL, SuggestedName);
806 MSG("a_UIcmd_save: %s\n", name);
807 dFree(SuggestedName);
808
809 if (name) {
810 a_Nav_save_url(bw, url, name);
811 }
941 UIcmd_save(bw, url, "Save Page as File");
812942 }
813943 }
814944
817947 */
818948 const char *a_UIcmd_select_file()
819949 {
820 return a_Dialog_select_file("Select a File", NULL, NULL);
950 return a_Dialog_select_file("Dillo: Select a File", NULL, NULL);
821951 }
822952
823953 /*
850980 char *name;
851981 DilloUrl *url;
852982
853 name = a_Dialog_open_file("Open File", NULL, "");
983 name = a_Dialog_open_file("Dillo: Open File", NULL, "");
854984
855985 if (name) {
856986 url = a_Url_new(name, "file:");
8781008 if (*c == '%')
8791009 switch(*++c) {
8801010 case 's':
881 dStr_append(ds, keys); break;;
1011 dStr_append(ds, keys); break;
8821012 case '%':
883 dStr_append_c(ds, '%'); break;;
1013 dStr_append_c(ds, '%'); break;
8841014 case 0:
885 MSG_WARN("search_url ends with '%%'\n"); c--; break;;
1015 MSG_WARN("search_url ends with '%%'\n"); c--; break;
8861016 default:
8871017 MSG_WARN("illegal specifier '%%%c' in search_url\n", *c);
8881018 }
9041034 {
9051035 const char *query;
9061036
907 if ((query = a_Dialog_input("Search the Web:"))) {
1037 if ((query = a_Dialog_input("Dillo: Search", "Search the Web:"))) {
9081038 char *url_str = UIcmd_make_search_str(query);
9091039 a_UIcmd_open_urlstr(vbw, url_str);
9101040 dFree(url_str);
9171047 const char *a_UIcmd_get_passwd(const char *user)
9181048 {
9191049 const char *passwd;
920 char *prompt = dStrconcat("Password for user \"", user, "\"", NULL);
921 passwd = a_Dialog_passwd(prompt);
922 dFree(prompt);
1050 const char *title = "Dillo: Password";
1051 char *msg = dStrconcat("Password for user \"", user, "\"", NULL);
1052 passwd = a_Dialog_passwd(title, msg);
1053 dFree(msg);
9231054 return passwd;
9241055 }
9251056
9281059 */
9291060 void a_UIcmd_save_link(BrowserWindow *bw, const DilloUrl *url)
9301061 {
931 const char *name;
932 char *SuggestedName;
933
934 a_UIcmd_set_save_dir(prefs.save_dir);
935
936 SuggestedName = UIcmd_make_save_filename(URL_STR(url));
937 if ((name = a_Dialog_save_file("Save Link as File", NULL, SuggestedName))) {
938 MSG("a_UIcmd_save_link: %s\n", name);
939 a_Nav_save_url(bw, url, name);
940 }
941 dFree(SuggestedName);
1062 UIcmd_save(bw, url, "Dillo: Save Link as File");
9421063 }
9431064
9441065 /*
10181139 */
10191140 void a_UIcmd_view_page_source(BrowserWindow *bw, const DilloUrl *url)
10201141 {
1021 char *buf;
1142 char *buf, *major;
10221143 int buf_size;
10231144 Dstr *dstr_url;
10241145 DilloUrl *vs_url;
10251146 static int post_id = 0;
10261147 char tag[8];
1027
1028 if (a_Nav_get_buf(url, &buf, &buf_size)) {
1148 const char *content_type = a_Nav_get_content_type(url);
1149
1150 a_Misc_parse_content_type(content_type, &major, NULL, NULL);
1151
1152 if (major && dStrAsciiCasecmp(major, "image") &&
1153 a_Nav_get_buf(url, &buf, &buf_size)) {
10291154 a_Nav_set_vsource_url(url);
10301155 dstr_url = dStr_new("dpi:/vsource/:");
10311156 dStr_append(dstr_url, URL_STR(url));
10411166 dStr_free(dstr_url, 1);
10421167 a_Nav_unref_buf(url);
10431168 }
1169 dFree(major);
10441170 }
10451171
10461172 /*
10511177 BrowserWindow *bw = (BrowserWindow*)vbw;
10521178
10531179 if (bw->num_page_bugs > 0) {
1054 a_Dialog_text_window(bw->page_bugs->str, "Detected HTML errors");
1180 a_Dialog_text_window("Dillo: Detected HTML errors", bw->page_bugs->str);
10551181 } else {
1056 a_Dialog_msg("Zero detected HTML errors!");
1182 a_Dialog_msg("Dillo: Valid HTML!", "Zero detected HTML errors!");
10571183 }
10581184 }
10591185
11761302 };
11771303 KeysCommand_t keycmd = (KeysCommand_t)icmd;
11781304
1179 for (uint_t i = 0; i < (sizeof(map)/sizeof(mapping_t)); i++) {
1305 for (uint_t i = 0; i < sizeof(map) / sizeof(map[0]); i++) {
11801306 if (keycmd == map[i].keys_cmd) {
11811307 layout->scroll(map[i].dw_cmd);
11821308 break;
5858 void a_UIcmd_close_bw(void *vbw);
5959 void a_UIcmd_close_all_bw(void *p);
6060
61 const char *a_UIcmd_get_save_dir();
62 void a_UIcmd_set_save_dir(const char *dir);
61 void a_UIcmd_init(void);
6362
6463
6564 // UI binding functions -------------------------------------------------------
687687
688688 if (tld_len > 0) {
689689 /* These TLDs were chosen by examining the current publicsuffix list
690 * in September 2011 and picking out those where it was simplest for
691 * them to describe the situation by beginning with a "*.[tld]" rule.
690 * in October 2012 and picking out those where it was simplest for
691 * them to describe the situation by beginning with a "*.[tld]" rule
692 * or every rule was "[something].[tld]".
692693 */
693 const char *const tlds[] = {"ar","au","bd","bn","bt","ck","cy",
694 "er","et","fj","fk","gt","gu","id",
695 "il","jm","ke","kh","kw","ml","mm","mt",
696 "mz","ni","np","nz","om","pg","py","qa",
697 "sv","tr","uk","uy","ve","ye","yu","za",
698 "zm","zw"};
694 const char *const tlds[] = {"ar","au","bd","bn","ck","cy","er","et",
695 "fj","fk","gt","gu","il","jm","ke","kh",
696 "kp","kw","lb","lr","mm","mt","mz","ni",
697 "np","nz","om","pg","py","sv","tr","uk",
698 "ve","ye","za","zm","zw"};
699699 uint_t i, tld_num = sizeof(tlds) / sizeof(tlds[0]);
700700
701701 for (i = 0; i < tld_num; i++) {
8383 #define URL_ILLEGAL_CHARS_SPC(u) URL_ILLEGAL_CHARS_SPC_(u)
8484
8585
86 typedef struct _DilloUrl DilloUrl;
87
8886 #ifdef __cplusplus
8987 extern "C" {
9088 #endif /* __cplusplus */
9189
92 struct _DilloUrl {
90 typedef struct {
9391 Dstr *url_string;
9492 const char *buffer;
9593 const char *scheme; /**/
105103 int ismap_url_len; /* Used by server side image maps */
106104 int illegal_chars; /* number of illegal chars */
107105 int illegal_chars_spc; /* number of illegal space chars */
108 };
106 } DilloUrl;
109107
110108
111109 DilloUrl* a_Url_new(const char *url_str, const char *base_url);
5454
5555 dReturn_val_if_fail(Web->bw != NULL, -1);
5656
57 // get the Layout object from the bw structure.
5857 Layout *layout = (Layout*)Web->bw->render_layout;
58
59 Viewer_t viewer = a_Mime_get_viewer(Type);
60 if (viewer == NULL)
61 return -1;
5962
6063 if (Web->flags & WEB_RootUrl) {
6164 /* We have RootUrl! */
6871 StyleEngine styleEngine (layout);
6972 styleEngine.startElement ("body");
7073
71 dw = (Widget*) a_Mime_set_viewer(Type, Web, Call, Data);
74 dw = (Widget*) viewer(Type, Web, Call, Data);
7275 if (dw == NULL)
7376 return -1;
7477
9598 } else {
9699 /* A non-RootUrl. At this moment we only handle image-children */
97100 if (!dStrnAsciiCasecmp(Type, "image/", 6)) {
98 dw = (Widget*) a_Mime_set_viewer(Type, Web, Call, Data);
101 dw = (Widget*) viewer(Type, Web, Call, Data);
99102 } else {
100103 MSG_HTTP("'%s' cannot be displayed as image; has media type '%s'\n",
101104 URL_STR(Web->url), Type);
1818 dw-imgbuf-mem-test \
1919 dw-resource-test \
2020 dw-ui-test \
21 fltk-browser \
21 containers \
2222 shapes \
23 cookies
23 cookies \
24 liang \
25 trie \
26 notsosimplevector \
27 unicode-test
2428
2529 dw_anchors_test_SOURCES = dw_anchors_test.cc
2630 dw_anchors_test_LDADD = \
146150 $(top_builddir)/lout/liblout.a \
147151 @LIBFLTK_LIBS@
148152
149 fltk_browser_SOURCES = fltk_browser.cc
150 fltk_browser_LDADD = @LIBFLTK_LIBS@
151
152153 shapes_SOURCES = shapes.cc
153154 shapes_LDADD = \
154155 $(top_builddir)/dw/libDw-core.a \
155156 $(top_builddir)/lout/liblout.a
156157
158 containers_SOURCES = containers.cc
159 containers_LDADD = $(top_builddir)/lout/liblout.a
160
157161 cookies_SOURCES = cookies.c
158162 cookies_LDADD = \
159163 $(top_builddir)/dpip/libDpip.a \
160164 $(top_builddir)/dlib/libDlib.a
165
166 liang_SOURCES = liang.cc
167
168 liang_LDADD = \
169 $(top_builddir)/dw/libDw-widgets.a \
170 $(top_builddir)/dw/libDw-fltk.a \
171 $(top_builddir)/dw/libDw-core.a \
172 $(top_builddir)/lout/liblout.a \
173 @LIBFLTK_LIBS@
174
175 trie_SOURCES = trie.cc
176
177 trie_LDADD = \
178 $(top_builddir)/dw/libDw-widgets.a \
179 $(top_builddir)/dw/libDw-fltk.a \
180 $(top_builddir)/dw/libDw-core.a \
181 $(top_builddir)/lout/liblout.a \
182 @LIBFLTK_LIBS@
183
184 notsosimplevector_SOURCES = notsosimplevector.cc
185
186 notsosimplevector_LDADD = $(top_builddir)/lout/liblout.a
187
188 unicode_test_SOURCES = unicode_test.cc
189
190 unicode_test_LDADD = \
191 $(top_builddir)/lout/liblout.a \
192 @LIBFLTK_LIBS@
0 # Makefile.in generated by automake 1.11.1 from Makefile.am.
0 # Makefile.in generated by automake 1.11.6 from Makefile.am.
11 # @configure_input@
22
33 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
4 # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
5 # Inc.
4 # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
5 # Foundation, Inc.
66 # This Makefile.in is free software; the Free Software Foundation
77 # gives unlimited permission to copy and/or distribute it,
88 # with or without modifications, as long as this notice is preserved.
1515 @SET_MAKE@
1616
1717 VPATH = @srcdir@
18 am__make_dryrun = \
19 { \
20 am__dry=no; \
21 case $$MAKEFLAGS in \
22 *\\[\ \ ]*) \
23 echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
24 | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
25 *) \
26 for am__flg in $$MAKEFLAGS; do \
27 case $$am__flg in \
28 *=*|--*) ;; \
29 *n*) am__dry=yes; break;; \
30 esac; \
31 done;; \
32 esac; \
33 test $$am__dry = yes; \
34 }
1835 pkgdatadir = $(datadir)/@PACKAGE@
1936 pkgincludedir = $(includedir)/@PACKAGE@
2037 pkglibdir = $(libdir)/@PACKAGE@
4158 dw-table-aligned$(EXEEXT) dw-table$(EXEEXT) \
4259 dw-border-test$(EXEEXT) dw-imgbuf-mem-test$(EXEEXT) \
4360 dw-resource-test$(EXEEXT) dw-ui-test$(EXEEXT) \
44 fltk-browser$(EXEEXT) shapes$(EXEEXT) cookies$(EXEEXT)
61 containers$(EXEEXT) shapes$(EXEEXT) cookies$(EXEEXT) \
62 liang$(EXEEXT) trie$(EXEEXT) notsosimplevector$(EXEEXT) \
63 unicode-test$(EXEEXT)
4564 subdir = test
4665 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
4766 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
48 am__aclocal_m4_deps = $(top_srcdir)/configure.in
67 am__aclocal_m4_deps = $(top_srcdir)/configure.ac
4968 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
5069 $(ACLOCAL_M4)
5170 mkinstalldirs = $(install_sh) -d
5372 CONFIG_CLEAN_FILES =
5473 CONFIG_CLEAN_VPATH_FILES =
5574 PROGRAMS = $(noinst_PROGRAMS)
75 am_containers_OBJECTS = containers.$(OBJEXT)
76 containers_OBJECTS = $(am_containers_OBJECTS)
77 containers_DEPENDENCIES = $(top_builddir)/lout/liblout.a
5678 am_cookies_OBJECTS = cookies.$(OBJEXT)
5779 cookies_OBJECTS = $(am_cookies_OBJECTS)
5880 cookies_DEPENDENCIES = $(top_builddir)/dpip/libDpip.a \
132154 dw_ui_test_DEPENDENCIES = $(top_builddir)/dw/libDw-widgets.a \
133155 $(top_builddir)/dw/libDw-fltk.a \
134156 $(top_builddir)/dw/libDw-core.a $(top_builddir)/lout/liblout.a
135 am_fltk_browser_OBJECTS = fltk_browser.$(OBJEXT)
136 fltk_browser_OBJECTS = $(am_fltk_browser_OBJECTS)
137 fltk_browser_DEPENDENCIES =
157 am_liang_OBJECTS = liang.$(OBJEXT)
158 liang_OBJECTS = $(am_liang_OBJECTS)
159 liang_DEPENDENCIES = $(top_builddir)/dw/libDw-widgets.a \
160 $(top_builddir)/dw/libDw-fltk.a \
161 $(top_builddir)/dw/libDw-core.a $(top_builddir)/lout/liblout.a
162 am_notsosimplevector_OBJECTS = notsosimplevector.$(OBJEXT)
163 notsosimplevector_OBJECTS = $(am_notsosimplevector_OBJECTS)
164 notsosimplevector_DEPENDENCIES = $(top_builddir)/lout/liblout.a
138165 am_shapes_OBJECTS = shapes.$(OBJEXT)
139166 shapes_OBJECTS = $(am_shapes_OBJECTS)
140167 shapes_DEPENDENCIES = $(top_builddir)/dw/libDw-core.a \
141168 $(top_builddir)/lout/liblout.a
169 am_trie_OBJECTS = trie.$(OBJEXT)
170 trie_OBJECTS = $(am_trie_OBJECTS)
171 trie_DEPENDENCIES = $(top_builddir)/dw/libDw-widgets.a \
172 $(top_builddir)/dw/libDw-fltk.a \
173 $(top_builddir)/dw/libDw-core.a $(top_builddir)/lout/liblout.a
174 am_unicode_test_OBJECTS = unicode_test.$(OBJEXT)
175 unicode_test_OBJECTS = $(am_unicode_test_OBJECTS)
176 unicode_test_DEPENDENCIES = $(top_builddir)/lout/liblout.a
142177 DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
143178 depcomp = $(SHELL) $(top_srcdir)/depcomp
144179 am__depfiles_maybe = depfiles
152187 CXXLD = $(CXX)
153188 CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
154189 -o $@
155 SOURCES = $(cookies_SOURCES) $(dw_anchors_test_SOURCES) \
156 $(dw_border_test_SOURCES) $(dw_example_SOURCES) \
157 $(dw_find_test_SOURCES) $(dw_images_scaled_SOURCES) \
158 $(dw_images_scaled2_SOURCES) $(dw_images_simple_SOURCES) \
159 $(dw_imgbuf_mem_test_SOURCES) $(dw_links_SOURCES) \
160 $(dw_links2_SOURCES) $(dw_lists_SOURCES) \
190 SOURCES = $(containers_SOURCES) $(cookies_SOURCES) \
191 $(dw_anchors_test_SOURCES) $(dw_border_test_SOURCES) \
192 $(dw_example_SOURCES) $(dw_find_test_SOURCES) \
193 $(dw_images_scaled_SOURCES) $(dw_images_scaled2_SOURCES) \
194 $(dw_images_simple_SOURCES) $(dw_imgbuf_mem_test_SOURCES) \
195 $(dw_links_SOURCES) $(dw_links2_SOURCES) $(dw_lists_SOURCES) \
161196 $(dw_resource_test_SOURCES) $(dw_table_SOURCES) \
162197 $(dw_table_aligned_SOURCES) $(dw_ui_test_SOURCES) \
163 $(fltk_browser_SOURCES) $(shapes_SOURCES)
164 DIST_SOURCES = $(cookies_SOURCES) $(dw_anchors_test_SOURCES) \
165 $(dw_border_test_SOURCES) $(dw_example_SOURCES) \
166 $(dw_find_test_SOURCES) $(dw_images_scaled_SOURCES) \
167 $(dw_images_scaled2_SOURCES) $(dw_images_simple_SOURCES) \
168 $(dw_imgbuf_mem_test_SOURCES) $(dw_links_SOURCES) \
169 $(dw_links2_SOURCES) $(dw_lists_SOURCES) \
198 $(liang_SOURCES) $(notsosimplevector_SOURCES) \
199 $(shapes_SOURCES) $(trie_SOURCES) $(unicode_test_SOURCES)
200 DIST_SOURCES = $(containers_SOURCES) $(cookies_SOURCES) \
201 $(dw_anchors_test_SOURCES) $(dw_border_test_SOURCES) \
202 $(dw_example_SOURCES) $(dw_find_test_SOURCES) \
203 $(dw_images_scaled_SOURCES) $(dw_images_scaled2_SOURCES) \
204 $(dw_images_simple_SOURCES) $(dw_imgbuf_mem_test_SOURCES) \
205 $(dw_links_SOURCES) $(dw_links2_SOURCES) $(dw_lists_SOURCES) \
170206 $(dw_resource_test_SOURCES) $(dw_table_SOURCES) \
171207 $(dw_table_aligned_SOURCES) $(dw_ui_test_SOURCES) \
172 $(fltk_browser_SOURCES) $(shapes_SOURCES)
208 $(liang_SOURCES) $(notsosimplevector_SOURCES) \
209 $(shapes_SOURCES) $(trie_SOURCES) $(unicode_test_SOURCES)
210 am__can_run_installinfo = \
211 case $$AM_UPDATE_INFO_DIR in \
212 n|no|NO) false;; \
213 *) (install-info --version) >/dev/null 2>&1;; \
214 esac
173215 ETAGS = etags
174216 CTAGS = ctags
175217 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
418460 $(top_builddir)/lout/liblout.a \
419461 @LIBFLTK_LIBS@
420462
421 fltk_browser_SOURCES = fltk_browser.cc
422 fltk_browser_LDADD = @LIBFLTK_LIBS@
423463 shapes_SOURCES = shapes.cc
424464 shapes_LDADD = \
425465 $(top_builddir)/dw/libDw-core.a \
426466 $(top_builddir)/lout/liblout.a
427467
468 containers_SOURCES = containers.cc
469 containers_LDADD = $(top_builddir)/lout/liblout.a
428470 cookies_SOURCES = cookies.c
429471 cookies_LDADD = \
430472 $(top_builddir)/dpip/libDpip.a \
431473 $(top_builddir)/dlib/libDlib.a
474
475 liang_SOURCES = liang.cc
476 liang_LDADD = \
477 $(top_builddir)/dw/libDw-widgets.a \
478 $(top_builddir)/dw/libDw-fltk.a \
479 $(top_builddir)/dw/libDw-core.a \
480 $(top_builddir)/lout/liblout.a \
481 @LIBFLTK_LIBS@
482
483 trie_SOURCES = trie.cc
484 trie_LDADD = \
485 $(top_builddir)/dw/libDw-widgets.a \
486 $(top_builddir)/dw/libDw-fltk.a \
487 $(top_builddir)/dw/libDw-core.a \
488 $(top_builddir)/lout/liblout.a \
489 @LIBFLTK_LIBS@
490
491 notsosimplevector_SOURCES = notsosimplevector.cc
492 notsosimplevector_LDADD = $(top_builddir)/lout/liblout.a
493 unicode_test_SOURCES = unicode_test.cc
494 unicode_test_LDADD = \
495 $(top_builddir)/lout/liblout.a \
496 @LIBFLTK_LIBS@
432497
433498 all: all-am
434499
467532
468533 clean-noinstPROGRAMS:
469534 -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
470 cookies$(EXEEXT): $(cookies_OBJECTS) $(cookies_DEPENDENCIES)
535 containers$(EXEEXT): $(containers_OBJECTS) $(containers_DEPENDENCIES) $(EXTRA_containers_DEPENDENCIES)
536 @rm -f containers$(EXEEXT)
537 $(CXXLINK) $(containers_OBJECTS) $(containers_LDADD) $(LIBS)
538 cookies$(EXEEXT): $(cookies_OBJECTS) $(cookies_DEPENDENCIES) $(EXTRA_cookies_DEPENDENCIES)
471539 @rm -f cookies$(EXEEXT)
472540 $(LINK) $(cookies_OBJECTS) $(cookies_LDADD) $(LIBS)
473 dw-anchors-test$(EXEEXT): $(dw_anchors_test_OBJECTS) $(dw_anchors_test_DEPENDENCIES)
541 dw-anchors-test$(EXEEXT): $(dw_anchors_test_OBJECTS) $(dw_anchors_test_DEPENDENCIES) $(EXTRA_dw_anchors_test_DEPENDENCIES)
474542 @rm -f dw-anchors-test$(EXEEXT)
475543 $(CXXLINK) $(dw_anchors_test_OBJECTS) $(dw_anchors_test_LDADD) $(LIBS)
476 dw-border-test$(EXEEXT): $(dw_border_test_OBJECTS) $(dw_border_test_DEPENDENCIES)
544 dw-border-test$(EXEEXT): $(dw_border_test_OBJECTS) $(dw_border_test_DEPENDENCIES) $(EXTRA_dw_border_test_DEPENDENCIES)
477545 @rm -f dw-border-test$(EXEEXT)
478546 $(CXXLINK) $(dw_border_test_OBJECTS) $(dw_border_test_LDADD) $(LIBS)
479 dw-example$(EXEEXT): $(dw_example_OBJECTS) $(dw_example_DEPENDENCIES)
547 dw-example$(EXEEXT): $(dw_example_OBJECTS) $(dw_example_DEPENDENCIES) $(EXTRA_dw_example_DEPENDENCIES)
480548 @rm -f dw-example$(EXEEXT)
481549 $(CXXLINK) $(dw_example_OBJECTS) $(dw_example_LDADD) $(LIBS)
482 dw-find-test$(EXEEXT): $(dw_find_test_OBJECTS) $(dw_find_test_DEPENDENCIES)
550 dw-find-test$(EXEEXT): $(dw_find_test_OBJECTS) $(dw_find_test_DEPENDENCIES) $(EXTRA_dw_find_test_DEPENDENCIES)
483551 @rm -f dw-find-test$(EXEEXT)
484552 $(CXXLINK) $(dw_find_test_OBJECTS) $(dw_find_test_LDADD) $(LIBS)
485 dw-images-scaled$(EXEEXT): $(dw_images_scaled_OBJECTS) $(dw_images_scaled_DEPENDENCIES)
553 dw-images-scaled$(EXEEXT): $(dw_images_scaled_OBJECTS) $(dw_images_scaled_DEPENDENCIES) $(EXTRA_dw_images_scaled_DEPENDENCIES)
486554 @rm -f dw-images-scaled$(EXEEXT)
487555 $(CXXLINK) $(dw_images_scaled_OBJECTS) $(dw_images_scaled_LDADD) $(LIBS)
488 dw-images-scaled2$(EXEEXT): $(dw_images_scaled2_OBJECTS) $(dw_images_scaled2_DEPENDENCIES)
556 dw-images-scaled2$(EXEEXT): $(dw_images_scaled2_OBJECTS) $(dw_images_scaled2_DEPENDENCIES) $(EXTRA_dw_images_scaled2_DEPENDENCIES)
489557 @rm -f dw-images-scaled2$(EXEEXT)
490558 $(CXXLINK) $(dw_images_scaled2_OBJECTS) $(dw_images_scaled2_LDADD) $(LIBS)
491 dw-images-simple$(EXEEXT): $(dw_images_simple_OBJECTS) $(dw_images_simple_DEPENDENCIES)
559 dw-images-simple$(EXEEXT): $(dw_images_simple_OBJECTS) $(dw_images_simple_DEPENDENCIES) $(EXTRA_dw_images_simple_DEPENDENCIES)
492560 @rm -f dw-images-simple$(EXEEXT)
493561 $(CXXLINK) $(dw_images_simple_OBJECTS) $(dw_images_simple_LDADD) $(LIBS)
494 dw-imgbuf-mem-test$(EXEEXT): $(dw_imgbuf_mem_test_OBJECTS) $(dw_imgbuf_mem_test_DEPENDENCIES)
562 dw-imgbuf-mem-test$(EXEEXT): $(dw_imgbuf_mem_test_OBJECTS) $(dw_imgbuf_mem_test_DEPENDENCIES) $(EXTRA_dw_imgbuf_mem_test_DEPENDENCIES)
495563 @rm -f dw-imgbuf-mem-test$(EXEEXT)
496564 $(CXXLINK) $(dw_imgbuf_mem_test_OBJECTS) $(dw_imgbuf_mem_test_LDADD) $(LIBS)
497 dw-links$(EXEEXT): $(dw_links_OBJECTS) $(dw_links_DEPENDENCIES)
565 dw-links$(EXEEXT): $(dw_links_OBJECTS) $(dw_links_DEPENDENCIES) $(EXTRA_dw_links_DEPENDENCIES)
498566 @rm -f dw-links$(EXEEXT)
499567 $(CXXLINK) $(dw_links_OBJECTS) $(dw_links_LDADD) $(LIBS)
500 dw-links2$(EXEEXT): $(dw_links2_OBJECTS) $(dw_links2_DEPENDENCIES)
568 dw-links2$(EXEEXT): $(dw_links2_OBJECTS) $(dw_links2_DEPENDENCIES) $(EXTRA_dw_links2_DEPENDENCIES)
501569 @rm -f dw-links2$(EXEEXT)
502570 $(CXXLINK) $(dw_links2_OBJECTS) $(dw_links2_LDADD) $(LIBS)
503 dw-lists$(EXEEXT): $(dw_lists_OBJECTS) $(dw_lists_DEPENDENCIES)
571 dw-lists$(EXEEXT): $(dw_lists_OBJECTS) $(dw_lists_DEPENDENCIES) $(EXTRA_dw_lists_DEPENDENCIES)
504572 @rm -f dw-lists$(EXEEXT)
505573 $(CXXLINK) $(dw_lists_OBJECTS) $(dw_lists_LDADD) $(LIBS)
506 dw-resource-test$(EXEEXT): $(dw_resource_test_OBJECTS) $(dw_resource_test_DEPENDENCIES)
574 dw-resource-test$(EXEEXT): $(dw_resource_test_OBJECTS) $(dw_resource_test_DEPENDENCIES) $(EXTRA_dw_resource_test_DEPENDENCIES)
507575 @rm -f dw-resource-test$(EXEEXT)
508576 $(CXXLINK) $(dw_resource_test_OBJECTS) $(dw_resource_test_LDADD) $(LIBS)
509 dw-table$(EXEEXT): $(dw_table_OBJECTS) $(dw_table_DEPENDENCIES)
577 dw-table$(EXEEXT): $(dw_table_OBJECTS) $(dw_table_DEPENDENCIES) $(EXTRA_dw_table_DEPENDENCIES)
510578 @rm -f dw-table$(EXEEXT)
511579 $(CXXLINK) $(dw_table_OBJECTS) $(dw_table_LDADD) $(LIBS)
512 dw-table-aligned$(EXEEXT): $(dw_table_aligned_OBJECTS) $(dw_table_aligned_DEPENDENCIES)
580 dw-table-aligned$(EXEEXT): $(dw_table_aligned_OBJECTS) $(dw_table_aligned_DEPENDENCIES) $(EXTRA_dw_table_aligned_DEPENDENCIES)
513581 @rm -f dw-table-aligned$(EXEEXT)
514582 $(CXXLINK) $(dw_table_aligned_OBJECTS) $(dw_table_aligned_LDADD) $(LIBS)
515 dw-ui-test$(EXEEXT): $(dw_ui_test_OBJECTS) $(dw_ui_test_DEPENDENCIES)
583 dw-ui-test$(EXEEXT): $(dw_ui_test_OBJECTS) $(dw_ui_test_DEPENDENCIES) $(EXTRA_dw_ui_test_DEPENDENCIES)
516584 @rm -f dw-ui-test$(EXEEXT)
517585 $(CXXLINK) $(dw_ui_test_OBJECTS) $(dw_ui_test_LDADD) $(LIBS)
518 fltk-browser$(EXEEXT): $(fltk_browser_OBJECTS) $(fltk_browser_DEPENDENCIES)
519 @rm -f fltk-browser$(EXEEXT)
520 $(CXXLINK) $(fltk_browser_OBJECTS) $(fltk_browser_LDADD) $(LIBS)
521 shapes$(EXEEXT): $(shapes_OBJECTS) $(shapes_DEPENDENCIES)
586 liang$(EXEEXT): $(liang_OBJECTS) $(liang_DEPENDENCIES) $(EXTRA_liang_DEPENDENCIES)
587 @rm -f liang$(EXEEXT)
588 $(CXXLINK) $(liang_OBJECTS) $(liang_LDADD) $(LIBS)
589 notsosimplevector$(EXEEXT): $(notsosimplevector_OBJECTS) $(notsosimplevector_DEPENDENCIES) $(EXTRA_notsosimplevector_DEPENDENCIES)
590 @rm -f notsosimplevector$(EXEEXT)
591 $(CXXLINK) $(notsosimplevector_OBJECTS) $(notsosimplevector_LDADD) $(LIBS)
592 shapes$(EXEEXT): $(shapes_OBJECTS) $(shapes_DEPENDENCIES) $(EXTRA_shapes_DEPENDENCIES)
522593 @rm -f shapes$(EXEEXT)
523594 $(CXXLINK) $(shapes_OBJECTS) $(shapes_LDADD) $(LIBS)
595 trie$(EXEEXT): $(trie_OBJECTS) $(trie_DEPENDENCIES) $(EXTRA_trie_DEPENDENCIES)
596 @rm -f trie$(EXEEXT)
597 $(CXXLINK) $(trie_OBJECTS) $(trie_LDADD) $(LIBS)
598 unicode-test$(EXEEXT): $(unicode_test_OBJECTS) $(unicode_test_DEPENDENCIES) $(EXTRA_unicode_test_DEPENDENCIES)
599 @rm -f unicode-test$(EXEEXT)
600 $(CXXLINK) $(unicode_test_OBJECTS) $(unicode_test_LDADD) $(LIBS)
524601
525602 mostlyclean-compile:
526603 -rm -f *.$(OBJEXT)
528605 distclean-compile:
529606 -rm -f *.tab.c
530607
608 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/containers.Po@am__quote@
531609 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cookies.Po@am__quote@
532610 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dw_anchors_test.Po@am__quote@
533611 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dw_border_test.Po@am__quote@
544622 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dw_table.Po@am__quote@
545623 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dw_table_aligned.Po@am__quote@
546624 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dw_ui_test.Po@am__quote@
547 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fltk_browser.Po@am__quote@
548625 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/form.Po@am__quote@
626 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liang.Po@am__quote@
627 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/notsosimplevector.Po@am__quote@
549628 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/shapes.Po@am__quote@
629 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trie.Po@am__quote@
630 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unicode_test.Po@am__quote@
550631
551632 .c.o:
552633 @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
672753
673754 installcheck: installcheck-am
674755 install-strip:
675 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
676 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
677 `test -z '$(STRIP)' || \
678 echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
756 if test -z '$(STRIP)'; then \
757 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
758 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
759 install; \
760 else \
761 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
762 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
763 "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
764 fi
679765 mostlyclean-generic:
680766
681767 clean-generic:
0 #include "../lout/object.hh"
1 #include "../lout/container.hh"
2
3 using namespace lout::object;
4 using namespace lout::container::typed;
5
6 void testHashSet ()
7 {
8 puts ("--- testHashSet ---");
9
10 HashSet<String> h(true);
11
12 h.put (new String ("one"));
13 h.put (new String ("two"));
14 h.put (new String ("three"));
15
16 puts (h.toString());
17 }
18
19 void testHashTable ()
20 {
21 puts ("--- testHashTable ---");
22
23 HashTable<String, Integer> h(true, true);
24
25 h.put (new String ("one"), new Integer (1));
26 h.put (new String ("two"), new Integer (2));
27 h.put (new String ("three"), new Integer (3));
28
29 puts (h.toString());
30
31 h.put (new String ("one"), new Integer (4));
32 h.put (new String ("two"), new Integer (5));
33 h.put (new String ("three"), new Integer (6));
34
35 puts (h.toString());
36 }
37
38 void testVector1 ()
39 {
40 puts ("--- testVector (1) ---");
41
42 Vector<String> v (true, 1);
43
44 v.put (new String ("one"));
45 v.put (new String ("two"));
46 v.put (new String ("three"));
47 puts (v.toString());
48
49 v.sort ();
50 puts (v.toString());
51 }
52
53 void testVector2 ()
54 {
55 puts ("--- testVector (2) ---");
56
57 Vector<String> v (true, 1);
58
59 v.insertSorted (new String ("one"));
60 puts (v.toString());
61
62 v.insertSorted (new String ("two"));
63 puts (v.toString());
64
65 v.insertSorted (new String ("three"));
66 puts (v.toString());
67
68 v.insertSorted (new String ("five"));
69 puts (v.toString());
70
71 v.insertSorted (new String ("six"));
72 puts (v.toString());
73
74 v.insertSorted (new String ("four"));
75 puts (v.toString());
76
77 for (int b = 0; b < 2; b++) {
78 bool mustExist = b;
79 printf ("mustExist = %s\n", mustExist ? "true" : "false");
80
81 String k ("alpha");
82 printf (" '%s' -> %d\n", k.chars(), v.bsearch (&k, mustExist));
83
84 for (Iterator<String> it = v.iterator(); it.hasNext(); ) {
85 String *k1 = it.getNext();
86 printf (" '%s' -> %d\n", k1->chars(), v.bsearch (k1, mustExist));
87
88 char buf[64];
89 strcpy (buf, k1->chars());
90 strcat (buf, "-var");
91 String k2 (buf);
92 printf (" '%s' -> %d\n", k2.chars(), v.bsearch (&k2, mustExist));
93 }
94 }
95 }
96
97 int main (int argc, char *argv[])
98 {
99 testHashSet ();
100 testHashTable ();
101 testVector1 ();
102 testVector2 ();
103
104 return 0;
105 }
4343 } D_STMT_END
4444
4545 #define MSG(...) MSG_INNARDS("", __VA_ARGS__)
46 #define MSG_WARN(...) MSG_INNARDS("** WARNING **: ", __VA_ARGS__)
4647 #define MSG_ERR(...) MSG_INNARDS("** ERROR **: ", __VA_ARGS__)
4748
4849
367368 }
368369
369370
370 static int Dpi_connect_socket(const char *server_name, int retry)
371 static int Dpi_connect_socket(const char *server_name)
371372 {
372373 struct sockaddr_in sin;
373 int sock_fd, err, dpi_port, ret=-1;
374 int sock_fd, dpi_port, ret = -1;
374375 char *cmd = NULL;
375376
376377 /* Query dpid for the port number for this server */
389390 if ((sock_fd = Dpi_make_socket_fd()) == -1) {
390391 perror("[dpi::socket]");
391392 } else if (connect(sock_fd, (void*)&sin, sizeof(sin)) == -1) {
392 err = errno;
393 sock_fd = -1;
394393 MSG("[dpi::connect] errno:%d %s\n", errno, dStrerror(errno));
395 if (retry) {
396 switch (err) {
397 case ECONNREFUSED: case EBADF: case ENOTSOCK: case EADDRNOTAVAIL:
398 sock_fd = Dpi_connect_socket(server_name, FALSE);
399 break;
400 }
401 }
402
403 /* send authentication Key (the server closes sock_fd on error) */
394
395 /* send authentication Key (the server closes sock_fd on auth error) */
404396 } else if (!(cmd = a_Dpip_build_cmd("cmd=%s msg=%s", "auth", SharedKey))) {
405397 MSG_ERR("[Dpi_connect_socket] Can't make auth message.\n");
406398 } else if (Dpi_blocking_write(sock_fd, cmd, strlen(cmd)) == -1) {
409401 ret = sock_fd;
410402 }
411403 dFree(cmd);
404 if (sock_fd != -1 && ret == -1) /* can't send cmd? */
405 Dpi_close_fd(sock_fd);
412406
413407 return ret;
414408 }
424418 return ret;
425419 }
426420
427 if ((sock_fd = Dpi_connect_socket(server_name, TRUE)) == -1) {
421 if ((sock_fd = Dpi_connect_socket(server_name)) == -1) {
428422 MSG_ERR("[a_Dpi_send_blocking_cmd] Can't connect to server.\n");
429423 } else if (Dpi_blocking_write(sock_fd, cmd, strlen(cmd)) == -1) {
430424 MSG_ERR("[a_Dpi_send_blocking_cmd] Can't send message.\n");
784778 expect(__LINE__, "Cookie: name=val\r\n", "http", "p6.com", "/dir/subdir/s");
785779 }
786780
781 int Cookies_rc_check()
782 {
783 const int line_maxlen = 4096;
784 FILE *stream;
785 char *filename;
786 char line[line_maxlen];
787 bool_t default_deny = TRUE;
788
789 /* Get a file pointer */
790 filename = dStrconcat(dGethomedir(), "/.dillo/cookiesrc", NULL);
791 stream = fopen(filename, "r");
792 dFree(filename);
793
794 if (!stream) {
795 MSG_ERR("Cannot run test; cannot open cookiesrc.\n");
796 return 1;
797 }
798
799 /* Get all lines in the file */
800 while (!feof(stream)) {
801 char *rc;
802
803 line[0] = '\0';
804 rc = fgets(line, line_maxlen, stream);
805 if (!rc && ferror(stream)) {
806 MSG_ERR("Error while reading rule from cookiesrc: %s\n",
807 dStrerror(errno));
808 fclose(stream);
809 return 2;
810 }
811
812 /* Remove leading and trailing whitespaces */
813 dStrstrip(line);
814
815 if (line[0] != '\0' && line[0] != '#') {
816 int domain_end, i = 0;
817 const char *rule;
818
819 /* Get the domain */
820 while (line[i] != '\0' && !dIsspace(line[i]))
821 i++;
822 domain_end = i;
823
824 /* Skip past whitespace */
825 while (dIsspace(line[i]))
826 i++;
827 line[domain_end] = '\0';
828
829 /* Get the rule */
830 rule = line + i;
831 while (line[i] != '\0' && !dIsspace(line[i]))
832 i++;
833 line[i] = '\0';
834
835 if (!dStrAsciiCasecmp(line, "DEFAULT")) {
836 if (!dStrAsciiCasecmp(rule, "ACCEPT") ||
837 !dStrAsciiCasecmp(rule, "ACCEPT_SESSION"))
838 default_deny = FALSE;
839 } else {
840 if (!dStrAsciiCasecmp(rule, "DENY"))
841 MSG_WARN("DENY rules in cookiesrc can interfere with test.\n");
842 }
843 }
844 }
845 fclose(stream);
846
847 if (default_deny) {
848 MSG_ERR("Cannot run test with cookiesrc default of deny.\n");
849 return 1;
850 } else {
851 return 0;
852 }
853 }
854
787855 int main()
788856 {
857 if (Cookies_rc_check()) {
858 MSG("If you change cookiesrc, remember to stop the DPIs via dpidc.\n");
859 return 1;
860 }
861
789862 a_Cookies_set("name=val", "ordinary.com", "/", NULL);
790863 expect(__LINE__, "Cookie: name=val\r\n", "http", "ordinary.com", "/");
791864
9651038 #endif
9661039
9671040 MSG("TESTS: passed: %u failed: %u\n", passed, failed);
1041
1042 MSG("Now that everything is full of fake cookies, you should run "
1043 "'dpidc stop', plus delete cookies.txt if necessary.\n");
1044
9681045 return 0;
9691046 }
129129 styleAttrs.margin.setVal (5);
130130 styleAttrs.color = Color::create (layout, 0x000000);
131131 styleAttrs.backgroundColor = Color::create (layout, 0xffffff);
132 topWidgetStyle = Style::create (layout, &styleAttrs);
132 topWidgetStyle = Style::create (&styleAttrs);
133133
134134 styleAttrs.margin.left = 20;
135135 styleAttrs.margin.right = 0;
136136 styleAttrs.backgroundColor = NULL;
137 widgetStyle = Style::create (layout, &styleAttrs);
137 widgetStyle = Style::create (&styleAttrs);
138138
139139 styleAttrs.margin.left = 0;
140 wordStyle = Style::create (layout, &styleAttrs);
140 wordStyle = Style::create (&styleAttrs);
141141
142142 fontAttrs.size = 28;
143143 fontAttrs.weight = 700;
144144 styleAttrs.font = dw::core::style::Font::create (layout, &fontAttrs);
145 headingStyle = Style::create (layout, &styleAttrs);
145 headingStyle = Style::create (&styleAttrs);
146146
147147 Fl::add_timeout (0, textTimeout, NULL);
148148
6464 styleAttrs.color = Color::create (layout, 0x000000);
6565 styleAttrs.backgroundColor = Color::create (layout, 0xffffff);
6666
67 Style *widgetStyle1 = Style::create (layout, &styleAttrs);
67 Style *widgetStyle1 = Style::create (&styleAttrs);
6868
6969 styleAttrs.backgroundColor = Color::create (layout, 0xffff80);
7070 styleAttrs.margin.setVal (0);
7373 styleAttrs.setBorderStyle (BORDER_SOLID);
7474 styleAttrs.padding.setVal (1);
7575
76 Style *widgetStyle2 = Style::create (layout, &styleAttrs);
76 Style *widgetStyle2 = Style::create (&styleAttrs);
7777
7878 Textblock *textblock1 = new Textblock (false);
7979 textblock1->setStyle (widgetStyle1);
8686 styleAttrs.backgroundColor = NULL;
8787 styleAttrs.cursor = CURSOR_TEXT;
8888
89 Style *wordStyle = Style::create (layout, &styleAttrs);
89 Style *wordStyle = Style::create (&styleAttrs);
9090
9191 const char *words1[] = { "Some", "random", "text.", NULL };
9292 const char *words2[] = { "A", "nested", "paragraph.", NULL };
5959 dw::core::style::Color::create (layout, 0xffffff);
6060
6161 dw::core::style::Style *widgetStyle =
62 dw::core::style::Style::create (layout, &styleAttrs);
62 dw::core::style::Style::create (&styleAttrs);
6363
6464 dw::Textblock *textblock = new dw::Textblock (false);
6565 textblock->setStyle (widgetStyle);
7171 styleAttrs.backgroundColor = NULL;
7272
7373 dw::core::style::Style *wordStyle =
74 dw::core::style::Style::create (layout, &styleAttrs);
74 dw::core::style::Style::create (&styleAttrs);
7575
7676 for(int i = 1; i <= 10; i++) {
7777 char buf[4];
106106 styleAttrs.margin.setVal (10);
107107 styleAttrs.color = Color::create (layout, 0x000000);
108108 styleAttrs.backgroundColor = Color::create (layout, 0xffffff);
109 Style *topWidgetStyle = Style::create (layout, &styleAttrs);
109 Style *topWidgetStyle = Style::create (&styleAttrs);
110110
111111 styleAttrs.margin.setVal (0);
112112 styleAttrs.margin.left = 30;
113113 styleAttrs.backgroundColor = NULL;
114 Style *widgetStyle = Style::create (layout, &styleAttrs);
114 Style *widgetStyle = Style::create (&styleAttrs);
115115
116116 styleAttrs.margin.left = 0;
117 Style *wordStyle = Style::create (layout, &styleAttrs);
117 Style *wordStyle = Style::create (&styleAttrs);
118118
119119 Textblock *textblock = new Textblock (false);
120120 textblock->setStyle (topWidgetStyle);
119119 styleAttrs.color = Color::create (layout, 0x000000);
120120 styleAttrs.backgroundColor = Color::create (layout, 0xffffff);
121121
122 Style *widgetStyle = Style::create (layout, &styleAttrs);
122 Style *widgetStyle = Style::create (&styleAttrs);
123123
124124 Textblock *textblock = new Textblock (false);
125125 textblock->setStyle (widgetStyle);
130130 styleAttrs.margin.setVal (0);
131131 styleAttrs.backgroundColor = NULL;
132132
133 Style *imageStyle = Style::create (layout, &styleAttrs);
133 Style *imageStyle = Style::create (&styleAttrs);
134134
135135 image = new dw::Image ("");
136136 textblock->addWidget (image, imageStyle);
9494 styleAttrs.color = Color::create (layout, 0x000000);
9595 styleAttrs.backgroundColor = Color::create (layout, 0xffffff);
9696
97 Style *widgetStyle = Style::create (layout, &styleAttrs);
97 Style *widgetStyle = Style::create (&styleAttrs);
9898
9999 Textblock *textblock = new Textblock (false);
100100 textblock->setStyle (widgetStyle);
107107 styleAttrs.padding.setVal (0);
108108 styleAttrs.backgroundColor = NULL;
109109
110 Style *wordStyle = Style::create (layout, &styleAttrs);
110 Style *wordStyle = Style::create (&styleAttrs);
111111
112112 styleAttrs.borderWidth.setVal (1);
113113 styleAttrs.setBorderColor (Color::create (layout, 0x000080));
117117 styleAttrs.width = createPerLength (0.25);
118118 styleAttrs.height = createPerLength (0.25);
119119
120 Style *imageStyle1 = Style::create (layout, &styleAttrs);
120 Style *imageStyle1 = Style::create (&styleAttrs);
121121 image1 = new dw::Image ("A longer ALT Text to demonstrate clipping.");
122122 textblock->addWidget (image1, imageStyle1);
123123 imageStyle1->unref();
127127 styleAttrs.width = LENGTH_AUTO;
128128 styleAttrs.height = LENGTH_AUTO;
129129
130 Style *imageStyle2 = Style::create (layout, &styleAttrs);
130 Style *imageStyle2 = Style::create (&styleAttrs);
131131 image2 = new dw::Image ("A longer ALT Text to demonstrate clipping.");
132132 textblock->addWidget (image2, imageStyle2);
133133 imageStyle2->unref();
118118 styleAttrs.color = Color::create (layout, 0x000000);
119119 styleAttrs.backgroundColor = Color::create (layout, 0xffffff);
120120
121 Style *widgetStyle = Style::create (layout, &styleAttrs);
121 Style *widgetStyle = Style::create (&styleAttrs);
122122
123123 Textblock *textblock = new Textblock (false);
124124 textblock->setStyle (widgetStyle);
129129 styleAttrs.margin.setVal (0);
130130 styleAttrs.backgroundColor = NULL;
131131
132 Style *imageStyle = Style::create (layout, &styleAttrs);
132 Style *imageStyle = Style::create (&styleAttrs);
133133
134134 image = new dw::Image ("");
135135 textblock->addWidget (image, imageStyle);
9898 styleAttrs.color = Color::create (layout, 0x000000);
9999 styleAttrs.backgroundColor = Color::create (layout, 0xffffff);
100100
101 Style *widgetStyle = Style::create (layout, &styleAttrs);
101 Style *widgetStyle = Style::create (&styleAttrs);
102102
103103 Textblock *textblock = new Textblock (false);
104104 textblock->setStyle (widgetStyle);
112112 styleAttrs.backgroundColor = NULL;
113113 styleAttrs.cursor = CURSOR_TEXT;
114114
115 Style *wordStyle = Style::create (layout, &styleAttrs);
115 Style *wordStyle = Style::create (&styleAttrs);
116116
117117 styleAttrs.color = Color::create (layout, 0x0000ff);
118118 styleAttrs.textDecoration = TEXT_DECORATION_UNDERLINE;
136136 }
137137
138138 styleAttrs.x_link = i;
139 Style *linkStyle = Style::create (layout, &styleAttrs);
139 Style *linkStyle = Style::create (&styleAttrs);
140140
141141 for(int j = 0; words2[j]; j++) {
142142 textblock->addText(words2[j], linkStyle);
127127 styleAttrs.color = Color::create (layout, 0x000000);
128128 styleAttrs.backgroundColor = Color::create (layout, 0xffffff);
129129
130 Style *widgetStyle = Style::create (layout, &styleAttrs);
130 Style *widgetStyle = Style::create (&styleAttrs);
131131
132132 Textblock *textblock = new Textblock (false);
133133 textblock->setStyle (widgetStyle);
141141 styleAttrs.backgroundColor = NULL;
142142 styleAttrs.cursor = CURSOR_TEXT;
143143
144 Style *wordStyle = Style::create (layout, &styleAttrs);
144 Style *wordStyle = Style::create (&styleAttrs);
145145
146146 styleAttrs.color = Color::create (layout, 0x0000ff);
147147 styleAttrs.textDecoration = TEXT_DECORATION_UNDERLINE;
165165 }
166166
167167 styleAttrs.x_link = i;
168 Style *linkStyle = Style::create (layout, &styleAttrs);
168 Style *linkStyle = Style::create (&styleAttrs);
169169
170170 for(int j = 0; words2[j]; j++) {
171171 textblock->addText (words2[j], linkStyle);
6060 styleAttrs.color = Color::create (layout, 0x000000);
6161 styleAttrs.backgroundColor = Color::create (layout, 0xffffff);
6262
63 Style *widgetStyle = Style::create (layout, &styleAttrs);
63 Style *widgetStyle = Style::create (&styleAttrs);
6464
6565 Textblock *textblock = new Textblock (false);
6666 textblock->setStyle (widgetStyle);
7272 styleAttrs.backgroundColor = NULL;
7373 styleAttrs.cursor = CURSOR_TEXT;
7474
75 Style *wordStyle = Style::create (layout, &styleAttrs);
75 Style *wordStyle = Style::create (&styleAttrs);
7676
7777 styleAttrs.margin.setVal (5);
7878 styleAttrs.padding.setVal (5);
8181 styleAttrs.setBorderStyle (BORDER_SOLID);
8282 styleAttrs.borderWidth.setVal (1);
8383
84 Style *itemStyle = Style::create (layout, &styleAttrs);
84 Style *itemStyle = Style::create (&styleAttrs);
8585
8686 const char *wordsPar[] = {
8787 "This", "is", "a", "normal", "paragraph.", "And",
6161 styleAttrs.color = Color::create (layout, 0x000000);
6262 styleAttrs.backgroundColor = Color::create (layout, 0xffffff);
6363
64 Style *widgetStyle = Style::create (layout, &styleAttrs);
64 Style *widgetStyle = Style::create (&styleAttrs);
6565
6666 Textblock *textblock = new Textblock (false);
6767 textblock->setStyle (widgetStyle);
7272 styleAttrs.margin.setVal (0);
7373 styleAttrs.backgroundColor = NULL;
7474
75 widgetStyle = Style::create (layout, &styleAttrs);
75 widgetStyle = Style::create (&styleAttrs);
7676
7777 SelectionResource *res = layout->getResourceFactory()->createListResource
7878 (ListResource::SELECTION_AT_MOST_ONE, 4);
6565 fontAttrs.fontVariant = FONT_VARIANT_NORMAL;
6666 styleAttrs.font = dw::core::style::Font::create (layout, &fontAttrs);
6767
68 Style *tableStyle = Style::create (layout, &styleAttrs);
68 Style *tableStyle = Style::create (&styleAttrs);
6969
7070 Table *table = new Table (false);
7171 table->setStyle (tableStyle);
7878 styleAttrs.margin.setVal (0);
7979 styleAttrs.padding.setVal (5);
8080
81 Style *cellStyle = Style::create (layout, &styleAttrs);
81 Style *cellStyle = Style::create (&styleAttrs);
8282
8383 styleAttrs.borderWidth.setVal (0);
8484 styleAttrs.margin.setVal (0);
8585 styleAttrs.cursor = CURSOR_TEXT;
8686 styleAttrs.textAlignChar = '.';
8787
88 Style *wordStyle = Style::create (layout, &styleAttrs);
88 Style *wordStyle = Style::create (&styleAttrs);
8989
9090 for (int i = 0; i < 4; i++) {
9191 table->addRow (wordStyle);
6565 styleAttrs.hBorderSpacing = 5;
6666 styleAttrs.vBorderSpacing = 5;
6767
68 Style *tableStyle = Style::create (layout, &styleAttrs);
68 Style *tableStyle = Style::create (&styleAttrs);
6969
7070 Table *table = new Table (false);
7171 table->setStyle (tableStyle);
7676 styleAttrs.borderWidth.setVal (1);
7777 styleAttrs.setBorderStyle (BORDER_INSET);
7878
79 Style *cellStyle = Style::create (layout, &styleAttrs);
79 Style *cellStyle = Style::create (&styleAttrs);
8080
8181 styleAttrs.borderWidth.setVal (0);
8282 styleAttrs.margin.setVal (0);
8484 styleAttrs.cursor = CURSOR_TEXT;
8585 styleAttrs.textAlignChar = '.';
8686
87 Style *wordStyle = Style::create (layout, &styleAttrs);
87 Style *wordStyle = Style::create (&styleAttrs);
8888
8989 TableCell *ref = NULL;
9090 for(int i = 0; i < 10; i++) {
6464 fontAttrs.fontVariant = FONT_VARIANT_NORMAL;
6565 styleAttrs.font = dw::core::style::Font::create (layout, &fontAttrs);
6666
67 Style *tableStyle = Style::create (layout, &styleAttrs);
67 Style *tableStyle = Style::create (&styleAttrs);
6868
6969 Table *table = new Table (false);
7070 table->setStyle (tableStyle);
7575 styleAttrs.backgroundColor = NULL;
7676 styleAttrs.margin.setVal (0);
7777
78 Style *cellStyle = Style::create (layout, &styleAttrs);
78 Style *cellStyle = Style::create (&styleAttrs);
7979
8080 // First of all, the resources. Later, they are embedded into the
8181 // widget tree.
+0
-43
test/fltk_browser.cc less more
0 /*
1 * Dillo Widget
2 *
3 * Copyright 2005-2007 Sebastian Geerken <sgeerken@dillo.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19
20
21 #include <FL/Fl_Window.H>
22 #include <FL/Fl_Multi_Browser.H>
23 #include <FL/Fl.H>
24
25 int main (int argc, char *argv[])
26 {
27 Fl_Window *window = new Fl_Window (300, 300, "FLTK Browser");
28 window->box(FL_NO_BOX);
29 window->begin ();
30 Fl_Multi_Browser *browser = new Fl_Multi_Browser (0, 0, 300, 300);
31 browser->begin ();
32
33 for (int i = 0; i < 10; i++) {
34 browser->add("first");
35 browser->add("second");
36 browser->add("third");
37 }
38
39 window->resizable(browser);
40 window->show();
41 return Fl::run();
42 }
0
1 #include "../dw/fltkcore.hh"
2 #include "../dw/hyphenator.hh"
3
4 void hyphenateWord (dw::core::Platform *p, const char *word)
5 {
6 dw::Hyphenator *h = dw::Hyphenator::getHyphenator ("de");
7
8 int numBreaks;
9 int *breakPos = h->hyphenateWord (p, word, &numBreaks);
10 for (int i = 0; i < numBreaks + 1; i++) {
11 if (i != 0)
12 printf (" \xc2\xad ");
13 int start = (i == 0 ? 0 : breakPos[i - 1]);
14 int end = (i == numBreaks ? strlen (word) : breakPos[i]);
15 for (int j = start; j < end; j++)
16 putchar (word[j]);
17 }
18 putchar ('\n');
19 if (breakPos)
20 free (breakPos);
21 }
22
23 int main (int argc, char *argv[])
24 {
25 dw::fltk::FltkPlatform p;
26
27 hyphenateWord (&p, "...");
28 hyphenateWord (&p, "Jahrhundertroman");
29 hyphenateWord (&p, "JAHRHUNDERTROMAN");
30 hyphenateWord (&p, "„Jahrhundertroman“");
31 hyphenateWord (&p, "währenddessen");
32 hyphenateWord (&p, "„währenddessen“");
33 hyphenateWord (&p, "Ückendorf");
34 hyphenateWord (&p, "über");
35 hyphenateWord (&p, "aber");
36 hyphenateWord (&p, "Ackermann");
37 hyphenateWord (&p, "„Ackermann“");
38 hyphenateWord (&p, "entscheidet.");
39 hyphenateWord (&p, "Grundstücksverkehrsgenehmigungszuständigkeits"
40 "übertragungsverordnung");
41 hyphenateWord (&p, "„Grundstücksverkehrsgenehmigungszuständigkeits"
42 "übertragungsverordnung“");
43 hyphenateWord (&p, "Grundstücksverkehrsgenehmigungszuständigkeit");
44 hyphenateWord (&p, "„Grundstücksverkehrsgenehmigungszuständigkeit“");
45 hyphenateWord (&p, "(6R,7R)-7-[2-(2-Amino-4-thiazolyl)-glyoxylamido]-3-"
46 "(2,5-dihydro-6-hydroxy-2-methyl-5-oxo-1,2,4-triazin-3-yl-"
47 "thiomethyl)-8-oxo-5-thia-1-azabicyclo[4.2.0]oct-2-en-2-"
48 "carbonsäure-7²-(Z)-(O-methyloxim)");
49 hyphenateWord (&p, "Abtei-Stadt");
50 hyphenateWord (&p, "Nordrhein-Westfalen");
51 hyphenateWord (&p, "kurz\xc2\xa0und\xc2\xa0knapp");
52 hyphenateWord (&p, "weiß");
53 hyphenateWord (&p, "www.dillo.org");
54
55 return 0;
56 }
0 #include "../lout/misc.hh"
1
2 static void print (lout::misc::NotSoSimpleVector<int> *v)
3 {
4 for (int i = 0; i < v->size(); i++) {
5 // Uncomment for debugging, after making the respective members public.
6 //if (v->startExtra != -1 && i == v->startExtra + v->numExtra)
7 // printf (" ]");
8 if (i > 0)
9 printf (", ");
10 //if (i == v->startExtra)
11 // printf ("[ ");
12
13 printf ("%d", v->get(i));
14 }
15
16 printf (" (%d elements)\n", v->size ());
17 }
18
19 int main (int argc, char *argv[])
20 {
21 lout::misc::NotSoSimpleVector<int> v(1);
22
23 for (int i = 1; i <= 10; i++) {
24 v.increase ();
25 v.set(v.size () - 1, i);
26 }
27
28 print (&v);
29
30 v.insert (2, 4);
31 for (int i = 0; i < 5; i++)
32 v.set (2 + i, 31 + i);
33
34 print (&v);
35
36 v.insert (8, 4);
37 for (int i = 0; i < 5; i++)
38 v.set (8 + i, 51 + i);
39
40 print (&v);
41
42 v.insert (10, 4);
43 for (int i = 0; i < 5; i++)
44 v.set (10 + i, 531 + i);
45
46 print (&v);
47
48 v.insert (1, 4);
49 for (int i = 0; i < 5; i++)
50 v.set (1 + i, 21 + i);
51
52 print (&v);
53
54 int n = v.size ();
55 v.insert (n, 5);
56 for (int i = 0; i < 5; i++)
57 v.set (n + i, 101 + i);
58
59 print (&v);
60
61 return 0;
62 }
0 #include "../dw/hyphenator.hh"
1
2 int main (int argc, char *argv[])
3 {
4 if (argc < 2) {
5 fprintf(stderr, "Usage: trie <pattern file>\n");
6 exit (1);
7 }
8
9 /* Use pack = 1024 to create a really small trie - can take a while.
10 */
11 dw::Hyphenator hyphenator (argv[1], NULL, 1024);
12 hyphenator.saveTrie (stdout);
13 }
0 #include <string.h>
1 #include <stdio.h>
2 #include <FL/fl_utf8.h>
3 #include "../lout/unicode.hh"
4
5 using namespace lout::unicode;
6
7 int main (int argc, char *argv[])
8 {
9 // 0-terminated string
10 const char *t1 = "abcäöüабв−‐";
11
12 // not 0-terminated; copy from 0-terminated
13 int t2len = strlen (t1);
14 char t2[t2len];
15 for (int i = 0; i < t2len; i++)
16 t2[i] = t1[i];
17
18 puts ("===== misc::unicode, 0-terminated =====");
19 for (const char *s = t1; s; s = nextUtf8Char (s))
20 printf ("%3d -> U+%04x ('%s')\n", (int)(s - t1), decodeUtf8(s), s);
21
22 puts ("===== Fltk, 0-terminated =====");
23 for (const char *s = t1; *s; s = fl_utf8fwd (s + 1, t1, t1 + strlen (t1)))
24 printf ("%3d -> U+%04x ('%s')\n", (int)(s - t1), decodeUtf8(s), s);
25
26 puts ("===== misc::unicode, not 0-terminated =====");
27 for (const char *s = t2; s; s = nextUtf8Char (s, t2len - (s - t2)))
28 printf ("%3d -> U+%04x\n", (int)(s - t2),
29 decodeUtf8(s, t2len - (s - t2)));
30
31 puts ("===== Fltk, not 0-terminated =====");
32 for (const char *s = t2; *s;
33 s - t2 < t2len && (s = fl_utf8fwd (s + 1, t2, t2 + t2len)))
34 printf ("%3d -> U+%04x\n", (int)(s - t2),
35 decodeUtf8(s, t2len - (s - t2)));
36
37 return 0;
38 }