Mercurial > dillo_port1.3
changeset 0:6ee11bf9e3ea
Initial revision
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/AUTHORS Sun Oct 07 00:36:34 2007 +0200 @@ -0,0 +1,68 @@ + + _________________________________________________________________ + + Dillo project's team + _________________________________________________________________ + + Project maintainer: + * Jorge Arellano Cid + + Core Developers: + * Jorge Arellano Cid + * Sebastian Geerken + + Steady developers: + * Livio Baldini + * Eric Gaudet + * Jörgen Viksell + + Contributors: + * Lars Clausen + * Geoff Lane + * Sammy Mannaert + * James McCollough + + Patches: + * Philip Blundell + * Francis Daly + * Sam Dennis + * Melvin Hadasht + * Madis Janson + * Andrew McPherson + * Sean 'Shaleh' Perry + * Marcos Ramírez + * Adam Sampson + * Andreas Schweitzer + * Dominic Wong + _________________________________________________________________ + + Web site logo: + * Eric Gaudet + * Jarrod Henry + + Gzilla author: + * Raph Levien + _________________________________________________________________ + + + + +------------------- +Up to gzilla-0.1.7: +------------------- + +Raph Levien <raph@acm.org> is the author of gzilla. + +Christoph Thompson <obituary@freshmeat.net> and Tomas O"gren <stric@ing.umu.se> + added pixmaps for the buttons and the code encessary to make them work. + They also reorganized the source tree and gave general advice and tips. + (Tomas will be pleased to find that my personal bookmarks file is no longer + hard-coded into Gzilla. :)) + +Ian Main <slow@intergate.bc.ca> did the bookmarks. + +Thanks to Otto Hammersmith, David Mosberger-Tang, and Peter Mattis for +patches. + +Contributions are always welcome! +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/COPYING Sun Oct 07 00:36:34 2007 +0200 @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + <program> Copyright (C) <year> <name of author> + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +<http://www.gnu.org/licenses/>. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +<http://www.gnu.org/philosophy/why-not-lgpl.html>.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ChangeLog Sun Oct 07 00:36:34 2007 +0200 @@ -0,0 +1,1416 @@ +============================================================================= +Dillo project +============================================================================= + +dillo-fltk2 + + - Ported Dillo from GTK1 to FLTK2. + - Ported a susbstantial part of the code from C to C++ (FLTK2 is in C++). + - Wrote a new library: Dlib. With "Dlib" Dillo doesn't need glib anymore. + - Ported all the code to Dlib. + - Fixed Http_must_use_proxy() to be case insensitive. + - Fixed some leaks and bugs in the cookies dpi. + - Made Dillo's UI Control Panel resizable on-the-fly. + - Implemented a new, simpler, dillorc parser. + - Added handling of "localhost" in file URIs. + - Fix: recognize "http://foo" and "http://foo/" as the same URL (BUG#497). + - Reimplemented the Concomitant Callback chains into a uniform scheme! + (two query branches and a single answer branch). It simplifies a lot the + former CCC paths and allows for easier error control. + - Added a new method for internally-generated urls: a_Cache_entry_inject(). + - Switched the cache to use Dlib's Dstr for its data storage. + - Removed threads from IO. Now it only uses select-based watches. + - Reimplemented IO.c and dpi.c to use Dlib's Dstr as its main buffer. + - Turned Klist into a sorted list. + - Removed one data-copy stage in Html_write_raw(). + - Switched gcc's "fmt..." syntax to ISO C __VA_ARGS__. + - Fixed Dillo and its dpis to work from "/tmp" (for easy device unmount). + - Simplified http.c by reusing the new non-blocking writes in IO. + - Reworked the capi API so cache is only accessable from capi. + - Rewrote the CCC's OpAbort handling. + - Rewrote the DNS API and the Dpid start code inside Dillo. + - Implemented Stop button to not only stop rendering but also networking. + Patches: Jorge Arellano + + + TODO: + + - test no_proxy (set a list in dillorc). + +----------------------------------------------------------------------------- + + +0.8.5-pre-dw-redesign-1 [internal] +- Prototype + +dillo-0.8.3-pre-dw-redesign-3 [Aug 30, 2004] + - * Fixed bug GtkDwViewport, which caused some redraws to be ignored. + * Added GdkDwPreview. + Patches: Sebastian Geerken + + +dillo-0.8.3-pre-dw-redesign-2 [Aug 28, 2004] + - * Added images to the current state of the redesign. + - New module Imgbuf, see doc/Imgbuf.txt for details. + Patch: Sebastian Geerken + + +dillo-0.8.3-pre-dw-redesign-1 [Aug 25, 2004] + - * Introduced an abstraction layer between Dw and Gtk+. See README-port and + doc/DwRender.txt for more details. + Patch: Sebastian Geerken + + +============================================================================= +Dillo project +============================================================================= + + +dillo-0.8.6 [Apr 26, 2006] + + - * Designed and implemented a dpi protocol library (libDpip.a in /dpip). + * Added a couple of new dpip commands. + * Fixed and uniformed the escaping of values inside dpip tags. + * Ported the bookmarks, download, file, https, ftp and hello plugins, + plus the dpid daemon and the rest of the source tree to use it. + * Improved the dpi buffer reception to handle split buffers (This was + required for handling arbitrary data streams with dpip). + * Fixed a bug in Cache_entry_remove_raw. + * Added a couple of "const" and C++ wrappers to dpiutil's API. + * Fixed a serious bug with the FTP plugin that led to two downloads of the + same file when left-clicking a non-viewable file. + * Added MIME/type detection to the FTP plugin, and removed popen(). + * Set the dpi daemon (dpid) not to exit when the downloads dpi is running. + * Improved the accuracy of the illegal-character error reporting for URLs. + * Now save dialog replaces %20 and ' ' with '_' in the Filename suggestion. + * Made URL ADT automatically count and strip illegal characters from URLs. + * Added dpi/downloads.cc (Default FLTK2-based GUI for downloads dpi). + * Added "./configure --disable-dlgui" to build without FLTK2-GUI downloads. + * Fixed dpip's tag syntax and its parsing to accept any value string. + * Added DOCTYPE parsing (for better bug-meter error messages). + * Added a DOCTYPE type declaration tag to dpi-generated HTML. + * Fixed bookmarks dpi to escape ' in URLs and &<>"' in titles (BUG#655). + * Added a check for malicious image sizes in IMG tags. + * Made the parser aware of buggy pages with multiple BODY and HTML elements. + * Fixed a bug in MIME content/type detection. + * Check HTTP Content-Type against real data (a security procedure). + Patches: Jorge Arellano + - * Added a datauri dpi to handle "data:" URIs (RFC-2397). + Patch: Jorge Arellano, Ben Wiley Sittler + - * Moved the cookies management into a dpi server: cookies.dpi. + * Removed the restriction of only one dillo with cookies enabled! + * Fixed a bug with cookies for sites with self-signed certificate. + * Updated the cookies documentation. + * Made the downloads plugin dillo-cookie aware. + * Ported the cookies dpi to libDpip.a. + * Merged the new dpip code into the source tree. + Patches: Diego Sáenz, Jorge Arellano + - * Added "./configure --disable-threaded-dns" (for some non reentrant BSDs). + Patch: Jorge Arellano, Francis Daly + - * Fixed a bug with roman literals divisible by 10 (BUG#700). + * Fixed a bug with long alphabetically ordered lists (BUG#704). + Patch: Glyn Kennington + - * Fixed a file descriptor leak in the dpi protocol library. + * Fixed a subtle segfault bug with malformed URLs in cookies.c. + Patch: Francis Daly + + +dillo-0.8.5 [Jun 15, 2005] + + - * Set "file:" to work as URI for current directory. + Patch: Diego Sáenz + - * Added a "small" dillorc option for panel size (medium without labels). + Patch: Eugeniy, Jorge Arellano + - * Fixed the shell escaping code in the ftp plugin. + * Added some checks for sane values in html.c. + * Added URL filtering to the ftp and downloads dpis to avoid SMTP hacks. + * Fixed the file dpi to react to the DpiBye command. + Patches: Jorge Arellano + + +dillo-0.8.4 [Jan 11, 2005] + + - * Fixed a possible attack (program abortion) by malicious web pages, which + contain huge values for <table> attributes "colspan" and "rowspan". + * Changed anchors, they are now tested to be unique, and removed properly, + when a widget tree is changed (e.g. another page is visited). Also added + HTML warnings. + Patches: Sebastian Geerken + - * Fixed two minor memory leaks (IO's Buf1Start & html's SPCBuf). + * Fixed handling of XML's "/>" tag-closing (e.g. <script ... />). BUG#514 + * Removed obsolete code from IO/file.c. + * Added a few missing EINTR handlers in dpi.c. + * Orthogonalized the generic parser: + - Fixes memory leaks and widget state when recovering from bad HTML. + - Improves error detection and validation (needed by XHTML). + - Makes DOC tree generation possible (needed by CSS). + - Cleaner design of handling routines for bad HTML. + - Orthodox treatment of double optional elements (HTML, HEAD, BODY). + - Lots of minor code cleanups. + * Switched the dpi file server's design to pthreads (fixes a critical race). + * Avoided a crash when indexed GIF images lack a color map (BUG#647). + * Fixed a bug when the remote HTTP server sends no Content-Type and + the TCP packetizing splits the header from data (BUG#650). + * Returned the parser to the old whitespace "collapsing" mode + (this can be changed with the SGML_SPCDEL define in html.c). + * Fixed a memory leak for DwStyle (there was one leak per page). + Patches: Jorge Arellano + - * Fixed a large memory leak of thread specific resources. --Very important + Patch: Jorge Arellano, Livio Baldini + - * Removed warnings for pointer arithmetic and strict prototypes all + around the code (now it works under LP64 architectures). + * Made miscelaneous cleanups for LP64 architectures. + Patches: Jorge Arellano, Dieter Baron + - * Changed dpid's umask to 0077. + Patch: Jorge Arellano, Richard Zidlicky + - * Switched to g_vsnprintf (instead of vsnprintf). + Patch: Frank Wille + - * Updated a bit the README file. + Patch: Dieter Baron + - * Made a grammatical and typographical review of the whole documentation + in doc/. Also added some clarifications. + * Fixed a libpng detection problem (e.g., on CYGWIN). BUG#651 + Patches: Roberto Sanchez + - * Fixed "id" and "name" attributes parsing logic. + * Improved the parsing algorithm for character entities. BUG#605 + Patches: Matthias Franz + - * Fixed a security bug with uncertain data and a_Interface_msg(). + CAN-2005-0012. + Patch: Tavis Ormandy + + +dillo-0.8.3 [Oct 27, 2004] + + - * Added a missing error handler for unreachable host in http.c. + Patch: Dennis Schneider, Jorge Arellano + - * Added fragment (aka anchor) decoding before it is set by Dw. + Patch: Matthias Franz, Jorge Arellano + - * Fixed dpid to work even when a dpi directory is empty. + Patch: George Georgiev, Jorge Arellano + - * Made the search dialog's URL go encoded in the query. + Patch: Matthias Franz + - * Fixed the width of sized text entry widgets within FORMS. + Patch: Thorben Thuermer + -(*)Made a library-based https dpi prototype, with certificate authentication! + * Separated the code in dpi/ so the common base now lies in dpiutil.c. + Patches: Garrett Kajmowicz + - * Added SSL library detection code to configure.in. + Patch: Garrett Kajmowicz, Thomas-Martin Seck + - * Fixed the wrong image-URL after cancelling a link-image popup (BUG#580). + * Improved the transfer speed for the bookmarks dpi when using 2.6.x linux. + * Fixed the downloads dpi to work when there're "'" characters in the URL. + * Fixed " and ' characters stuffing in capi and interface for dpip commands. + (*)Added a "dialog" command to the dpi protocol (dpip). It allows any dpi to + make GUI choice-questions trough Dillo by using simple dpi tags. + * Merged some dialog-generating code in interface.c and fixed a bug with + the FORM repost dialog. + * Designed and implemented a unified API for handling data streams inside + dillo plugins. Servers and filters can use it. + * Converted the bookmarks, ftp, file, hello and the https prototype dpis + to the new dpiutil API. + * Replaced the old 'force_visited_color' dillorc option with the new + 'contrast_visited_color' (using a renewed color-choosing algorithm). + * Added some 'undefined ASCII' to latin1 character conversions. + * Added the "w3c_plus_heuristics" option to dillorc. + * Removed a segfault bug on oversized images (rare case). + * Removed a CPU-hog on 302 redirections with cookies. + * Made HTTP's 302 redirections non-cacheable (incomplete). + * Implemented a new scheme for detecting redirection loops. + * Fixed cookies to accept four legacy old-date formats for "Expires". + Patches: Jorge Arellano + - * Introduced a light-weight heuristic algorithm over the W3C parsing + scheme (allows for slightly better rendering: w3c_plus_heuristics=YES). + Patch: Rubén Fernández + - * Moved the internal support for "file:" URIs into a dpi (server plugin). + * Added TABLE-based rendering of directory listings to the new file dpi. + Patches: Jorge Arellano, Jörgen Viksell + - * Removed DwWidget::realize and DwWidget::unrealize. + * Made all signals expect events to abstract methods. + * Renamed a_Dw_widget_{size_request|get_extremes|size_allocate|set_*} to + p_*, they should not be used outside of Dw. + Patches: Sebastian Geerken + - * Fixed the meta refresh warning to not switch from IN_HEAD to IN_BODY. + Patch: Björn Brill + + +dillo-0.8.2 [Jul 06, 2004] + + - * Made PgUp/PgDn scroll by a full page, instead of a half (BUG#418). + * Added new Gtk+ widgets GtkExtButton, GtkExtMenu, and GtkExtMenuItem. + - Used GtkExtButton to enhance the button 3 menu of the forward button, + backward button and bug meter buutton. + - GtkExtMenu and GtkExtMenuItem are used to make handling button 2 + in the history menus cleaner. + * Made bug meter button react on high-level "clicked" signal, instead of + "button-press-event". + * New widget GtkMenuTitle, used for nicer titles in menus. + Patches: Sebastian Geerken + - * Added a small handler for javascript links (BUG#546). + * Made the parser ignore white space immediately after an open tag, and + immediately before a close tag. + * Fixed handling of redirection answers with unviewable MIME type (BUG#563). + * Fixed the history-stack handling after redirection chains. + * Fixed the character escaping logic in directory listings (BUG#564). + * Added a small hack to view UTF-8 encoded quotation marks. + * Added a "start_page" option to dillorc (to override the splash screen). + * Tuned the buffering scheme for local directory listings (more speed). + * Set some initial socket-buffering for dpis (in dpid). + * Disallowed the "about:" method on non-root URLs (BUG#573). + * Made the rendered area keep its focus after a form submition. + * Fixed some include files in src/IO/. + Patches: Jorge Arellano + - * Added hints (icons and tooltip text) to buttons featuring a right-click + context menu. + * Now you can copy & paste an URL into the "Clear URL" button. + Patch: Jorge Arellano, Sebastian Geerken + - * Made the save and open file dialogs remember the last directory (BUG#211). + Patch: Diego Sáenz + + +dillo-0.8.1 [May 14, 2004] + + - * Fixed dirent.h includes inside dpid. + Patch: Joseph Myers + - * Fixed a slippery bug with certain interlaced gif images (BUG#500). + Patch: Andreas Mueller + - * Fixed libpng-1.2.4 detection in configure.in. + Patch: Rubén Helguera + - * Added proxy authentication support through the "http_proxyuser" option + in dillorc (the password is asked at run time). + Patch: Ivan Daniluk, Jorge Arellano, Francis Daly + - * Moved tooltips to DwStyle, tooltip event handling to DwPage, and applied + this also to the TITLE attribute of <a> and <abbr>. + Patch: Jörgen Viksell, Sebastian Geerken + - * Fixed a bug related to spaces after anchors and breaks. + Patch: Sebastian Geerken + - * Removed two "type punning" gcc warnings (dw_gtk_viewport.c). + * Added some missing "static" qualifiers. + * Improved a_Strbuf_chars() so no list reversion is required. + * Removed an unused data list (dns.c), and redundant code (selection.c). + * Switch one realloc() call to g_realloc(), to match g_free() (dpi.c). + * Removed unnecessary NULL-checks and NULL initializations. + * Added Html_get_attr_wdef(), it lets providing a default return value. + Patches: Jörgen Viksell + - * Fixed configure.in so pthreads are only linked where needed. + Patch: Jörgen Viksell, Jorge Arellano + - * Modified a_Misc_stuff_chars for simplicity and removed a memory leak. + * Made the dpi framework send the HTTP query to the https dpi + (this allows for an SSL-lib dpi and for easier session caching). + * Cleaned up the int2void and void2int casts in CCC parameters. + * Added container|inline model information to the HTML element table, and + made the bug-meter and the parser aware of it. This both improves bug + detection and rendering. + * Fixed newly detected HTML bugs in bookmarks dpi and file.c. + * Fixed opening files with a ':' character in its name (again). + * Added binaryconst.h (allows for binary constants in C). + * Fixed The ladder effect with lists (BUG#534). + * Made the bug-meter detect tags lacking a closing '>' (BUG#532). + * Made the bug-meter detect excluded inline elements from <PRE>. + * Eliminated a segfault source with tricky <input> tags (BUG#552). + * Fixed <address> to render as a block element (BUG#527). + * Added a content test for "name" and "id" attribute values (BUG#536). + * Fixed the URL resolver handling of the "//" sequence in <path> (BUG#535). + * Added "show_extra_warnings" and removed "use_old_parser" (dillorc). + * Added minor support for the deprecated <MENU> element. + * Eliminated a race condition that produced segfaults when a dpi transfer + was cancelled before the contents were sent (a very rare case). + * Added a test for socklen_t in configure.in. + * Fixed the downloads dpi to handle both new savenames and target directory. + * GdkRgb: fixed handling of not usable system default visual and colormap. + * Made dillo recognize unhandled MIME types, and offer a download dialog! + Patches: Jorge Arellano + + +dillo-0.8.0 [Feb 08, 2004] + + - * Added a right-mouse-button popup for images! + Patch: Frank de Lange, Eric Gaudet, Jorge Arellano + - * Made main document window grab focus on startup, fullwindow, + and after open url (BUG#330) + * Set Ctrl-U to focus the location entry, + Ctrl-R to reload, and Ctrl-H to hide controls. + Patches: Johan Hovold, Jorge Arellano, Stephan Goetter + - * Added a missing handler for broken-connection condition. + Patch: Jorge Arellano, Phil Pennock + - * Introduced a new way of handling dillo plugins! Now the + communications and managing is done by a daemon: dpid. + This comes with a lot of advantages described in Dpid.txt. + Patch: Programming: Ferdi Franceschini; Design: Jorge Arellano + - * Wrote documentation for dpid (Dpid.txt). + * Removed a memory leak in Get_line(). + Patches: Jorge Arellano, Ferdi Franceschini + - * Developed a plugin for downloads. It uses wget and can handle several + connections at the same time. + * Developed stress tests for both dpid and the downloads dpi. + Patches: Ferdi Franceschini + - * Adapted dpi.c to manage plugins through dpid. + * Improved the incoming dpi-stream processing to accept images from a dpi. + * Added/updated lots of dpi-related comments. + * Updated the dpi1 spec. + * Removed the forced end-to-end reload that was set upon dpis. Now, + dpi-generated pages can be cached. + * Made dillo able to handle multiple plugins (still lacks a dynamic API) + * Wrote bare bones plugins for handling: FTP and HTTPS. + * Wrote an example plugin: HELLO --kind of "Hello world". + * Made all the bindings to make it work (fully commented). + * Added code for automatical and non-blocking dpid start! + * Added an extensible secondary URL convenience for popup menus. + * Attached the image popup to the link menu (when the link is an image). + * Removed a memory leak in the selection code (commands.c). + * Cleaned up memory handling when reusing the GioChannel for IPv6. + * Removed a race-condition-polling-CPU-hog bug in IO! (hairy... ;) + * Adapted the generic parser to make HTML error detection, providing + the line number and a hint (expected tag) in the error message! + * Added a bug-meter button that shows the count of detected HTML errors + (left click shows the errors, right click offers a validation menu). + * Added information about optional, required and forbidden end tags. + * Modified the parser's handling of closing tags to account for elements + with an optional close tag, and for more accurate diagnosis messages. + * Added 'use_old_parser' option to dillorc (boolean). + * Fixed the handling of HEAD and BODY elements to account for their + double optional condition (both open and close tags are optional). + * Added the MSG() macro to msg.h and replaced g_print() with it. + * Added the "show_msg" dillorc option to disable MSG(). + * Increased the number of warning messages reported by gcc. + * Solved a lot of signed/unsigned problems. + * Made the necessary cleanups/bug-removals for the new warning level. + * Connected the dpi stream to the cache using the CCC! + * Fixed the cache API by introducing the new call a_Capi_get_buf(). + * Fixed a race condition and a multiple request problem. + * Cleaned up the code for the progressbar widgets. + * Standarized unix domain sockets with AF_LOCAL for portability. + * Minor cleanups for a smooth compile on older systems (libc5). + * Fixed the handling of P element for the HTML nesting checks. + * Set Ctrl-B for bookmarks shortcut (instead of Alt-B). + Patches: Jorge Arellano + - * Enhanced the speed of the actual selection of text. + * Added command line option --debug-rendering. + * Added "button_sensitive" attribute to DwWidget, which is needed to + make <BUTTON>'s accessable at all. (They were inaccessable since the + introduction of text selection!) + * Changed behaviour of DwButton, see NOTE at beginning of dw_button.c. + * Added "collapsing margins" to DwPage. + * Added CSS "list-style-type" and "display" equivalents to DwStyle, changed + definition of "font", replaced "nowrap" by "white-space", and renamed + "link" to "x_link". + * DwBullet now uses DwStyle for the bullet type, made necessary changes + in HTML parser. + * Changed DwStyleLength, now only pixel values and percentages are + supported. (For CSS, anything else will be done elsewhere.) + * Added word backgrounds to DwPage (not yet used.) + * Added the possibility to clip widget drawings (new function + p_Dw_widget_will_clip). + * Made images showing the ALT text as long as no image data has been + retrieved. + * Cleaned up event handling and related code: "link_*" signals now return + gboolean, and DwWidget events are signals. + * Moved DwRectangle and related to dw.c. + * Rewrote idle drawing, fixed BUG#202. + * Removed p_Dw_widget_queue_clear*. + * Added --enable-rtfl option to configure. + * Fixed a bug in findtext (wrong highlighting). + * Many changes in scrolling: added x coordinate (except for anchors), and + DW_[VH]POS_INTO_VIEW position. Added x coordinate also to DilloUrl. + Patches: Sebastian Geerken + - * Fixed bug in DwImage::link_clicked signal. + Patch: Stephan Goetter, Frank de Lange (simultaneously and independent :-) + - * Fixed memory leak in Html_tag_open_isindex. + * Added numerical keypad cursor keys navigation. + * Changed return values of Dw event methods from gint to gboolean. + * Cleaned up debug message generation by using glib wrappers. + * Replaced DwStyle::SubSup by new DwStyleVAlignType values, and + DwStyle::uline and DwPage::strike by new DwStyle::text_decorations. + * Added new convenience macros DW_WIDGET_HEIGHT, DW_WIDGET_CONTENT_HEIGHT, + and DW_WIDGET_CONTENT_WIDTH. + * Added configure options to disable either: png, jpeg or gif. + * Fixed configure.in for proper library linking for dpis and dpid. + * Improved libpng detection. + Patches: Jörgen Viksell + - * Fixed wrong handling of coordinates in ISMAP and USEMAP images. + * Added a hand-shaped cursor to input controls of type image. + * Fixed a off-by-one memory leak in Dw(Ext)Iterator. + * Fixed NULL result handling of p_Dw_widget_text_iterator() in DwBullet, + DwHRuler and DwImage. + * Made dpid/Makefile.am aware of $(DESTDIR). + * Fixed wrong return value of a_Findtext_search for widget == NULL. + Patches: Frank de Lange + - * Fixed a bug in Dw cursor code. + Patch: Frank de Lange, Sebastian Geerken + - * Corrected marshal functions for DwWidget signals. + Patch: Anders Gavare, Sebastian Geerken + - * Added support for anchors using the "id" attribute (BUG#495). + * Defined dillo's version-string in one place only: configure.in. + Patch: Francis Daly + - * Removed a segfault source with corrupted MIME types in HTTP (BUG#501). + * Made SPAM-safe URLs aware of image buttons (BUG#508). + Patch: Francis Daly, Jorge Arellano + - * Added a web search dialog (with toolbar icon, shortcut: Ctrl-S). + The search engine can be set in dillorc (defaults to google). + Patch: Johan Hovold, Jorge Arellano + - * Fixed a problem with libpng options detection (configure.in). + Patch: Rubén Fernández + - * Added "pthreads" (with an "s") detection to configure.in. + Patch: Andreas Schweitzer + - * Added the "-geometry" switch to the CLI. + Patch: Jorge Arellano, Jan Dittmer + + +dillo-0.7.3 [Aug 03, 2003] + + - * Some more selection goodies: + - Redesign of the selection state model, now the selection is preserved + as long as possible. + - Highlighted text is now drawn inverse (new DwWidget::bg_color). + - Selection of images, list bullets and hrulers (as text), with a common + text iterator for the respective widgets. + * Borders may now be drawn inverse (needed for selection). + * Improved the speed when selecting large areas. (BUG#450) + * Fixed a bug in DwPage extremes. + * Fixed a wrong implementation of incremental resizing for DwPage. + (Affected functions: Dw_page_rewrap and a_Dw_page_add_widget) + * Fixed a bug in a_Dw_widget_size_allocate. + * Made jumping to anchors faster (removes CPU hog). + * Fixed a bug in Dw_page_get_extremes(). + * Made (invalid) <li>'s without <ol> or <ul> defined, and independent of + each other. + * Fixed rendering of <frameset>. + Patches: Sebastian Geerken + - * Made a new set of toolbar icons! + Patch: John Grantham (http://www.grantham.de/) + - * Added support for the hspace and vspace attributes of the IMG tag. + * Made only left button activate the image input type (BUG#367,#451). + * Fixed SELECT with "multiple" but without "size" (BUG#469). + Patches: Jörgen Viksell + - * Added titles to bookmark server's html pages. + Patch: Kelson Vibber + - * Made IFRAME to be handled like FRAME (shows link). + Patch: Nikita Borodikhin, Jorge Arellano + - * Fixed a bug in 'a_Misc_stristr' that permeated findtext. (BUG#447) + Patch: Jorge Arellano, "squirrelblue" + - * Finished handling of single and double quotes inside dpi tags. + * Fixed a bug for named-entities' character codes greater than 255. + * Introduced a small UCS to Latin1 converter to help rendering. + * Added a check for Unix98's "socklen_t" (BUG#466). + * Added the missing EINTR handlers in IO.c and file.c. + * Fixed the problem of adding garbage anchors. + Patches: Jorge Arellano + + +dillo-0.7.2 [Apr 30, 2003] + + - * Implemented text selection! (aka: Copy&Paste) (BUG#59) + Patch: Sebastian Geerken, Eric Gaudet + - * Fixed IPv6 support when the unthreaded server is used. + Patch: Damien Couderc, Jorge Arellano + - * Fixed the IPv6 socket connection code for *BSD. + Patch: Daniel Hartmeier, Jorge Arellano + - * Made the URL_SpamSafe flag be inherited by the BASE element. + Patch: Melvin Hadasht + - * Switched configure.in to use AC_CANONICAL_SYSTEM instead of 'uname'. + Patch: Patrice Mandin + - * Added "image/x-png" to MIME types (obsolete, but should be recognized). + Patch: Paolo P. + - * Fixed the code that handled the installation of "dillorc". + Patch: Andreas Schweitzer + - * Fixed a lot of glitches in configure.in: notably libpng and libjpeg + detection, enabling and disabling. (BUG#: 386, 407, 392, 349)! + Patches: Andreas Schweitzer + - * Fixed two leaks in Dw(Ext)Iterator. + Patches: Jörgen Viksell + - * Repaired some minor misbehaviours in the cookie-strings parser. + Patches: Jörgen Viksell, Jorge Arellano + - * Enabled entities parsing in HTML-given hidden and password values. + Patch: Jorge Arellano, Francis Daly + - * Implemented character stuffing in dpi (Fix bookmarks with quotes) BUG#434. + * Added a HTML warning message for META outside HEAD. + * Removed a segfault source when the server doesn't send content/type info. + * Added file type detection for filenames without extension. + * Removed the warnings detected with gcc 3.2.2. + * Fixed the VERBATIM parsing mode and replaced the SCRIPT mode with it. + * Fixed the problem with CR handling in TEXTAREA (BUG#318). + * Fixed initial value parsing within TEXTAREA tags (BUG#400). + * Fixed loading files with spaces in the name (command line) BUG#437. + Patches: Jorge Arellano + + +dillo-0.7.1.2 [Mar 11, 2003] + + - * Fixed a bug in the bugfix that used uninitialized memory contents + causing all kind of undesirable side effects. + Patch: Andreas Schweitzer + + +dillo-0.7.1 [Mar 10, 2003] -- bugfix release + + - * Fixed the setting of the FD_CLOEXEC flag. + Patch: Raphael Barabas + - * Added an automatic file-locking alternative for systems lacking flock(). + Patch: Yang Guilong + - * Fixed a memory leak with pixmaps. + Patch: Keith Packard + - * Fixed the link color switch with scroll wheel mouses (BUG#348) + Patch: Stephen Lewis + - * Made the bookmarks server keep a backup file: bm.txt.bak. + * Fixed not loading the bookmarks file (and erasing the bookmarks). + * Added some missing EINTR handlers. + * Added a handler for unresponsive dpi sockets! + * Restricted dpi-requests to dpi-generated pages only. + * Used -1 instead of WAIT_ANY (some systems don't have it). (BUG#413) + * Fixed a source bug when G_DNS_THREADED is not defined. (BUG#421) + * Switched sprintf to g_snprintf which is safer. + Patches: Jorge Arellano + + +dillo-0.7.0 [Feb 17, 2003] + + - * Added IPv6 support! [./configure --enable-ipv6] (BUG#351) + Patch: Philip Blundell + - * Fixing char escaping/encoding problems with file URIs (BUG#321) + * Fixing buffer overflow sources in file.c. + * Switched the image tooltip from "alt" to "title" attribute. + Patch: Francis Daly, Jorge Arellano + - * Added code so that tooltips stay within the screen. + Patch: Pekka Lampila, Sebastian Geerken + - * Fixed a problem occurring when scrolling with the "b" key. + Patch: Livio Baldini + - * Fixed a memory leak in DwAlignedPage. + Patch: Jörgen Viksell, Sebastian Geerken + - * Moved stuff into remove_cookie() and add_cookie() functions. + * Made cookies sort once in add_cookie(). + * Removed some unneeded casts and calls in cookies. + * Repairing some minor misbehaviours in Cookies_parse_string(). + Patches: Jörgen Viksell, Jorge Arellano, Madis Janson + - * Fixed a bug in Dw_widget_mouse_event. + Patch: Jörgen Viksell + - * Fixed a bug in DwPage ("height" argument). + Patch: Pekka Lampila + - * Removed a segfault source in http.c + Patch: Madis Janson + - * Removed space around tables. + * Implemented the <button> tag! (BUG#276) + * Added iterators (DwItetator, DwExtItetator, DwWordItetator). + - Rewrote findtext, added highlighting and "case sensitive" option. + - Improved findtext dialog placement too! + * Implemented "ALIGN = {LEFT|RIGHT|CENTER}" for <table>, and + "ALIGN = {LEFT|RIGHT|CENTER|JUSTIFY}" for <tr>. + * Implemented character alignment, applied it on ALIGN=CHAR and CHAR for + <tr>, <td> and <th>. + - New widget DwTableCell. + - Some smaller changes in DwAlignedPage and DwPage (virtual word_wrap, + ignore_line1_offset_sometimes). + * Implemented vertical alignment of table cells. + - Changed behavior of Dw_page_size_allocate. + - Applied it on "VALIGN={TOP|BOTTOM|MIDDLE|BASELINE}" for <tr>, <td> and + <th>. + - Fixed splash screen. + * Set the height of <BR>'s in non-empty lines to zero. + * Moved some code from html.c to a_Dw_page_change_link_color. + * Made bullets size depending on the font size. + * Fixed too wide widgets in lists (e.g. nested lists). + Patches: Sebastian Geerken + - * Added support for <input type=image...> (BUG#313) + Patch: Madis Janson, Sebastian Geerken, Jorge Arellano + - * Made a better EAGAIN handler, and enabled FreeIOVec operation in IOWrite. + Patch: Jorge Arellano, Livio Baldini + - * Fixed include directives for config.h + Patch: Jorge Arellano, Claude Marinier + - * Made lots of minor cleanups. + Patches: Lex Hider, Jorge Arellano, Rudmer van Dijk + - * Added a simple command line interface, and enabled some options (BUG#372). + * Added full-window option in command line and dillorc. + * Added an option to set offline URLs from CLI. + * Made dillo embeddable into other GTK applications. + Patches: Jorge Arellano, Melvin Hadasht + - * Made drafts for dillo plugins protocol (dpi1) + Work: Jorge Arellano, Eric Gaudet + - * Avoided a file lock when cookiesrc disables cookies (BUG#358). + * Fixed scroll-jumping between widgets when pressing Up&Dn arrows. + * Added a tiny warning/handler for meta refresh. + * Concomitant Control Chain (CCC): + - Extended the theory to allow bidirectional message passing. + - Renewed the API. + - Improved the debugging code. + - Redesigned the old CCCs, and made a new one for plugins (dpi). + - Reimplemented dillo's core with the new chains. + * Input/Output engine (IO): + - Extended the functionallity with a threaded operation that + allows buffered writes of small chunks on the same FD. + - Created a new IO API, and adapted dillo to it. + * Used the new CCC and IO to implement dillo plugins! (dpi). + * Implemented the internal support for a bookmarks dpi. + * Wrote a dpi-program for bookmarks. + * Created capi.c, a meta module for cache.c. + * Restructured Html_write so custom HTML can be inserted. + * Set BackSpace and Shift+BackSpace to work as Back/Forward buttons. + * Set the escape key as a dialog closing shortcut. + * Removed a segfault in find text with a string of spaces (BUG#393) + * Added wrappers/whitespace filtering for pasted/typed/CLI URLs. (RFC-2396) + * Added an HTML warning message for illegal characters inside URLs. + * Made dpi communication go through unix domain sockets. + * Enabled dillo to launch the bookmarks plugin! + * Made some cleanups in IO/. + Patches: Jorge Arellano + + +dillo-0.6.6 [May 30, 2002] + + - * Added a few canonical casts to fix some obvious 64bit issues. + Patch: pvalchev + - * Fixed a bug with cookies path parsing. + * Fixed persistent-cookies obliteration (BUG#312, BUG#314) + * Set max 20 persistent cookies for each domain. + Patches: Jörgen Viksell + - * Switched flock to lockf. + Patch: Andreas Schweitzer + - * Made a little bugfix in doc/Makefile.am. + Patch: Grigory Bakunov + - * Removed the < 256 hostname length restraint from http queries. + * Made a date-parser that copes with three HTTP date-syntaxes (BUG#335) + * Made the HTML parser a bit more robust with bad HTML (BUG#325, BUG#326) + Patches: Jorge Arellano + + +dillo-0.6.5 [Apr 26, 2002] + + - * Improved a bit table rendering speed. + Patch: Mark Schreiber + - * Extended Dw crossing events. + Patch: Sebastian Geerken + - * Added code to autoresize the "View source" window (BUG#198). + Patch: Andreas Schweitzer + - * Improved *BSD detection code at './configure' time. + Patch: Andreas Schweitzer, Jorge Arellano + - * Added a (pthread_t) cast in dns.c + * Fixed a problem with #fragment hash-lookup (in anchors_table). + * Added code to install/test usr/local/etc/dillorc (BUG#287) + * Added control-character filtering for pasted/typed URLs. + * Replaced the old cache list with a hash table! + Patches: Livio Baldini + - * Fixed a momentous memory leak in png decoding. + * Fixed a segfault source in GIF colormap handling. + Patch: Livio Baldini, Jorge Arellano + - * Added fontname selection to dillorc. + Patch: Arvind Narayanan + - * Removed a segfault source under G_IO_ERR conditions in IO.c. + Patch: Madis Janson + - * Removed a wild deallocation chance in klist.c + Patch: Pekka Lampila + - * Fixed saving of pages that result from POST. + Patch: Nikita Borodikhin + - * Fixed a tiny bug with dillorc parsing on certain locales (BUG#301) + Patch: Lars Clausen, Jorge Arellano + - * Added support for cookies! RFC-2965 (BUG#82) + Patch: Jörgen Viksell, Lars Clausen, Jorge Arellano + - * Added code to detect redirect-loops (BUG#260) + Patch: Jorge Arellano, Chet Murthy + - * Added support for missing Content-Type in HTTP headers (BUG#216) + * Added support for a bare '>' inside attribute values (BUG#306) + Patch: Jorge Arellano, Andreas Schweitzer + - * Allowed enter to submit forms when there's a single text entry. + * Added 'generate_submit' and 'enterpress_forces_submit' to dillorc. + Patch: Jorge Arellano, Mark Schreiber. + - * Added support for rendering adjacent <BR>, Tabs in <PRE>, and linebreak + handling (BUG#244, BUG#179, BUG#291). + Patch: Jorge Arellano, Mark Schreiber, Sebastian Geerken. + - * Switched a_List_* methods to three parameters (and wiped BUG#286) + * Fixed two little bugs within url.c (BUG#294) + * Created an API for nav_stack usage (a handy cleanup). + * Set the attribute parser to trim leading and trailing white space. + * Fixed a problem with NULL requests to the dns (BUG#296). + * Added Tru64(tm) detection code at './configure' time. + * Fixed the parser to skip <style> and <script> contents (BUG#316). + * Bound the space key to PgDn, and 'b' | 'B' to PgUp. + * Allowed 'query' and 'fragment' in POST submitions (BUG#284). + * Changed the url module API (the URL_* macros), and updated the calling + modules, removing several potential bugs at the same time --toilsome. + Patches: Jorge Arellano + + +dillo-0.6.4 [Jan 29, 2002] + + - * Implemented remembering of page-scrolling-position! (BUG#219) + Patch: Jorge Arellano, Livio Baldini + - * Moved jpeg's include directory from CFLAGS to CPPFLAGS in configure.in + Patch: John L. Utz, Lionel Ulmer + - * Made a standarization cleanup to every *.h + * Cleaned some casts to use the GPOINTER_TO_INT and GINT_TO_POINTER macros. + * Added the 'static' qualifier to some module-internal variables. + * Added the 'static' qualifier to module-internal functions! + Patches: Jörgen Viksell + - * New widget DwAlignedPage for alignment of vertical arrays. + - New widget DwListItem for nicer list items (based on some extensions + of DwPage) BUG#271. + * Implemented text alignments (except CHAR). + - Extension of DwStyle and DwPage. + - Applied it on "ALIGN = {LEFT|RIGHT|CENTER}" for <hr>, and + "ALIGN = {LEFT|RIGHT|CENTER|JUSTIFY}" for <p>, <hN>, <div>, <td> and + <th>. Implemented <center> --BUGs #215, #189. + * Small change in DwPageWord (space_style), fixes problems with spaces and + underlining (BUG#278). + Patches: Sebastian Geerken + - * Added 'force_visited_colors' to dillorc. It asserts a different color + on visited links, regardless of the author's setting. + Patch: Jorge Arellano, Sebastian Geerken + - * Updated and improved several #include directives inside *.c + * Added history.c for linear history and scroll-position tracking. + Now the navigation-stack references linear history and nav-expect + holds a DilloUrl (history.c provides an API). + * Fixed a rare data-integrity race-condition with popups (BUG#225) + * Made small icons a bit narrower. + * Fixed a problem with image-maps handling code (BUG#277) + * Added support for several domains in dillorc's 'no_proxy' variable. + * Fixed a small boundary-bug in named-colors parsing. + * Implemented IOs validity-test with klist (avoids a rare segfault source). + Patches: Jorge Arellano + + +dillo-0.6.3 [Dec 23, 2001] + + - * Removed a_Dw_widget_set_usize. + * Removed *_indent in DwStyle, this is now done by nested widgets. + * List items are now single widgets, this fixes bug #78. + * Extended queue_resize and related code, removed fast resizing. + - Applied these changes on DwPage (many changes!). + * Changes in requisition of DwPage. + * Added a nice indenter to the pagemarks! ("Jump to..." menu). + Patches: Sebastian Geerken + - * Reworked the dicache to use a hash table and use image versions. + * Wiped some dicache glitches, and added a dillorc option turn it off! + (reducing memory usage significatively). + Patches: Livio Baldini + - * Added support for OSes that use a slightly different 'struct sockaddr'. + Patch: Johan Danielsson + - * Removed a cache leak when reloading (BUG#257). + Patch: Livio Baldini, Jorge Arellano + - * Added full-screen mode! (left double-click toggles it). + Patch: Jorge Arellano, Sebastian Geerken + - * Extended interface customization options in dillorc (a must for iPAQ). + Patch: Jorge Arellano, Sam Engström + - * Rewrote the whole tag-parsing code with a new scheme (single pass FSM!) + (BUG#190, BUG#197, BUG#207, BUG#228, BUG#239) --Big work here. + Patch: Jorge Arellano, Jörgen Viksell + - * Set form encoding to escape everything but alphanumeric and -_.* (BUG#236) + * Rewrote Html_tag_open_input. + * Extended BACK and FWD key shortcuts to: {ALT | MOD*} + {, | .} :-) + * Fixed URI fragment parsing (BUG#247). + * Centered FindText and OpenUrl dialog windows. + * Structured dillorc (now it's more readable! ;) + * Added a dillorc option to force transient_dialogs. + * Fixed a subtle bug with HTTP end-to-end reload (BUG#234). + * Fixed form submition when action has <query> or <fragment> (BUG#255) + * Added fast URL resolving methods! (96% rfc2396 compliant by now) BUG#256 + * Switched form-urlencoded CR to be sent as CR LF pair (BUG#266). + * Fixed leaving open FDs when the socket connection fails (BUG#268). + Patches: Jorge Arellano + + +dillo-0.6.2 [Oct 17, 2001] + + - * Added code to parse away <?...> tags (BUG#203). + Patch: Sebastian Geerken + - * Made an explicit ISO8859-1 requirement in font loading (BUG#193). + Patch: Karsten M. Self + - * Added a temporary handler for frames! (lynx/w3m like). + Patch: Livio Baldini + - * Added gtk_set_locale to dillo's init sequence (BUG#173). + Patch: Eric Gaudet, Martynas Jocius + - * Added support for <big> and <small> tags (BUG#221). + Patch: Livio Baldini, Jorge Arellano + - * Added back and forward history popup menus! (BUG#227) + Patch: Jorge Arellano, Eric Gaudet, Olaf Dietsche + - * Removed anchors from to-proxy queries (also added some checks, BUG#210). + * Removed a leak in url.c + * Fixed a bug with command-line HTML files that reference images (BUG#217). + * Improved status-bar messages a bit, modified toolbar pixmaps and + reduced the number of a_Url_dup calls. + * Set Ctrl-Q to close window and Alt-Q to quit. + * Devised an abstract model for parsing, wrote it into HtmlParser.txt and + made dillo compliant with it! + * Fixed CR/LF entities parsing inside <PRE> (BUG#188) + * Added an error message for unsupported protocols (BUG#226) + * Removed some warnings detected with different gcc versions. + Patches: Jorge Arellano + + +dillo-0.6.1 [Sep 13, 2001] + + - * Changed calculation of shaded colors. + * Eliminated redundant code when drawing background colors. + * Fixed a bug in DwStyle drawing functions. + * Fixed a bug in Dw_page_calc_widget_size. + * Some changes for <hr> (also BUG#168). + * Added <tr> backgrounds. + Patches: Sebastian Geerken + - * Added support for hexadecimal character references, as ¡ (BUG#183) + Patch: Liam Quinn + - * Replaced atoi(3) calls with strtol(3). + * Made path comparison case sensitive in a_Url_cmp. + Patches: Livio Baldini + - * Added a tiny handler for <DIV> + Patch: Robert J. Thomson + - * Fixed a segfault source in color parsing, and extended it a bit. + Patch: Scott Cooper, Jorge Arellano + - * Removed a leak with the DilloImage structure (when image is not found). + * Fixed (and made faster) Url_str_resolve_relative (BUG#194) + Patch: Jorge Arellano, Livio Baldini + - * Added parsing support for %HexHex escape sequences in file URIs + Patch: Jorge Arellano, Livio Baldini, Agustín Ferrín :) + - * Implemented Ctrl-W (close window) (BUG#87) + Patch: Jorge Arellano, Martynas Jocius + - * Fixed a segfault when dillo cannot access ~/.dillo for some reason. + Patch: Jorge Arellano, Amit Vainsencher + - * Fixed the segfault from untrue Content-Length in HTTP header (BUG#187) + * Fixed closing an active browser window from the window manager (bug#91) + * Eliminated anchors from HTTP queries (BUG#195) + * Fixed the repeated reload segfault (BUG#69) + * Updated some docs in doc/ dir. + * Added a keyed-list ADT (klist.[ch]) + * Removed a segfault source in dns.c. + * Massive changes in Cache module: redesigned the external and internal API, + implemented new methods, changed several algorithms, removed transitory + and obsoleted code, removed a segfault source and improved CCC operations. + * Changes in Http module: extended error handling, improved abort sequences, + and added code that's aware of race conditions (based on klist ADT). + * Uniformed CCC start operation in IO, http and cache modules. + Patches: Jorge Arellano + + +dillo-0.6.0 [July 31, 2001] + + - * Fixed a bunch of memory leaks! + * Fixed links on pages with only one line, tuned text-entries size and + fixed the HTTP header problem (BUG#180) + Patches: Jörgen Viksell + - * Improved dialogs handling: find_text, view_source, open_url, open_file, + save_link and save_page (also removed a leak here). + Patches: Jorge Arellano, Jörgen Viksell + - * Modified GtkDwScrolledWindow and GtkDwViewport, now scrollbars work much + better. This also fixes of the wrong viewport length (BUG#137). + * Implemented tables! (incomplete) + - Changes in Dw: DwTable and DwWidget::get_extremes. + - html.c: extended DilloHtmlState, added code for table parsing, moved + some attributes from DwPage into the HTML linkblock. + * Restructured code for image maps (works now with tables). + * Removed "alt" attribute from <a> tag (no standard). + * Fixed a bug in a_Url_dup. + * Extended Dw events: leave_notify_event is now called for more widgets. + * Extended DwPage and DwImage signal "link_entered". + * Extended DwStyle by CSS-style boxes, background colors and border_spacing: + - Implemented borders around image links (BUG#169). + * Fixed the wrong PNG background? (BUG#172) + * Corrected handling of styles by the html parser. + * Added alternative, "fast" resizing method. + * Added a simple possibility to scroll long option menus (BUG#158) + * Added backing pixmap, this prevents flickering (BUG#174). + * Changes and extensions in handling lenghts, see doc/DwStyle.txt. + * Added option "limit_text_width". + Patches: Sebastian Geerken + - * Added nowrap attribute to DwStyle, and applied it to <pre> (BUG#134), + <td> and <th>. + Patch: Jörgen Viksell, Sebastian Geerken + - * Added a_List_resize to list.h methods. + * Added debug.h to standarize debugging messages. + Patches: Sebastian Geerken, Jorge Arellano + - * Added file selection while saving pages or links. + Patch: Livio Baldini + - * Added a few 'const', a missing header and some strength reductions. + Patch: Aaron Lehmann + - * Made dillo to also check '/etc/dillorc' for options. + Patch: Eduardo Marcel Maçan, Jorge Arellano + - * Made a help page, and linked it to 'about:help' (BUG#72) + Patch: Jorge Arellano, Kristian A. Rink + - * Added an "alt" camp to DilloUrl + * Fixed the linkblock memory-leak (BUG#163) + * Fixed local file loading from the command line (BUG#164) + * Fixed server-side image maps support (BUG#165) + * Added code for accel-keys on toolbar buttons + * Fixed the segfault with unconnected servers (BUG#170) + * Fixed the open HTTP-sockets problem (BUG#171) + * Reimplemented the low-level file descriptor handling with GIOChannels + (and dillo became even faster!) + * Made reload-button to request an end-to-end reload (BUG#64) + * Fixed the multiple-POST problem, and added a confirmation dialog (BUG#175) + * Finished fixing the repeated link-click problem (BUG#74) + * Misc: rewrote the 'about:splash' method, tuned DwPage for minimal + memory usage, improved a_Color_parse and Html_read_coords, cleaned-up + popup-menus and linkblock initialization, eliminated a lock-source in + Html_parse_length. + * Added DEBUG_HTML_MSG macro for invalid HTML messages. + * Fixed the nav-stack (and multiple #anchors) problem (BUG#177) + * Added code to avoid segfaults with unhandled MIME types. + * Fixed dns.c from solving the same address on different channels (BUG#178) + * Improved error handling and extended the CCC scope! (mainly HTTP). + * Fixed a Dw-leak that was affecting: hr, bullets, images, tables (&pages)! + * Made several cleanups and added/fixed comments in various places. + * Reimplemented find-text with a faster algorithm and extended semantics!! + * Fixed some oddities with our autoconf stuff. + Patches: Jorge Arellano + + +dillo-0.5.1 [May 30, 2001] + + - * Designed a new URL handling scheme, and integrated it throughout the code! + Patch: Livio Baldini, Jorge Arellano + - * Removed a significative memory leak in dw_page. + * Added support for EAGAIN in IO.c + Patches: Livio Baldini + - * Removed 6 memory leaks! (of varying significance) + Patches: Jörgen Viksell + - * Fixed a bug in DwPage (BUG#162, crash when clicking on links). + * Removed a_Dw_gtk_viewport_queue_anchor and related code (becomes obsolete + with the new URL handling scheme). + * Speed-optimized key moving in GtkDwScrolledFrame (no more blocking). + * Fixed two memory leaks, in Dw_style_color_remove, and + Dw_style_font_remove. + Patches: Sebastian Geerken + - * Implemented the splash screen with "about:" (No more splash-file saving!) + * Set all pthreads to run in detached state. + * Reworked dillo's interface so now there're six options; available by + changing 'panel_size' and the new 'small_icons' in dillorc. + * Removed a minor leak in dns.c and a wild-deallocation source. + Patches: Jorge Arellano + + +dillo-0.5.0 [May 10, 2001] + + - * Implemented <IMG> ALT as tooltip. + * Fixed bug #135 (incorrect update of statusbar when leaving "ismap" img). + Patches: Livio Baldini, Sebastian Geerken + - * Completed image scaling (BUG#75). + Patch: Sebastian Geerken, Jorge Arellano + - * Fixed proxy support (BUG#150). + Patch: Livio Baldini + - * Fixed two bugs in the Dw event handling. + * Fixed bugs in DwEmbedGtk and GtkDwViewport: idle functions are now + removed properly. + * Fixed bug in DwEmbedGtk (added call of parent_class->destroy). + * Moved DwPageAttr into a new submodule (DwStyle). + - Applied DwStyle to DwBullet (BUG#146). + - Implemented immediate changing of link color provisionally (BUG#152). + * Fixed positioning of headers (half of BUG#118). + * Fixed rendering of <b><i> and <i><b> (BUG#145). + * Fixed unrecognized dillorc text_color setting (BUG#151). + Patches: Sebastian Geerken + - * Changed word/line structure of DwPage + * Improved FORM sending (standar name/value submits) and processing; + added READONLY, SIZE, MAXLENGTH attributes, type=BUTTON and some cleanups + * Fixed VERBATIM parsing mode (BUG#130) + * Fixed a bug in calculating the page width (BUG#136) + Patches: Jörgen Viksell + - * Added a dillorc option to set the location entry within the menu bar. + Patch: Eric Gaudet + - * Integrated some modifications to ease compiling on GNU Darwin. + * Added support for leading whitespaces in HREF (BUG#120) + * Fixed anchor's hash_table and a few more quirks (were warnings on Alpha) + * Fixed entities parsing in URI attributes (BUG#114) + * Fixed stop button's sensitivity on plain files (BUG#142) + * Made filesize more accurate on directory listings (BUG#143) + * Introduced the new Concomitant Control Chain (CCC) design! + - All the way in the quering branch + - Halfway in the answering branch + - Introduced more error handling and status messages + - Started implementing error control using the CCC! + - Fixed too much caching (BUG#84) + - Fixed a CPU hog error condition (BUG#144) + - Eliminated the segfault from outdated dns answers (BUG#140) + - Fixed repeated Back (faster than rendering) segfault. + * Cleaned the header include files + * Incremented the valid-charset for dillorc identifiers (BUG#149) + * Added support for unterminated quotation of attribute values (BUG#155) + Patches: Jorge Arellano + + +dillo-0.4.0 [March 3, 2001] + + - * Rewrote most of the Dw module from scratch: + - Page widget: ported, added support for relative sizes of widgets, and + changed behaviour for pressing button 2 on a link. + - Removed the now unnecessary event boxes for check and radio buttons. + - Modified the code outside to use new Dw. + * Started to implement relative sizes for images (in html.c) + * Implemented attributes WIDTH, SIZE and NOSHADE of the <hr> tag. + * Added focus adjustment for selection lists (<SELECT>) + * Implemented TAB, Shift+TAB navigation in FORMS (BUG#86) + Patches: Sebastian Geerken + - * Included a scaling font_factor into dillorc! + Patch: Bruno Widmann + - * Fixed bugs #125 and #129 (menu item focus and radio reset in forms) + Patch: Jörgen Viksell + - * Added code to ignore anything inside STYLE tags. + Patch: Mark McLoughlin + - * Implemented image rendering based on GdkRGB and DwImage! + * Fixed 4 bit color planes support, cleaned the image code, + removed a few leaks and added documentation (Images.txt). + * Ported every patch from 0.3.2 to 0.4.0 + Patches: Jorge Arellano + + +dillo-0.3.2 [February 22, 2001] + + - * Added the option to use oblique font instead of italic (dillorc) + Patch: Eric Gaudet, Sebastian Geerken, Jorge Arellano + - * Changed Dw_page_find_line_index to use a binary search + Patch: Eric Gaudet, Jorge Arellano + - * Added a visual hint for visited links (BUG#117) + * Repaired the dillorc parser to skip unknown symbols (BUG#119) + Patch: Eric Gaudet + - * Fixed the segfault for controls outside FORM and SELECT elements (BUG#121) + Patch: Eric Gaudet, Jörgen Viksell + - * Added support for SUB and SUP tags (BUG#115) + Patch: Jörgen Viksell + - * Added a geometry directive to dillorc (sets initial browser size) + Patch: Livio Baldini, Jorge Arellano + - * Fixed bookmarks loading in new browser windows (BUG#110) + * Included a workaround for BUG#71 + Patch: Livio Baldini + - * Fixed a CPU hog when clicking ftp URLs (BUG#123) + * Set a 64 bytes threshold on pagemark headers + Patch: Jorge Arellano + - * Added check for negative image sizes. + Patch: Livio Baldini, Sebastian Geerken + + +dillo-0.3.1 [December 22, 2000] + + - * Implemented basic Find-text functionality + Patch: Sam Dennis, Sebastian Geerken, Allan Clark and Jorge Arellano :-) + - * Implemented "Pagemarks" (Kind of a headings-based page index!) + Patch: Sebastian Geerken and Eric Gaudet + - * Fixed nested-lists numbering, and added support for "type" (BUG#76) + * Added support for image maps, both usemap and ismap! (BUG#27) + * Set "on" as default value for check boxes + Patch: Eric Gaudet, Jorge Arellano + - * Added "Copy link location" to the link menu + Patch: Eric Gaudet + - * Removed redundant functions from misc.c + * Added support for BASE, CODE, DFN, KBD, SAMP and VAR tags (BUG#106) + * Added support for TAB characters in plain text files (BUG#112) + Patches: Jörgen Viksell, Jorge Arellano + - * Fixed a_Url_squeeze (BUG#100) + Patch: Livio Baldini, Jorge Arellano + - * Added gamma support and basic transparency for PNG images (BUG#60) + * Moved menu_popup into the 'bw' structure (BUG#96) + * Fixed the gif decoder to get image size from the right place (BUG#98) + * Made the new browser window size the same as the parent (BUG#55) + Patch: Livio Baldini + - * Added support for ISINDEX method (BUG#15) + Patch: Sam Dennis + - * Added support for bare '<' character parsing + * Removed every sign-conflict warnings given by gcc with '-W -Wall' + * Fixed several identation problems (rendering) + * Implemented "Save link as" (link menu) + * Removed the subtle bug that used to segfault when deleting and processing + queue clients at the same time (BUG#111). + * + Some comments, cleanups, size reductions, minor optimizations etc. + Patches: Jorge Arellano Cid + + +dillo-0.3.0 [November 13, 2000] +(Lots of patches are pending!) + + - * Added support for <strike>, <s>, <del> and <u> tags. + Patch: Jörgen Viksell + - * Fixed a bug in #anchors code + Patch: Sebastian Geerken + - * Parsed text between script tags, out of the rendering part. + * Added support for decimal entities that start with 0. + * Added some comments to html.c + Patches: Sean 'Shaleh' Perry + - * Added support for corrupted png images (avoids segfaults!) + Patch: Eric Gaudet, Jorge Arellano + - * Fixed empty title bookmarking (BUG#85 and #88) + Patch: Livio + - * Fixed view-source to take its URL from the right place. + Patch: Sam Dennis + - * Added font support for the compaq iPaq linux distribution. + Patch: Eric Christianson + - * Fixed spaced attribute parsing (BUG#79). + * Fixed concurrent save and downloading! + * Added alpha support for external (simple) plugins. + ? * Added a workaround (maybe a bug fix) for BUG#77 (No segfault). + * Introduced a new design layer between the IO and Dw: + - The imgsink stuff was completely removed. + - The dicache was rewritten from scratch and integrated + into the normal cache. + - A single client queue is being used for both caches. + - The file descriptors were replaced by cache keys that serve + as connection handlers. + - The image data structure and related sources got changed. + - Every decoder (png, gif, jpeg) was adapted to the new scheme. + * Fixed the file-images caching problem and the associated memory-leaks. + * Improved progress bar accuracy for images. + * Added progress bar functionality for plain text (+comments +cleanups) + * Fixed the right-click-over-plain-text segfault (BUG#80). + * Started improving the right-mouse-button menus. + Patches: Jorge Arellano Cid + + +dillo-0.2.4 [August 21, 2000] + + - * Fixed the white square bug with PNG images (BUG #4) + Patch: Luca Rota + - * Added support for #anchors! (BUG #10) + * Added support for resolving relative #anchors (BUG #65) + Patches: Sebastian Geerken + - * Fixed a segfault-source that produced BUG #61. + * Made several cleanups and standarizations in html.c + * Extended entity-parsing scope, and the list of supported entities. + * Rearranged TagInfo data into a new structure. + * Added the base for refresh support in META tags. + Patches: Sean 'Shaleh' Perry + - * Added support for TEXTAREA tags! + Patch: Jörgen Viksell + - * Improved and fixed Html_parse_entities. + * Reimplemented the Stash buffer with a GString. + * Fixed a bug with \r\n-terminated HTML lines. + * Added redirection support for relative URLs (BUG #73). + * Added some comments and minor fixes to patches. + Patches: Jorge Arellano Cid + - * Linked "open link in new window" to mouse button #2 (#3 also works) + Patch: Eric Gaudet + + +dillo-0.2.3 [August 4, 2000] + + - * Removed "search.h" include in http.c (freeBSD compatibility). + Patch: Kurt J. Lidl + - * Removed several memory leaks that were sprinkled through the code. + Patches: Jörgen Viksell + - * Fixed a segfault crash when hitting PgDn in the URL box (BUG #54). + * Removed a segfault source in commands.c + * Made some minor fixes to Dw and added more comments to the code. + * Made changes in dw_gtk_view.c, and fixed the rendering problem that + arise when changing from a scrolled page into another (BUG #58). + * Changes in hruler dynamic resize --not finished though. + * Removed a floating point exception bug in image handling code (image.c) + * Dramatically improved rendering speed!!! Most notably long HTML pages + with lots of links; Improvement ranges from 2 to 5 times faster! (aprox.) + * Fixed misplaced rendering of small pages (BUG #35) + * Fixed the bookmark bug with empty title strings (BUG #57, #67) + * Completed support for "\r", "\n" and "\r\n" in PRE tags. + * Fixed text rendering between multiple selection boxes (BUG #56) + * Added several minor enhancements (comments, formatting, speed, etc) + * Added extensive documentation! (IO.txt, DilloWidget.txt and Dw.txt) + Patches: Jorge Arellano Cid + + +dillo-0.2.2 [July 9, 2000] + + - * Added a gtk_window_set_wmclass to all windows to prevent dialogs + from having the same size as the main window. (Ex: with Sawfish) + * Made some width and height changes to the SELECT-stuff + * Added "submit" to submit buttons without a value. + Patches: Jörgen Viksell + - * Fixed a segfault when calling "about:" method + Patch: Dominic Wong + - * Added an option to force dillorc-defined colors (Try it with slashdot!) + * Fixed display of encoded-URL-links on the status bar + Patches: Adam Sampson + - * Removed several compiler dependencies + (detected with lcc on a 64 bit machine) + * Modified mime.c and Url.c to use list.h, and eliminated hdlr.c + * Standarized unsigned types to glib all around the code + * Added some includes for libc5 compatibility + * Modified IO_callback to avoid a CPU-hog (it happened in some systems). + * Fixed a bug that added a trailing ampersand to GET and POST queries. + * FIxed attribute parsing. It had nasty side effects; as providing + wrong attribute values to POST and GET methods. + * Joined Url.c and url.c into a single module. + * Reimplemented URL resolving functions. + * Implemented a new parser for "file:" URLs (Try "file:" & "file:."). + * Removed child_linkblock and changed the HTML stack handling + (both changes result in a simpler, easier to understand code). + * Modified and removed a segfault source in Html_lb_new. + * Modified forms handling to be more tolerant with messy HTML. + * Linked "image/pjpeg" in MIME types (progressive jpeg) + * Fixed form submittion when there's no submit button (bug #49) + Now dillo can search on freshmeat, altavista, etc! + Patches: Jorge Arellano Cid + + +dillo-0.2.1 [June 17, 2000] + + - * Modified the pixmaps for better interface perception ;) + * Modified Dw_gtk_view_adjustment_value_changed to update the visible + rectangle even though the widget is not realized; it seems to work! + * Implemented the horizontal ruler as a Dw --dw_hruler.[ch] + Fixed its expose problems (Bug #13). (todo: resizing). + * Changed Dw_gtk_progressbar module to "progressbar" --naming stuff + * Added Content-length in file headers (avoids reallocations) + * Modified form submittion and encoding to use dynamic memory allocation + * Eliminated a dns.c hack that passed an int as a void* ;) + * Updated the documentation with an extensive IO description. + Patches: Jorge Arellano Cid + - * Added some functionality to reload button (not complete yet) + Patch: Luca Rota , Jorge Arellano Cid + - * Fixed hash handling within URL parsing. (Bug #9) + Patch: Marcos Ramírez , Jorge Arellano Cid + + +dillo-0.2.0 [June 2, 2000] +*** THIS IS A HALF-NEW BROWSER *** + + - * Finally reimplemented the whole networking process (***BIG changes***) + Rewrote from scratch: IO, cache, web, http, socket, ... + Modified: gif, png, jpeg, html, nav, plain, ... (Every client) + All the querying, retrieving, caching and delivering is NEW!!! + * Eliminated CPU-hogging while waiting for a DNS query to complete + * Eliminated CPU-hogging when facing redirections + * Implemented basic redirection functionality + * Eliminated several segmentation fault bugs + * Modified autoconf stuff + * Modified source-code tree and libraries + * Reduced binary size + * Eliminated a memory leak in socket connections + * Created a new socket connection scheme + * Implemented Cache as the main networking abstraction layer + * Joined almost every URL-retrieving module into libDio + * Set the basis for save-link-as functionality (see save function) + * Modified the navigation stack to a cleaner design + * Improved status bar messages when connecting + * Changed some function names + * Created new pixmaps for the toolbar! + * Added a "new" button near the URL to clear the entry! + * Added a_List_remove to list.h + * Updated documentation in doc/ + (README, Cache.txt, store.txt, Dillo.txt, Images.txt and IO.txt) + Patches: Jorge Arellano Cid + - * Added a workaround patch for BUG #35 (page expose problems) + Patch: Andrew McPherson + + +dillo-0.1.0 [Mar 30, 2000] + + - * Fixed a bug that used to lock hostname queries. + ('DNS can't resolve name' mesg.) + * Fixed the wrong parent link when browsing directory contents + * Changed the file/directory HTML-output-layout + * Finally rewrote the whole file.c module :-) + * Made Http_query buffer overflow-safe + * Commented and cleaned web.c + * Changed the licence to GPL. (Raph agreed on that) + * Fixed a tag-search bug in html.c; it produced rendering problems. + * Fixed a parsing problem with tags that were split on different lines + * Fixed the after-tables parsing problem + * Added a startup page + Patches: Jorge Arellano Cid + - * Fixed a bug with http queries that sometimes produced infinite loops + Patch: Marcos Ramírez + + +dillo-0.0.6 [Mar 9, 2000] + + - * Readded an old, wiped-by-mistake, bug fix. + * Added preferences settings using a readable config (dillorc) + * Added a page-title trimmer facility (39 chars) to bookmarks saving. + Patch: Luca Rota + - * Fixed three memory leaks in bookmarks reading + * Added 'Open link in a new window' within the right button pop-up-menu + Patch: Sammy Mannaert + - * Fixed a bug that used to put two slashes on directory file anchors + * Actualized plugin.txt to current code base (and a bit of fix) + * Changed "fprintf(stderr..." to "g_print(..." + * Improved list.h + * Fixed image URLs both for HTTP and local files! + * Fixed tag attribute parsing (The trimmed-text-inside-buttons bug) + * Wrote several documentation files (placed them in doc/) + * Fixed transparent image rendering + * Implemented a binary search for HTML tags (just a bit faster) + * Small leak fixes and some corrections to http.c + * Made style fixes, added function comments and things like that. + Patches: Jorge Arellano Cid + + +dillo-0.0.5 [Feb 3, 2000] + + - * Added progress bars (to be improved) + Patch: James McCollough, Jorge Arellano Cid + - * Rearranged, changed and commented the decompressed image cache code + * Fixed autoconf stuff to include zlib + * Added memory deallocating functions to cache, dicache, socket, http & dns + * Fixed memory leaks in jpeg.c, png.c and gif.c + * Made several changes in dw_page.c and dw_image.c + * Introduced 'list.h' source, and standarized the whole code to use it + * Fixed image rendering (Fixed algorithms and data structures) BIG CHANGES + * Removed some false comments and added true ones (I hope ;) + * Made several "standarizing" changes all over the code and + * some other changes (not worth listing) + Patches: Jorge Arellano Cid + - * Added support for 'text' and 'link' colors inside <BODY> tags + * Standarized all memory management to glib functions + * Fixed the plugin API to work again (forked) + * Removed a warning (remove not implemented for Dw_view and Dw_scroller) + * Solved the page-without-title bug in bookmarks. + Patches: Luca Rota + + +dillo-0.0.4 [Jan 4, 2000] + + - * Removed the test widget + * Added a jpeg image decoder error-handler + Patches: Sammy Mannaert + - * Changed some ADTs to glib to be compatible with newer glibc2 systems + * Added background color alternative when bg. is white (or not specified) + * Improved connecting time status messages + Patches: Jorge Arellano Cid + - * Added background color support. + Patch: Luca Rota, James McCollough + - * Added support for <OL></OL> tags + * Added view-source and view-bookmarks functionality + * Improved PgUP/PgDown and Up/Down response. (No need to grab focus!) + * Fixed openfile gtk run-time warning + * Fixed the focus problem with text camps + * Fixed the title-linger bug with pages that don't specify title. + * Added a preliminary right button menu + * Added POST method support + Patches: Luca Rota + - * Added PNG image support. + Source Code: Geoff Lane, Patch: Jorge Arellano + + +dillo-0.0.3.tar.gz [Dec 18, 1999] + + - * Finished the whole Naming&Coding effort!!! + Stage 2 worked by: Luca Rota and Jorge Arellano + - * Removed all compile time warnings (at least with gcc 2.7.2.3) + * Added more documentation inside the code + * Removed the '~/.dillo' directory creation bug. + * Integrated a patch for menu module + * Renamed menus.c to menu.c + * And some other minor things... + Patches: Jorge Arellano Cid + + +dillo-0.0.2.tar.gz [Dec, 1999 --Does anyone remember the day?] + + - * Finished stage one of the naming&coding design (Hey, it's 1.3 Mb of code!) + Worked by: Jorge Arellano, Sammy Mannaert, James McCollough and Luca Rota + - * Removed some bugs and renamed the source files. + * Heavily rearranged URL/ an IO/ files for better understanding & debugging + * Added more documentation within the sources + * Recoded automake stuff + * Integrated some queued patches + * (And several things that I have no time to write now! :-) + Patches: Jorge Arellano Cid + + +dillo-0.0.1.tar.gz [Dec, 1999] + + - * Halfway release, amidst stage one of the naming&coding effort. + Worked by: Jorge Arellano, Sammy Mannaert, James McCollough and Luca Rota + + +dillo-0.0.0.tar.gz [Dec, 1999] + + - * Applied a cleanning patch to menus.[ch] + Patch: Sammy Mannaert + - * Made a threaded DNS scheme (several improvements: now it works with gdb) + * Bug fix on TMP_FAILURE_RETRY + * Bug fix on links not been followed (Url parsing) + * Changed the default pixmaps + * Maked automake, autoconf, autoheader, changes + * Changed binary name + Patches: Jorge Arellano Cid + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/INSTALL Sun Oct 07 00:36:34 2007 +0200 @@ -0,0 +1,176 @@ +Basic Installation +================== + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, a file +`config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + + The file `configure.in' is used to create `configure' by a program +called `autoconf'. You only need `configure.in' if you want to change +it or regenerate `configure' using a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes a while. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. You can give `configure' +initial values for variables by setting them in the environment. Using +a Bourne-compatible shell, you can do that on the command line like +this: + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure + +Or on systems that have the `env' program, you can do it like this: + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not supports the `VPATH' +variable, you have to compile the package for one architecture at a time +in the source code directory. After you have installed the package for +one architecture, use `make distclean' before reconfiguring for another +architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' can not figure out +automatically, but needs to determine by the type of host the package +will run on. Usually `configure' can figure that out, but if it prints +a message saying it can not guess the host type, give it the +`--host=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name with three fields: + CPU-COMPANY-SYSTEM + +See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the host type. + + If you are building compiler tools for cross-compiling, you can also +use the `--target=TYPE' option to select the type of system they will +produce code for and the `--build=TYPE' option to select the type of +system on which you are compiling the package. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Operation Controls +================== + + `configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`configure' also accepts some other, not widely useful, options. +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Makefile.am Sun Oct 07 00:36:34 2007 +0200 @@ -0,0 +1,5 @@ +SUBDIRS = doc dlib dpip src dpid dpi + +EXTRA_DIST = ChangeLog.old dillorc2 install-dpi-local README-port + +sysconf_DATA = dillorc2
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/NEWS Sun Oct 07 00:36:34 2007 +0200 @@ -0,0 +1,33 @@ +---- +NEWS +---- + +Nov 2000: + + Introduced a new design layer between the IO and the Dw. + +March 2001: + + Finally the new dillo widget is ready! (dillo >= 0.4.0). + 0.4.0 is able to cope with low resolution depths. + +Apr 2002: + + We moved to: http://dillo.cipsga.org.br/ + +Dec 2002 + + We moved to: http://dillo.auriga.wearlab.de/ + +Jun 2003 + + http://www.dillo.org/ (hosted at the wearlab!) + +Sep 2007 + + The new FLTK2-based dillo code is released! (under GPL3) + + Jorge.- + jcid@dillo.org + Project maintainer, core developer, patcher, you name it! :-) +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/README Sun Oct 07 00:36:34 2007 +0200 @@ -0,0 +1,76 @@ +======= + Dillo +======= + + This is an alpha release of the next generation of the Dillo +web browser. The code underwent a major rewrite: significant +parts of the codebase were ported to C++, and the rendering +engine now uses the FLTK2 library instead of GTK1. + + With regard to Dillo 0.8.6, dillo-f15f has some advantages (as +antialiasing and utf-8), and some disadvantages. The problems are +simple to solve and only need some man months to complete. When +we're there, dillo-f15f will be easily regarded as better than +the former series. + + This is release should be regarded as alpha. + + + Here's a list of some well known problems: + + * no iteration inside simple lists + * image links haven't been hooked yet + * you may experience crashes from "assert" statements from + unfinished code. + * the scrolling position is not yet updated (when following a + link, the former scroll position is kept). + * viewport scrolling is not yet optimized (takes lots of CPU) + * context menus are not yet completely hooked or activated + + * no FRAMES rendering + * no https -- read the FAQ to enable a protoype. + + +------------ +Dpi programs +------------ + + These are installed by "make install". If you don't have root +access, copy "dillo" and "dpid" to some directory in your path +and install the dpis by running "./install-dpi-local" from the +top directory (they will be installed under ~/.dillo). + + +---- +*BSD +---- + + Dillo may compile on *BSD systems; please report on this. +Please note that you'll need GNU make. + + From OpenBSD >= 3.3, gethost* calls are not thread safe. If +your dillo crashes or locks at times, just use: + + ./configure --disable-threaded-dns + + so dillo uses a single thread for name resolving. + + +------- +Solaris +------- + + Dillo may compile and run OK on Solaris but (please report): + + * use gmake (a symbolic link make -> gmake works OK) + + Solaris is very inconsistent so you may need to add/remove: + + -lrt -lposix4 + + at link time. + + +Jorge.- +(jcid@dillo.org) +Sep 30, 2007
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/README-port Sun Oct 07 00:36:34 2007 +0200 @@ -0,0 +1,145 @@ +============================== + Porting Dw to Other Toolkits +============================== + +This is a pre-release, which only contains a small test-program to +test Dw with new new rendering abstraction. This rendering +abstraction, which is described in doc/DwRender.txt, will make Dw +portable at all, by implementing several interfaces, which are defined +in src/dw_render.h. + +Currently, the new rendering abstraction is incomplete, and so not +able to be integrated into dillo. There will be several pre-releases, +with the version number 0.8.3-pre-dw-redesign-<n>. + +Actual Porting +============== + +You will not have to read the whole "DwRender.txt", in order to port +Dw to another platform, instead, here is a description of what to do. + +Gtk Dependencies +---------------- +The current version must still be linked to Gtk+, since the Gtk+ +object model is used for class inheritance (especially the DwWidget +hierarchy). I have been careful to limit the dependencies to a +minimum, there is a script, src/search-gdk-refs, which detects all Gdk +dependencies (which are generally not allowed), as well as those Gtk+ +dependencies, which do not refer to the Gtk+ object model. + +Glib is also used, there are currently no limitations for the usage. + +These dependencies will be removed in the future, so it is recommended +not to use Gtk+ at all for the code, which is necessary for new +platform. + +Test Program +------------ +For the Gtk+ version of Dw, there is a test program dw-test in the src +directory. This should be rewritten by a version, which uses the newly +written platform specific implementations. + +Interfaces +---------- +Since Dw is (currently) written in C, interfaces become a bit +tricky. Generally, there are two structures, one for the object +itself, which implements the interface, and one static structure, +which contains static stuff related to the implementing object, mostly +methods. + +For example, a_Dw_render_layout_new expects two arguments, one for a +newly allcoated implementation the platform interface (as void*), and +another (static) instance of DwRenderPlatformClass. In the test +program, this is Dw_gtk_platform_class, which is defined in +dw_gtk_platform.c. Notice, that the first argument is destroyed, when +the layout is destroyed, while the second one is not touched. + +Methods are simply implemented as function pointers, which first +parameter is void*. When such a method is called, the first argument +is the object, in this case, what has been passed as first argument to +a_Dw_render_layout_new. In some cases, such an interface structure may +contain other members, such as DwRenderViewClass::class_id. + +When implementing an interface in C, you should look at +dw_gtk_platform.[ch] for an example. When using C++, it is probably +the best to put static methods into the *Class structures, which will +delegate to non-static methods. + +What to Implement +----------------- +There are two interfaces, which must at least be implemented, +DwRenderPlatform and DwRenderView. For details, see the comments in +dw_render.h. DwRenderPlatform is relatively simple, it provides some +(nearly) static, platform-specific properties. DwRenderView is rather +abstract, read DwRender.txt for possible implementations. However, +most important is a viewport implementation, this is also the only +current (Gtk+) implementation. + +Important note: Coordinates in the implementation of DwRenderView are +always world coordinates, so it may be to convert them into viewport +coordinates, when the implementation uses a small window for the +viewport (which is recommended for reasons immediately +following). Also, world coordinates are 32 bits, since 16 bits would +not be enough for the dimensions of a typical web page. + +The following functions will have to be called by the view, see the +comments in dw_render.c for details: + + p_Dw_render_layout_expose + p_Dw_render_layout_button_press + p_Dw_render_layout_button_release + p_Dw_render_layout_motion_notify + p_Dw_render_layout_enter_notify + p_Dw_render_layout_leave_notify + p_Dw_render_layout_scroll_pos_changed + p_Dw_render_layout_viewport_size_changed + +The first argument is always the layout, which has been passed to the +view in DwRenderView::set_layout. + + +Dw_style and Dw_tooltip +======================= + +These two modules are still bound to the Gtk+ platform, and so must be +re-implemented, which should, per se, not cause many problems. The +interfaces of these modules are kept in a way, which makes +toolkit-independant usage, e.g. whithin implementations of DwWidget +possible, e.g. by some simple typedef's (GdkGC -> DwGC +etc.). Dw_style_draw itself is independant of the toolkit. + +(This approach is possible on the long term, but will make it +impossible, to use multiple platforms at one time, see DwRender.txt +for details.) + + +UI Widgets +========== + +Embedding UI Widgets (buttons, entries, ...) into the Dw tree is +completly platform specific, see DwRender.txt, section "UI +Widgets". The Gtk+ implementation will reuse Gtk+ widgets, which are +embedded via a special Dw widget. This approach should be preferred in +other implementations. + +At least in Gtk+, embedding Gtk+ widgets is rather tricky, because the +world coordinates are represented by 32 bits. In Gtk+, this is solved +by using the widget GtkLayout as a base for the viewport, which does +some weird stuff like event filtering. An alternative implementation +should deal with this problem in a very early stage of development. + + +Images +====== + +There is another module, which has to be replaced, Imgbuf, which is +described in doc/Imgbuf.txt. Most of its interface should remain, the +only exception is a_Imgbuf_draw, which is only used by GtkDwViewport. + +A view must implement the method draw_image(), which will typically be +delegated to the image buffer (see Dw_gtk_viewport_draw_image() as an +example). The Gtk+ implementation does not use the passed DwGC, but +for portability, this remains in the platform independant part. + +DwImage should remain platform independant, all platform specific code +has been moved into Imgbuf.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/config.h.in Sun Oct 07 00:36:34 2007 +0200 @@ -0,0 +1,106 @@ +/* config.h.in. Generated from configure.in by autoheader. */ + +/* Enable GIF images */ +#undef ENABLE_GIF + +/* Enable JPEG images */ +#undef ENABLE_JPEG + +/* Enable PNG images */ +#undef ENABLE_PNG + +/* Enable SSL support */ +#undef ENABLE_SSL + +/* Define to 1 if you have the <fcntl.h> header file. */ +#undef HAVE_FCNTL_H + +/* Define to 1 if you have the `gethostbyname' function. */ +#undef HAVE_GETHOSTBYNAME + +/* Define to 1 if you have the <inttypes.h> header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `nsl' library (-lnsl). */ +#undef HAVE_LIBNSL + +/* Define to 1 if you have the <libpng/png.h> header file. */ +#undef HAVE_LIBPNG_PNG_H + +/* Define to 1 if you have the `socket' library (-lsocket). */ +#undef HAVE_LIBSOCKET + +/* Define to 1 if you have the <memory.h> header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the <png.h> header file. */ +#undef HAVE_PNG_H + +/* Define to 1 if you have the `setsockopt' function. */ +#undef HAVE_SETSOCKOPT + +/* Define to 1 if you have the <stdint.h> header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the <stdlib.h> header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the <strings.h> header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the <string.h> header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the <sys/types.h> header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the <sys/uio.h> header file. */ +#undef HAVE_SYS_UIO_H + +/* Define to 1 if you have the <unistd.h> header file. */ +#undef HAVE_UNISTD_H + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* The size of `char', as computed by sizeof. */ +#undef SIZEOF_CHAR + +/* The size of `int', as computed by sizeof. */ +#undef SIZEOF_INT + +/* The size of `long', as computed by sizeof. */ +#undef SIZEOF_LONG + +/* The size of `short', as computed by sizeof. */ +#undef SIZEOF_SHORT + +/* The size of `void *', as computed by sizeof. */ +#undef SIZEOF_VOID_P + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Version number of package */ +#undef VERSION + +/* Define the real type of socklen_t */ +#undef socklen_t
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/configure.in Sun Oct 07 00:36:34 2007 +0200 @@ -0,0 +1,475 @@ +dnl Process this file with aclocal, autoconf and automake. + +AC_INIT(src/dillo.cc) + +dnl Detect the canonical host and target build environment +AC_CANONICAL_SYSTEM + +AM_INIT_AUTOMAKE(dillo, f15) +AM_CONFIG_HEADER(config.h) + +dnl Options + +AC_ARG_WITH(jpeg-lib, [ --with-jpeg-lib=DIR Specify where to find libjpeg], LIBJPEG_LIBDIR=$withval) +AC_ARG_WITH(jpeg-inc, [ --with-jpeg-inc=DIR Specify where to find libjpeg's headers], LIBJPEG_INCDIR=$withval) + +AC_ARG_ENABLE(efence, [ --enable-efence Try to compile and run with Electric Fence], + , enable_efence=no) +AC_ARG_ENABLE(gprof, [ --enable-gprof Try to compile and run with profiling enabled], + , enable_gprof=no) +AC_ARG_ENABLE(insure, [ --enable-insure Try to compile and run with Insure++], + , enable_insure=no) +AC_ARG_ENABLE(ansi, [ --enable-ansi Try to compile and run with ANSI flags], + , enable_ansi=no) +AC_ARG_ENABLE(ipv6, [ --enable-ipv6 Build with support for IPv6], , ) +AC_ARG_ENABLE(rtfl, [ --enable-rtfl Build with rtfl messages], enable_rtfl=yes) +AC_ARG_ENABLE(cookies,[ --disable-cookies Don't compile support for cookies], + , enable_cookies=yes) +AC_ARG_ENABLE(png, [ --disable-png Disable support for PNG images], + enable_png=$enableval, enable_png=yes) +AC_ARG_ENABLE(jpeg, [ --disable-jpeg Disable support for JPEG images], + enable_jpeg=$enableval, enable_jpeg=yes) +AC_ARG_ENABLE(gif, [ --disable-gif Disable support for GIF images], + enable_gif=$enableval, enable_gif=yes) +AC_ARG_ENABLE(ssl, [ --disable-ssl Disable ssl features (eg. https)], + enable_ssl=$enableval, enable_ssl=yes) +AC_ARG_ENABLE(threaded-dns,[ --disable-threaded-dns Disable the advantage of a reentrant resolver library], + enable_threaded_dns=$enableval, enable_threaded_dns=yes) + +AC_PROG_CC +AC_PROG_CXX +AM_PROG_CC_STDC +AC_PROG_RANLIB +AC_PROG_CPP + +dnl ---------------------------- +dnl Check our char and int types +dnl ---------------------------- +dnl +AC_CHECK_SIZEOF(char) +AC_CHECK_SIZEOF(short) +AC_CHECK_SIZEOF(long) +AC_CHECK_SIZEOF(int) +AC_CHECK_SIZEOF(void *) + +case 2 in +$ac_cv_sizeof_short) gint16=short;; +$ac_cv_sizeof_int) gint16=int;; +esac +case 4 in +$ac_cv_sizeof_short) gint32=short;; +$ac_cv_sizeof_int) gint32=int;; +$ac_cv_sizeof_long) gint32=long;; +esac + +cat >d_size.h <<_______EOF +#ifndef __D_SIZE_H__ +#define __D_SIZE_H__ + + +#include "config.h" + +#if HAVE_STDINT_H == 0 +#include <stdint.h> +#else +typedef signed $gint16 int16_t; +typedef unsigned $gint16 uint16_t; +typedef signed $gint32 int32_t; +typedef unsigned $gint32 uint32_t; +#endif +typedef unsigned char uchar_t; +typedef unsigned short ushort_t; +typedef unsigned long ulong_t; +typedef unsigned int uint_t; +typedef int bool_t; + + +#endif /* __D_SIZE_H__ */ +_______EOF + + +dnl -------------------------------------- +dnl Check whether to add /usr/local or not +dnl (this is somewhat a religious problem) +dnl -------------------------------------- +dnl +if test "`$CPP -v < /dev/null 2>&1 | grep '/usr/local/include' 2>&1`" = ""; then + CPPFLAGS="$CPPFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib" +fi + +dnl ------------------------------------ +dnl Check for socket libs (AIX, Solaris) +dnl ------------------------------------ +dnl +AC_CHECK_FUNCS(gethostbyname,, + [AC_CHECK_LIB(nsl,gethostbyname,,[AC_CHECK_LIB(socket,gethostbyname)])]) +AC_CHECK_FUNCS(setsockopt,,[AC_CHECK_LIB(socket,setsockopt)]) + +dnl -------------------- +dnl Checks for socklen_t +dnl -------------------- +dnl +AC_MSG_CHECKING([for socklen_t]) +ac_cv_socklen_t="" +AC_TRY_COMPILE([ +#include <sys/types.h> +#include <sys/socket.h> +],[ +socklen_t a=0; +getsockname(0,(struct sockaddr*)0, &a); +], +ac_cv_socklen_t="socklen_t", +AC_TRY_COMPILE([ +#include <sys/types.h> +#include <sys/socket.h> +],[ +int a=0; +getsockname(0,(struct sockaddr*)0, &a); +], +ac_cv_socklen_t="int", +ac_cv_socklen_t="size_t" +) +) +AC_MSG_RESULT($ac_cv_socklen_t) +if test "$ac_cv_socklen_t" != "socklen_t"; then + AC_DEFINE_UNQUOTED(socklen_t, $ac_cv_socklen_t, + [Define the real type of socklen_t]) +fi + + +dnl ---------------------- +dnl Test for FLTK2 library +dnl ---------------------- +dnl +dnl For debugging and to be user friendly +AC_MSG_CHECKING([FLTK2]) +if sh -c "fltk2-config --version" >/dev/null 2>&1 +then AC_MSG_RESULT(yes) + LIBFLTK_CXXFLAGS=`fltk2-config --cxxflags` + LIBFLTK_LIBS=`fltk2-config --use-images --ldflags` +else if sh -c "fltk-config --version" >/dev/null 2>&1 + then AC_MSG_RESULT(yes) + LIBFLTK_CXXFLAGS=`fltk-config --cxxflags` + LIBFLTK_LIBS=`fltk-config --ldflags` + else AC_MSG_RESULT(no) + AC_ERROR(FLTK2 must be installed!) + fi +fi + + +dnl ---------------- +dnl Test for libjpeg +dnl ---------------- +dnl +if test "x$enable_jpeg" = "xyes"; then + AC_CHECK_HEADER(jpeglib.h, jpeg_ok=yes, jpeg_ok=no) + + if test "x$jpeg_ok" = "xyes"; then + old_libs="$LIBS" + AC_CHECK_LIB(jpeg, jpeg_destroy_decompress, jpeg_ok=yes, jpeg_ok=no) + LIBS="$old_libs" + fi + + if test "x$jpeg_ok" = "xyes"; then + LIBJPEG_LIBS="-ljpeg" + if test -n "$LIBJPEG_LIBDIR"; then + LIBJPEG_LDFLAGS="-L$LIBJPEG_LIBDIR" + fi + if test -n "$LIBJPEG_INCDIR"; then + LIBJPEG_CPPFLAGS="-I$LIBJPEG_INCDIR" + fi + else + AC_MSG_WARN([*** No libjpeg found. Disabling jpeg images.***]) + fi +fi + +if test "x$jpeg_ok" = "xyes"; then + AC_DEFINE([ENABLE_JPEG], [], [Enable JPEG images]) +fi + +dnl ------------------------------ +dnl Test for zlib (libpng uses it) +dnl ------------------------------ +dnl +if test "x$enable_png" = "xyes"; then + AC_CHECK_HEADER(zlib.h, libz_ok=yes, libz_ok=no) + + if test "x$libz_ok" = "xyes"; then + old_libs="$LIBS" + AC_CHECK_LIB(z, zlibVersion, libz_ok=yes, libz_ok=no) + LIBS="$old_libs" + fi + + if test "x$libz_ok" = xyes; then + LIBZ_LIBS="-lz" + else + AC_MSG_WARN([*** No libz found. Disabling PNG images ***]) + fi +fi + +dnl --------------- +dnl Test for libpng +dnl --------------- +dnl +if test "x$enable_png" = "xyes" && test "x$libz_ok" = "xyes"; then + AC_MSG_CHECKING([for libpng-config]) + +dnl Check if the user hasn't set the variable $PNG_CONFIG + if test -z "$PNG_CONFIG"; then + PNG_CONFIG=`which libpng12-config` + if test -z "$PNG_CONFIG"; then + PNG_CONFIG=`which libpng-config` + fi + if test -z "$PNG_CONFIG"; then + PNG_CONFIG=`which libpng10-config` + fi + fi + +dnl Check if the libpng-config script was found and is executable + if test -n "$PNG_CONFIG" && test -x "$PNG_CONFIG"; then + AC_MSG_RESULT([$PNG_CONFIG]) + png_ok="yes" + else + AC_MSG_RESULT([missing]) + png_ok="no" + fi + + if test "x$png_ok" = "xyes"; then +dnl For debugging and to be user friendly + AC_MSG_CHECKING([for libpng version]) + png_version=`$PNG_CONFIG --version` + case $png_version in + 1.2.*) AC_MSG_RESULT([$png_version (newer version)]) ;; + 1.0.*) AC_MSG_RESULT([$png_version (older version)]) ;; + *) AC_MSG_RESULT([ERROR]) ;; + esac + +dnl Try to use options that are supported by all libpng-config versions... + LIBPNG_CFLAGS=`$PNG_CONFIG --cflags` + LIBPNG_LIBS=`$PNG_CONFIG --ldflags` + case $png_version in + 1.2.4*) LIBPNG_LIBS="$LIBPNG_LIBS `$PNG_CONFIG --libs`" ;; + esac + else +dnl Try to find libpng even though libpng-config wasn't found + AC_CHECK_HEADERS(png.h libpng/png.h, png_ok=yes && break, png_ok=no) + + if test "x$png_ok" = "xyes"; then + old_libs="$LIBS" + AC_CHECK_LIB(png, png_check_sig, png_ok=yes, png_ok=no, $LIBZ_LIBS -lm) + LIBS="$old_libs" + + if test "x$png_ok" = "xyes"; then + LIBPNG_LIBS="-lpng -lm" + fi + fi + + if test "x$png_ok" = "xno"; then + AC_MSG_WARN([*** No libpng found. Disabling PNG images ***]) + fi + fi +fi + +if test "x$png_ok" = "xyes"; then + AC_DEFINE([ENABLE_PNG], [], [Enable PNG images]) +fi + +dnl Check if support for GIF images should be compiled in +if test "x$enable_gif" = "xyes"; then + AC_DEFINE([ENABLE_GIF], [], [Enable GIF images]) +fi + +dnl -------------------------- +dnl Test for support for SSL +dnl -------------------------- +dnl +if test "x$enable_ssl" = "xyes"; then + AC_CHECK_HEADER(openssl/ssl.h, ssl_ok=yes, ssl_ok=no) + + if test "x$ssl_ok" = "xyes"; then + old_libs="$LIBS" + AC_CHECK_LIB(ssl, SSL_library_init, ssl_ok=yes, ssl_ok=no, -lcrypto) + LIBS="$old_libs" + fi + + if test "x$ssl_ok" = "xyes"; then + LIBSSL_LIBS="-lcrypto -lssl" + else + AC_MSG_WARN([*** No libssl found. Disabling ssl support.***]) + fi +fi + +if test "x$ssl_ok" = "xyes"; then + AC_DEFINE([ENABLE_SSL], [], [Enable SSL support]) +fi + + +dnl ---------------------- +dnl Test for POSIX threads +dnl ---------------------- +dnl +if test -z "$LIBPTHREAD_LIBS"; then +case $target in + *-*-linux*|*-*-solaris*) + old_libs="$LIBS" + AC_CHECK_LIB(pthread, pthread_create, LIBPTHREAD_LIBS="-lpthread") + LIBS="$old_libs" + ;; + + *-*-osf1*) + AC_MSG_CHECKING(whether pthreads work) + LIBPTHREAD_LIBS="-lpthread -lexc -ldb" + AC_MSG_WARN([*** _Untested pthreads_ try setting LIBPTHREAD_LIBS manually if it doesn't work ***]) + ;; + + *) + AC_MSG_CHECKING(whether threads work with -pthread) + LDSAVEFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -pthread" + AC_TRY_LINK_FUNC(pthread_create, pthread_ok=yes, pthread_ok=no) + LDFLAGS=$LDSAVEFLAGS + + if test "x$pthread_ok" = "xyes"; then + AC_MSG_RESULT(yes) + LIBPTHREAD_LDFLAGS="-pthread" + else + AC_MSG_RESULT(no. Now we will try some libraries.) + + AC_SEARCH_LIBS(pthread_create, pthread, + LIBPTHREADS_LIBS="-lpthread", + AC_SEARCH_LIBS(pthread_create, pthreads, + LIBPTHREADS_LIBS="-lpthreads", + AC_SEARCH_LIBS(pthread_create, c_r, + LIBPTHREADS_LIBS="-lc_r", thread_ok=no))) + + if test "x$thread_ok" = "xno"; then + AC_MSG_WARN([*** No pthreads found. ***]) + AC_MSG_ERROR([*** Try setting LIBPTHREAD_LIBS manually to point to your pthreads library. ***]) + exit 1 + else + AC_MSG_WARN([found a way to link threads, but it may not work...]) + fi + fi + ;; + +esac +fi + +dnl ------------------------------------ +dnl Workaround for nanosleep and solaris +dnl ------------------------------------ +dnl +case $target in + *-*-solaris*) + AC_MSG_CHECKING(whether SunOS has -lrt ) + LDSAVEFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -lrt" + AC_TRY_LINK_FUNC(nanosleep, rt_ok=yes, rt_ok=no) + if test "x$rt_ok" = "xyes"; then + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + AC_MSG_CHECKING(whether SunOS has -lposix4 ) + LDFLAGS="$LDSAVEFLAGS -lposix4" + AC_TRY_LINK_FUNC(nanosleep, posix_ok=yes, posix_ok=no) + if test "x$posix_ok" = "xyes"; then + AC_MSG_RESULT(yes) + else + LDFLAGS=$LDSAVEFLAGS + AC_MSG_RESULT(no) + AC_MSG_WARN([*** Try setting LIBS or LDFLAGS manually to point to the library with nanosleep()***]) + fi + fi + ;; +esac + +dnl -------------------- +dnl Command line options +dnl -------------------- +dnl +if test "x$enable_cookies" = "xno" ; then + CFLAGS="$CFLAGS -DDISABLE_COOKIES" +fi +if test "x$enable_ipv6" = "xyes" ; then + CFLAGS="$CFLAGS -DENABLE_IPV6" +fi +if test "x$enable_efence" = "xyes" ; then + LIBS="-lefence $LIBS" +fi +if test "x$enable_gprof" = "xyes" ; then + CFLAGS="$CFLAGS -pg" +fi +if test "x$enable_insure" = "xyes" ; then + CC="insure -Zoi \"compiler $CC\"" + LIBS="$LIBS -lstdc++-2-libc6.1-1-2.9.0" +fi +if test "x$enable_rtfl" = "xyes" ; then + CFLAGS="$CFLAGS -DDBG_RTFL" +fi +if test "x$enable_threaded_dns" = "xyes" ; then + CFLAGS="$CFLAGS -DD_DNS_THREADED" +fi + +dnl ----------------------- +dnl Checks for header files +dnl ----------------------- +dnl +AC_HEADER_STDC +AC_CHECK_HEADERS(fcntl.h unistd.h sys/uio.h) + +dnl -------------------------- +dnl Check for compiler options +dnl -------------------------- +dnl +if eval "test x$GCC = xyes"; then + if test "`echo $CFLAGS | grep '\-D_REENTRANT' 2> /dev/null`" = ""; then + CFLAGS="$CFLAGS -D_REENTRANT" + fi + if test "`echo $CFLAGS | grep '\-D_THREAD_SAFE' 2> /dev/null`" = ""; then + CFLAGS="$CFLAGS -D_THREAD_SAFE" + fi + if test "`echo $CFLAGS | grep '\-Wall' 2> /dev/null`" = ""; then + CFLAGS="$CFLAGS -Wall" + fi + if test "`echo $CFLAGS | grep '\-W[^a]' 2> /dev/null`" = ""; then + if test "`$CC -v 2>&1 | grep 'version 3'`" != ""; then + CFLAGS="$CFLAGS -W -Wno-unused-parameter" + fi + fi + if test "`echo $CFLAGS | grep '\-Waggregate-return' 2> /dev/null`" = ""; then + CFLAGS="$CFLAGS -Waggregate-return" + fi + + if eval "test x$enable_ansi = xyes"; then + if test "`echo $CFLAGS | grep '\-ansi' 2> /dev/null`" = ""; then + CFLAGS="$CFLAGS -ansi" + fi + + if test "`echo $CFLAGS | grep '\-pedantic' 2> /dev/null`" = ""; then + CFLAGS="$CFLAGS -pedantic" + fi + fi +fi +dnl ----------- +dnl CXX options +dnl ----------- +dnl +CXXFLAGS="$CXXFLAGS -Wall -W -Wno-unused-parameter" + +AC_SUBST(LIBJPEG_LIBS) +AC_SUBST(LIBJPEG_LDFLAGS) +AC_SUBST(LIBJPEG_CPPFLAGS) +AC_SUBST(LIBPNG_LIBS) +AC_SUBST(LIBPNG_CFLAGS) +AC_SUBST(LIBZ_LIBS) +AC_SUBST(LIBSSL_LIBS) +AC_SUBST(LIBPTHREAD_LIBS) +AC_SUBST(LIBPTHREAD_LDFLAGS) +AC_SUBST(LIBFLTK_CXXFLAGS) +AC_SUBST(LIBFLTK_LIBS) +AC_SUBST(datadir) +AC_SUBST(src doc) + +AC_OUTPUT(Makefile dlib/Makefile dpip/Makefile dpid/Makefile dpi/Makefile doc/Makefile src/Makefile src/IO/Makefile) +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dillorc2 Sun Oct 07 00:36:34 2007 +0200 @@ -0,0 +1,194 @@ +# dillorc +# Sample dillo initialization file. +# Lines that start with a '#' are comments. + + +#------------------------------------------------------------------------- +# FIRST SECTION :) +#------------------------------------------------------------------------- + +# Set the desired initial browser size +#geometry=820x650 +#geometry=650x545 +geometry=725x545 + +# Dicache is where the Decompressed Images are cached (not the original ones). +# If you have a lot of memory and a slow CPU, use YES, otherwise use NO +use_dicache=NO + + +#------------------------------------------------------------------------- +# RENDERING SECTION +#------------------------------------------------------------------------- + +# Fontname for variable width rendering (most of the text). +# - some fonts may slow down rendering, some others not! +# - try to tune a fontname/font_factor combination. +# Ex. {helvetica, lucida, times, "new century schoolbook", utopia, ...} +#vw_fontname="new century schoolbook" +#vw_fontname="helvetica" +#vw_fontname="times" +#vw_fontname="Bitstream vera Serif" +#vw_fontname="arial" +vw_fontname="DejaVu Sans" + +# Fontname for fixed width rendering (mainly text quoted with <pre>) +#fw_fontname=courier +#fw_fontname="Bitstream Vera Sans Mono" +#fw_fontname="Andale Mono" +fw_fontname="DejaVu Sans Mono" + +# All fontsizes are scaled by this value (default is 1.0) +#font_factor=1.2 +font_factor=1.5 + +# If you prefer oblique over italic fonts, uncoment next line +#use_oblique=YES + +# Show tooltip popup for images? +# Note: We use the "title" attribute and not "alt". +# More info at: http://bugzilla.mozilla.org/show_bug.cgi?id=25537 +show_tooltip=YES + +# Set this to YES, if you want to limit the word wrap width to the vieport +# width (may be useful for iPAQ) +limit_text_width=NO + + +#------------------------------------------------------------------------- +# PARSING SECTION +#------------------------------------------------------------------------- + +# If you prefer more accurate HTML bug diagnose, over better rendering +# (page authors and webmasters) set the following to "NO". +# +w3c_plus_heuristics=YES + + +#------------------------------------------------------------------------- +# NETWORK SECTION +#------------------------------------------------------------------------- + +# Set the start page. +# Uncomment if you want to override the default start page. +#start_page="file:/home/jcid/Thinkpad385XD.html" + +# Set the home location +#home="http://dillo.cipsga.org.br/" +home="file:/home/jcid/HomePage/Home.html" + +# Set search url to use with "s <keywords>". +# %s is replaced with keywords separated by '+'. +#search_url="http://search.lycos.com/default.asp?query=%s" +#search_url="http://www.alltheweb.com/search?cat=web&query=%s" +search_url="http://www.google.com/search?q=%s" + +# Set the proxy information for http +#http_proxy=http://localhost:8080/ + +# if you need to provide a user/password pair for the proxy, +# set the proxy user name here and Dillo will ask for the password later. +#http_proxyuser="joe" + +# Set the domains to access without proxy +#no_proxy = ".hola.com .mynet.cl .hi.de" + + +#------------------------------------------------------------------------- +# COLORS SECTION +#------------------------------------------------------------------------- + +# Here we can use the HTML color names or C syntax. + +# Set the background color +# bg_color=gray +# bg_color=0xd6d6c0 +bg_color=0xdcd1ba + +# Set the text color +text_color=black + +# Set the link color +link_color=blue + +# If your eyes don't suffer with white backgrounds, or you need +# high contrast to see sharply, uncomment next line. +allow_white_bg=NO + +# Use the same colors with all documents? +#force_my_colors=YES + +# When set to YES, visited links always have a characteristic color, +# independent of the author's setting. +contrast_visited_color=YES + + +#------------------------------------------------------------------------- +# USER INTERFACE SECTION +#------------------------------------------------------------------------- + +# Size of dillo panel (used to enlarge the browsing area) +# tiny : recommended for iPAQ (with small_icons) +# small : very nice! (it's "medium" without icon titles) +# medium : nice! +# large : Traditional +#panel_size=tiny +panel_size=small +#panel_size=medium +#panel_size=large +small_icons=NO + +# Here you can choose to hide some widgets of the dillo panel... +#show_back=NO +#show_forw=NO +#show_home=NO +#show_reload=NO +#show_save=NO +#show_stop=NO +#show_bookmarks=NO +show_menubar=YES +#show_clear_url=NO +#show_url=NO +#show_search=NO +#show_progress_box=NO + +# Start dillo windows with a hidden panel? +fullwindow_start=NO + +# Enabling this will restrain OpenUrl and FindText, but may be required +# for the ION window manager. +transient_dialogs=NO + +# When filling forms, our default behaviour is to submit on enterpress, +# but only when there's a single text entry (to avoid incomplete submits). +# OTOH, if you have to fill the same form lots of times, you may find +# useful to keep away from the mouse by forcing enter to submit. +enterpress_forces_submit=NO + +# Some forms lack a submit button, and dillo can generate a custom one +# internally. Unfortunately there's no guarantee for it to work. :( +# (my experience is that forms that lack a submit rely on Javascript) +generate_submit=NO + +#------------------------------------------------------------------------- +# DEBUG MESSAGES SECTION +#------------------------------------------------------------------------- + +# Soon we should add the "show_debug_messages=NO" option... + +# Generic messsages (mainly for debugging specific parts) +# Uncomment the following line to disable them. +#show_msg=NO + + +#------------------------------------------------------------------------- +# HTML BUG MESSAGES SECTION +#------------------------------------------------------------------------- + +# Accepted by the W3C validator but "strongly discouraged" by the SPEC. +# (As "TAB character inside <PRE>"). +#show_extra_warnings=YES + + +# ----------------------------------------------------------------------- +# dillorc ends here.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dlib/Makefile.am Sun Oct 07 00:36:34 2007 +0200 @@ -0,0 +1,6 @@ +noinst_LIBRARIES = libDlib.a + +libDlib_a_SOURCES = \ + dlib.h \ + dlib.c +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dlib/dlib.c Sun Oct 07 00:36:34 2007 +0200 @@ -0,0 +1,750 @@ +/* + * File: dlib.c + * + * Copyright (C) 2006 Jorge Arellano Cid <jcid@dillo.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + */ + +/* Memory allocation, Simple dynamic strings, Lists (simple and sorted), + * and a few utility functions + */ + +/* + * TODO: vsnprintf() is in C99, maybe a simple replacement if necessary. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <unistd.h> +#include <errno.h> +#include <ctype.h> + +#include "dlib.h" + +/* + *- Memory -------------------------------------------------------------------- + */ + +void *dMalloc (size_t size) +{ + void *value = malloc (size); + if (value == 0) + exit(1); + return value; +} + +void *dRealloc (void *mem, size_t size) +{ + void *value = realloc (mem, size); + if (value == 0) + exit(1); + return value; +} + +void *dMalloc0 (size_t size) +{ + void *value = dMalloc (size); + memset (value, 0, size); + return value; +} + +void dFree (void *mem) +{ + if (mem) + free(mem); +} + +/* + *- strings (char *) ---------------------------------------------------------- + */ + +char *dStrdup(const char *s) +{ + if (s) { + int len = strlen(s)+1; + char *ns = dNew(char, len); + memcpy(ns, s, len); + return ns; + } + return NULL; +} + +char *dStrndup(const char *s, size_t sz) +{ + if (s) { + char *ns = dNew(char, sz+1); + memcpy(ns, s, sz); + ns[sz] = 0; + return ns; + } + return NULL; +} + +/* + * Concatenate a NULL-terminated list of strings + */ +char *dStrconcat(const char *s1, ...) +{ + va_list args; + char *s, *ns = NULL; + + if (s1) { + Dstr *dstr = dStr_sized_new(64); + va_start(args, s1); + for (s = (char*)s1; s; s = va_arg(args, char*)) + dStr_append(dstr, s); + va_end(args); + ns = dstr->str; + dStr_free(dstr, 0); + } + return ns; +} + +/* + * Remove leading and trailing whitespace + */ +char *dStrstrip(char *s) +{ + char *p; + int len; + + if (s && *s) { + for (p = s; isspace(*p); ++p); + for (len = strlen(p); len && isspace(p[len-1]); --len); + if (p > s) + memmove(s, p, len); + s[len] = 0; + } + return s; +} + +/* + * Return a new string of length 'len' filled with 'c' characters + */ +char *dStrnfill(size_t len, char c) +{ + char *ret = dNew(char, len+1); + for (ret[len] = 0; len > 0; ret[--len] = c); + return ret; +} + +/* + * strsep() implementation + */ +char *dStrsep(char **orig, const char *delim) +{ + char *str, *p; + + if (!(str = *orig)) + return NULL; + + p = strpbrk(str, delim); + if (p) { + *p++ = 0; + *orig = p; + } else { + *orig = NULL; + } + return str; +} + +/* + * Case insensitive strstr + */ +char *dStristr(const char *haystack, const char *needle) +{ + int i, j; + + for (i = 0, j = 0; haystack[i] && needle[j]; ++i) + if (tolower(haystack[i]) == tolower(needle[j])) { + ++j; + } else if (j) { + i -= j; + j = 0; + } + + if (!needle[j]) /* Got all */ + return (char *)(haystack + i - j); + return NULL; +} + + +/* + *- dStr ---------------------------------------------------------------------- + */ + +/* + * Private allocator + */ +static void dStr_resize(Dstr *ds, int n_sz, int keep) +{ + if (n_sz >= 0) { + if (keep && n_sz > ds->len) { + ds->str = (Dstr_char_t*) dRealloc (ds->str, n_sz*sizeof(Dstr_char_t)); + ds->sz = n_sz; + } else { + if (ds->str) + free(ds->str); + ds->str = dNew(Dstr_char_t, n_sz); + ds->sz = n_sz; + ds->len = 0; + ds->str[0] = 0; + } + } +} + +/* + * Create a new string with a given size. + * Initialized to "" + */ +Dstr *dStr_sized_new (int sz) +{ + if (sz < 2) + sz = 2; + + Dstr *ds = dNew(Dstr, 1); + ds->str = NULL; + dStr_resize(ds, sz, 0); + return ds; +} + +/* + * Return memory if there's too much allocated + */ +void dStr_fit (Dstr *ds) +{ + dStr_resize(ds, ds->len + 1, 1); +} + +/* + * Insert a C string, at a given position, into a Dstr (providing length). + * Note: It also works with embedded nil characters. + */ +void dStr_insert_l (Dstr *ds, int pos_0, const char *s, int l) +{ + int n_sz; + + if (ds && s && l && pos_0 >= 0 && pos_0 <= ds->len) { + for (n_sz = ds->sz; ds->len + l >= n_sz; n_sz *= 2); + if (n_sz > ds->sz) { + dStr_resize(ds, n_sz, (ds->len > 0) ? 1 : 0); + } + if (pos_0 < ds->len) + memmove(ds->str+pos_0+l, ds->str+pos_0, ds->len-pos_0); + memcpy(ds->str+pos_0, s, l); + ds->len += l; + ds->str[ds->len] = 0; + } +} + +/* + * Insert a C string, at a given position, into a Dstr + */ +void dStr_insert (Dstr *ds, int pos_0, const char *s) +{ + if (s) + dStr_insert_l(ds, pos_0, s, strlen(s)); +} + +/* + * Append a C string to a Dstr (providing length). + * Note: It also works with embedded nil characters. + */ +void dStr_append_l (Dstr *ds, const char *s, int l) +{ + dStr_insert_l(ds, ds->len, s, l); +} + +/* + * Append a C string to a Dstr. + */ +void dStr_append (Dstr *ds, const char *s) +{ + dStr_append_l(ds, s, strlen(s)); +} + +/* + * Create a new string. + * Initialized to 's' or empty if 's == NULL' + */ +Dstr *dStr_new (const char *s) +{ + Dstr *ds = dStr_sized_new(0); + if (s) + dStr_append(ds, s); + return ds; +} + +/* + * Free a dillo string. + * if 'all' free everything, else free the structure only. + */ +void dStr_free (Dstr *ds, int all) +{ + if (ds) { + if (all && ds->str) + free(ds->str); + free(ds); + } +} + +/* + * Append one character. + */ +void dStr_append_c (Dstr *ds, int c) +{ + char cs[2]; + + if (ds) { + if (ds->sz > ds->len + 1) { + ds->str[ds->len++] = (Dstr_char_t)c; + ds->str[ds->len] = 0; + } else { + cs[0] = (Dstr_char_t)c; + cs[1] = 0; + dStr_append_l (ds, cs, 1); + } + } +} + +/* + * Truncate a Dstr to be 'len' bytes long. + */ +void dStr_truncate (Dstr *ds, int len) +{ + if (ds && len < ds->len) { + ds->str[len] = 0; + ds->len = len; + } +} + +/* + * Erase a substring. + */ +void dStr_erase (Dstr *ds, int pos_0, int len) +{ + if (ds && pos_0 >= 0 && len > 0 && pos_0 + len <= ds->len) { + memmove(ds->str + pos_0, ds->str + pos_0 + len, ds->len - pos_0 - len); + ds->len -= len; + ds->str[ds->len] = 0; + } +} + +/* + * vsprintf-like function that appends. + * Used by: dStr_vsprintf(), dStr_sprintf() and dStr_sprintfa(). + */ +void dStr_vsprintfa (Dstr *ds, const char *format, va_list argp) +{ + int n, n_sz; + + if (ds && format) { + while (1) { + n = vsnprintf(ds->str + ds->len, ds->sz - ds->len, format, argp); + if (n > -1 && n < ds->sz - ds->len) { + ds->len += n; /* Success! */ + break; + } else if (n > -1) { /* glibc >= 2.1 */ + n_sz = ds->len + n + 1; + } else { /* old glibc */ + n_sz = ds->sz * 2; + } + dStr_resize(ds, n_sz, (ds->len > 0) ? 1 : 0); + } + } +} + +/* + * vsprintf-like function. + */ +void dStr_vsprintf (Dstr *ds, const char *format, va_list argp) +{ + if (ds) { + dStr_truncate(ds, 0); + dStr_vsprintfa(ds, format, argp); + } +} + +/* + * Printf-like function + */ +void dStr_sprintf (Dstr *ds, const char *format, ...) +{ + va_list argp; + + if (ds && format) { + va_start(argp, format); + dStr_vsprintf(ds, format, argp); + va_end(argp); + } +} + +/* + * Printf-like function that appends. + */ +void dStr_sprintfa (Dstr *ds, const char *format, ...) +{ + va_list argp; + + if (ds && format) { + va_start(argp, format); + dStr_vsprintfa(ds, format, argp); + va_end(argp); + } +} + +/* + *- dList --------------------------------------------------------------------- + */ + +/* + * Create a new empty list + */ +Dlist *dList_new(int size) +{ + if (size <= 0) + return NULL; + + Dlist *l = dNew(Dlist, 1); + l->len = 0; + l->sz = size; + l->list = dNew(void*, l->sz); + return l; +} + +/* + * Free a list (not its elements) + */ +void dList_free (Dlist *lp) +{ + if (!lp) + return; + + dFree(lp->list); + dFree(lp); +} + +/* + * Insert an element at a given position [0 based] + */ +void dList_insert_pos (Dlist *lp, void *data, int pos0) +{ + int i; + + if (!lp || pos0 < 0 || pos0 > lp->len) + return; + + if (lp->sz == lp->len) { + lp->sz *= 2; + lp->list = (void**) dRealloc (lp->list, lp->sz*sizeof(void*)); + } + ++lp->len; + + for (i = lp->len - 1; i > pos0; --i) + lp->list[i] = lp->list[i - 1]; + lp->list[pos0] = data; +} + +/* + * Append a data item to the list + */ +void dList_append (Dlist *lp, void *data) +{ + dList_insert_pos(lp, data, lp->len); +} + +/* + * Prepend a data item to the list + */ +void dList_prepend (Dlist *lp, void *data) +{ + dList_insert_pos(lp, data, 0); +} + +/* + * For completing the ADT. + */ +int dList_length (Dlist *lp) +{ + if (!lp) + return 0; + return lp->len; +} + +/* + * Remove a data item without preserving order. + */ +void dList_remove_fast (Dlist *lp, const void *data) +{ + int i; + + if (!lp) + return; + + for (i = 0; i < lp->len; ++i) { + if (lp->list[i] == data) { + lp->list[i] = lp->list[--lp->len]; + break; + } + } +} + +/* + * Remove a data item preserving order. + */ +void dList_remove (Dlist *lp, const void *data) +{ + int i, j; + + if (!lp) + return; + + for (i = 0; i < lp->len; ++i) { + if (lp->list[i] == data) { + --lp->len; + for (j = i; j < lp->len; ++j) + lp->list[j] = lp->list[j + 1]; + break; + } + } +} + +/* + * Return the nth data item, + * NULL when not found or 'n0' is out of range + */ +void *dList_nth_data (Dlist *lp, int n0) +{ + if (!lp || n0 < 0 || n0 >= lp->len) + return NULL; + return lp->list[n0]; +} + +/* + * Return the found data item, or NULL if not present. + */ +void *dList_find (Dlist *lp, const void *data) +{ + int i = dList_find_idx(lp, data); + return (i >= 0) ? lp->list[i] : NULL; +} + +/* + * Search a data item. + * Return value: its index if found, -1 if not present. + * (this is useful for a list of integers, for finding number zero). + */ +int dList_find_idx (Dlist *lp, const void *data) +{ + int i, ret = -1; + + if (!lp) + return ret; + + for (i = 0; i < lp->len; ++i) { + if (lp->list[i] == data) { + ret = i; + break; + } + } + return ret; +} + +/* + * Search a data item using a custom function. + * func() is given the list item and the user data as parameters. + * Return: data item when found, NULL otherwise. + */ +void *dList_find_custom (Dlist *lp, const void *data, dCompareFunc func) +{ + int i; + void *ret = NULL; + + if (!lp) + return ret; + + for (i = 0; i < lp->len; ++i) { + if (func(lp->list[i], data) == 0) { + ret = lp->list[i]; + break; + } + } + return ret; +} + +/* + * QuickSort implementation. + * This allows for a simple compare function for all the ADT. + */ +static void QuickSort(void **left, void **right, dCompareFunc compare) +{ + void **p = left, **q = right, **t = left; + + while (1) { + while (p != t && compare(*p, *t) < 0) + ++p; + while (q != t && compare(*q, *t) > 0) + --q; + if (p > q) + break; + if (p < q) { + void *tmp = *p; + *p = *q; + *q = tmp; + if (t == p) + t = q; + else if (t == q) + t = p; + } + if (++p > --q) + break; + } + + if (left < q) + QuickSort(left, q, compare); + if (p < right) + QuickSort(p, right, compare); +} + +/* + * Sort the list using a custom function + */ +void dList_sort (Dlist *lp, dCompareFunc func) +{ + if (lp && lp->len > 1) { + QuickSort(lp->list, lp->list + lp->len - 1, func); + } +} + +/* + * Insert an element into a sorted list. + * The comparison function receives two list elements. + */ +void dList_insert_sorted (Dlist *lp, void *data, dCompareFunc func) +{ + int i, st, min, max; + + if (lp) { + min = st = i = 0; + max = lp->len - 1; + while (min <= max) { + i = (min + max) / 2; + st = func(lp->list[i], data); + if (st < 0) { + min = i + 1; + } else if (st > 0) { + max = i - 1; + } else { + break; + } + } + dList_insert_pos(lp, data, (st >= 0) ? i : i+1); + } +} + +/* + * Search a sorted list. + * Return the found data item, or NULL if not present. + * func() is given the list item and the user data as parameters. + */ +void *dList_find_sorted (Dlist *lp, const void *data, dCompareFunc func) +{ + int i, st, min, max; + void *ret = NULL; + + if (lp && lp->len) { + min = 0; + max = lp->len - 1; + while (min <= max) { + i = (min + max) / 2; + st = func(lp->list[i], data); + if (st < 0) { + min = i + 1; + } else if (st > 0) { + max = i - 1; + } else { + ret = lp->list[i]; + break; + } + } + } + + return ret; +} + +/* + *- Misc utility functions ---------------------------------------------------- + */ + +/* + * Return the current working directory in a new string + */ +char *dGetcwd () +{ + size_t size = 128; + + while (1) { + char *buffer = dNew(char, size); + if (getcwd (buffer, size) == buffer) + return buffer; + dFree (buffer); + if (errno != ERANGE) + return 0; + size *= 2; + } +} + +/* + * Return the home directory in a static string (don't free) + */ +char *dGethomedir () +{ + static char *homedir = NULL; + + if (!homedir) { + if (getenv("HOME")) { + homedir = dStrdup(getenv("HOME")); + + } else if (getenv("HOMEDRIVE") && getenv("HOMEPATH")) { + homedir = dStrconcat(getenv("HOMEDRIVE"), getenv("HOMEPATH"), NULL); + } + } + return homedir; +} + +/* + * Get a line from a FILE stream. + * It handles backslash as line-continues character. + * Return value: read line on success, NULL on EOF. + */ +char *dGetline (FILE *stream) +{ + int ch; + Dstr *dstr; + char *line; + + dReturn_val_if_fail (stream, 0); + + dstr = dStr_sized_new(64); + while((ch = fgetc(stream)) != EOF) { + if (ch == '\\') { + /* continue with the next line */ + while((ch = fgetc(stream)) != EOF && ch != '\n'); + continue; + } + dStr_append_c(dstr, ch); + if (ch == '\n') + break; + } + + line = (dstr->len) ? dstr->str : NULL; + dStr_free(dstr, (line) ? 0 : 1); + return line; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dlib/dlib.h Sun Oct 07 00:36:34 2007 +0200 @@ -0,0 +1,158 @@ +#ifndef __DLIB_H__ +#define __DLIB_H__ + +#include <stdio.h> /* for FILE* */ +#include <stddef.h> /* for size_t */ +#include <stdarg.h> /* for va_list */ +#include <string.h> /* for strerror */ +#include <strings.h> /* for strcasecmp, strncasecmp (POSIX 2001) */ + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + *-- Common macros ----------------------------------------------------------- + */ +#ifndef FALSE +#define FALSE (0) +#endif + +#ifndef TRUE +#define TRUE (!FALSE) +#endif + +#undef MAX +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) + +#undef MIN +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) + +/* + *-- Casts ------------------------------------------------------------------- + */ +/* TODO: include a void* size test in configure.in */ +#define VOIDP2INT(p) ((int)(p)) +#define INT2VOIDP(i) ((void*)(i)) + +/* + *-- Memory ------------------------------------------------------------------- + */ +#define dNew(type, count) \ + ((type *) dMalloc ((unsigned) sizeof (type) * (count))) +#define dNew0(type, count) \ + ((type *) dMalloc0 ((unsigned) sizeof (type) * (count))) + +void *dMalloc (size_t size); +void *dRealloc (void *mem, size_t size); +void *dMalloc0 (size_t size); +void dFree (void *mem); + +/* + *- Debug macros -------------------------------------------------------------- + */ +#define D_STMT_START do +#define D_STMT_END while (0) +#define dReturn_if_fail(expr) \ + D_STMT_START{ \ + if (!(expr)) { return; }; \ + }D_STMT_END +#define dReturn_val_if_fail(expr,val) \ + D_STMT_START{ \ + if (!(expr)) { return val; }; \ + }D_STMT_END + +/* + *- C strings ----------------------------------------------------------------- + */ +char *dStrdup(const char *s); +char *dStrndup(const char *s, size_t sz); +char *dStrconcat(const char *s1, ...); +char *dStrstrip(char *s); +char *dStrnfill(size_t len, char c); +char *dStrsep(char **orig, const char *delim); +char *dStristr(const char *haystack, const char *needle); + +/* these are in POSIX 2001. Could be implemented if a port requires it */ +#define dStrcasecmp strcasecmp +#define dStrncasecmp strncasecmp +#define dStrerror strerror + +/* + *-- dStr --------------------------------------------------------------------- + */ +#define Dstr_char_t char + +typedef struct _dstr { + int sz; /* allocated size (private) */ + int len; + Dstr_char_t *str; +} Dstr; + +Dstr *dStr_new (const char *s); +Dstr *dStr_sized_new (int sz); +void dStr_fit (Dstr *ds); +void dStr_free (Dstr *ds, int all); +void dStr_append_c (Dstr *ds, int c); +void dStr_append (Dstr *ds, const char *s); +void dStr_append_l (Dstr *ds, const char *s, int l); +void dStr_insert (Dstr *ds, int pos_0, const char *s); +void dStr_insert_l (Dstr *ds, int pos_0, const char *s, int l); +void dStr_truncate (Dstr *ds, int len); +void dStr_erase (Dstr *ds, int pos_0, int len); +void dStr_vsprintfa (Dstr *ds, const char *format, va_list argp); +void dStr_vsprintf (Dstr *ds, const char *format, va_list argp); +void dStr_sprintf (Dstr *ds, const char *format, ...); +void dStr_sprintfa (Dstr *ds, const char *format, ...); + +/* + *-- dList -------------------------------------------------------------------- + */ +struct Dlist_ { + int sz; /* allocated size (private) */ + int len; + void **list; +}; + +typedef struct Dlist_ Dlist; + +/* dCompareFunc: + * Return: 0 if parameters are equal (for dList_find_custom). + * Return: 0 if equal, < 0 if (a < b), > 0 if (b < a) --for insert sorted. + * + * For finding a data node with an external key, the comparison function + * parameters are: first the data node, and then the key. + */ +typedef int (*dCompareFunc) (const void *a, const void *b); + + +Dlist *dList_new(int size); +void dList_free (Dlist *lp); +void dList_append (Dlist *lp, void *data); +void dList_prepend (Dlist *lp, void *data); +int dList_length (Dlist *lp); +void dList_remove (Dlist *lp, const void *data); +void dList_remove_fast (Dlist *lp, const void *data); +void *dList_nth_data (Dlist *lp, int n0); +void *dList_find (Dlist *lp, const void *data); +int dList_find_idx (Dlist *lp, const void *data); +void *dList_find_custom (Dlist *lp, const void *data, dCompareFunc func); +void dList_sort (Dlist *lp, dCompareFunc func); +void dList_insert_sorted (Dlist *lp, void *data, dCompareFunc func); +void *dList_find_sorted (Dlist *lp, const void *data, dCompareFunc func); + +/* + *- Misc utility functions ---------------------------------------------------- + */ +char *dGetcwd (); +char *dGethomedir (); +char *dGetline (FILE *stream); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __DLIB_H__ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/Cache.txt Sun Oct 07 00:36:34 2007 +0200 @@ -0,0 +1,185 @@ + June 2000, --Jcid + Last update: Oct 2004 + + ------- + CACHE + ------- + + The cache module is the main abstraction layer between +rendering and networking. + + The capi module acts as a discriminating wrapper which either +calls the cache or the dpi routines depending on the type of +request. + + Every URL must be requested using a_Capi_open_url, no matter +if it is a http, file, dpi or whatever type of request. The capi +asks the dpi module for dpi URLs and the Cache for everything +else. + + Here we'll document non dpi requests. + + The cache, at its turn, sends the requested-data from memory +(if cached), or opens a new network connection (if not cached). + + This means that no mattering whether the answer comes from +memory or the net, the client requests it through the capi +wrapper, in a single uniform way. + + + ---------------- + CACHE PHILOSOPHY + ---------------- + + Dillo's cache is very simple, every single resource that's +retrieved (URL) is kept in memory. NOTHING is saved. This is +mainly for three reasons: + + - Dillo encourages personal privacy and it assures there'll be +no recorded tracks of the sites you visited. + + - The Network is full of intermediate transparent proxys that +serve as caches. + + - If you still want to have cached stuff, you can install an +external cache server (as WWWOFFLE), and benefit from it. + + + --------------- + CACHE STRUCTURE + --------------- + + Currently, dillo's cache code is spread in different sources: +mainly in cache.[ch], dicache.[ch] and it uses some other +functions from mime.c, Url.c and web.c. + + Cache.c is the principal source, and it also is the main +responsible for processing cache-clients (held in a queue). +Dicache.c is the "decompressed image cache" and it holds the +original data and its corresponding decompressed RGB +representation (more on this subject in Images.txt). + + Url.c, mime.c and web.c are used for secondary tasks; as +assigning the right "viewer" or "decoder" for a given URL. + + +---------------- +A bit of history +---------------- + + Some time ago, the cache functions, URL retrieving and +external protocols were a whole mess of mixed code, and it was +getting REALLY hard to fix, improve or extend the functionality. +The main idea of this "layering" is to make code-portions as +independent as possible so they can be understood, fixed, +improved or replaced without affecting the rest of the browser. + + An interesting part of the process is that, as resources are +retrieved, the client (dillo in this case) doesn't know the +Content-Type of the resource at request-time. It only gets known +when the resource header is retrieved (think of http), and it +happens when the cache has the control so, the cache sets the +proper viewer for it! (unless the Callback function is specified +with the URL request). + + You'll find a good example in http.c. + + Note: Files don't have a header, but the file handler inside +dillo tries to determine the Content-Type and sends it back in +HTTP form! + + +------------- +Cache clients +------------- + + Cache clients MUST use a_Cache_open_url to request an URL. The +client structure and the callback-function prototype are defined, +in cache.h, as follows: + +struct _CacheClient { + gint Key; /* Primary Key for this client */ + const char *Url; /* Pointer to a cache entry Url */ + guchar *Buf; /* Pointer to cache-data */ + guint BufSize; /* Valid size of cache-data */ + CA_Callback_t Callback; /* Client function */ + void *CbData; /* Client function data */ + void *Web; /* Pointer to the Web structure of our client */ +}; + +typedef void (*CA_Callback_t)(int Op, CacheClient_t *Client); + + + Notes: + + * Op is the operation that the callback is asked to perform + by the cache. { CA_Send | CA_Close | CA_Abort }. + + * Client: The Client structure that originated the request. + + + +-------------------------- +Key-functions descriptions +-------------------------- + +································································ +int a_Cache_open_url(const char *Url, CA_Callback_t Call, void *CbData) + + if Url is not cached + Create a cache-entry for that URL + Send client to cache queue + Initiate a new connection + else + Feed our client with cached data + +································································ +ChainFunction_t a_Url_get_ccc_funct(const char *Url) + + Scan the Url handlers for a handler that matches + If found + Return the CCC function for it + else + Return NULL + + * Ex: If Url is an http request, a_Http_ccc is the matching +handler. + +································································ + +---------------------- +Redirections mechanism + (HTTP 30x answers) +---------------------- + + This is by no means complete. It's a work in progress. + + Whenever an URL is served under an HTTP 30x header, its cache +entry is flagged with 'CA_Redirect'. If it's a 301 answer, the +additional 'CA_ForceRedirect' flag is also set, if it's a 302 +answer, 'CA_TempRedirect' is also set (this happens inside the +Cache_parse_header() function). + + Later on, in Cache_process_queue(), when the entry is flagged +with 'CA_Redirect' Cache_redirect() is called. + + + + + + + +----------- +Notes +----------- + + The whole process is asynchronous and very complex. I'll try +to document it in more detail later (source is commented). + Currently I have a drawing to understand it; hope the ASCII +translation serves the same as the original. + If you're planning to understand the cache process troughly, +write me a note, just to assign a higher priority on further +improving of this doc. + Hope this helps! + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/Cookies.txt Sun Oct 07 00:36:34 2007 +0200 @@ -0,0 +1,85 @@ +Jan 2002, Jörgen Viksell - jorgen.viksell@telia.com, + Jorge Arellano Cid -- +Last update: Dec 2004 + + +================== + Cookies in Dillo +================== + + The cookie support in Dillo aims to support cookies of the old +original Netscape style, as well as the kind specified in RFC 2109. + Between sessions, the cookies get saved to ~/.dillo/cookies. +At the moment the only enforcements on the amount of cookies to +save to disk is max 20 per domain. + There's also a file for controlling cookies: ~/.dillo/cookiesrc. Dillo +initially sets it to ignore (reject) all cookies, so if you want to use +cookies, change it to meet your needs. + + If you don't want cookies at all, you have two options: + +1.- Delete ~/.dillo/cookiesrc (or leave it just as dillo creates it). +2. Configure Dillo with ./configure --disable-cookies. Then all the + cookie stuff will be skipped at compilation. + + +===================== + Controlling cookies +===================== + + There is a small and simple way to restrict urls from setting cookies +in Dillo. In the file ~/.dillo/cookiesrc You may specify rules +for different domains. The syntax looks something like this: + +DEFAULT DENY +slashdot.org ACCEPT +.host.com ACCEPT_SESSION + + The first line says that we should deny all cookies from all domains +by default. + The second one tells Dillo to save all cookies from slashdot.org +across sessions, until it expires. + And finally, the third says that all subdomains of host.com should be +allowed to set cookies. But these cookies will only be saved in +memory until you exit. + + +=================== + Cookies & Privacy +=================== + + Cookies can be a severe threat to personal privacy. The pages you +visit can be tracked, logged, and associated to a peronal data-record, +allowing the possibility of building a detailed profile of your +browsing habits. + + This data is sold to companies that profit from direct use of such +information (SPAM, Spying, etc). + + If this data is cross-referenced with other databases, they can end up +with more information than you have about yourself. + + Some people may tell you this is "paranoid". But please, take my words +as those of someone that has written a web browser, a cookies implementation, +and that has deep understanding of HTTP (RFC-2068) and cookies (RFC-2965). + + Non technical persons may like to read: + http://www.junkbusters.com/cookies.html + http://www.newsfactor.com/perl/story/16455.html (about user-spying) + + The dillo project is especially concerned about privacy and security +issues. Our advice is to avoid cookies whenever possible and at most set +ACCEPT_SESSION to specific, trusted sites. -- You have been warned. + + +============== + Restrictions +============== + + If you use a single dillo with multiple windows, then there's no +problem, but if you launch different dillos the latter ones will +have cookies disabled. + + + +Thats all folks!
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/Dillo.txt Sun Oct 07 00:36:34 2007 +0200 @@ -0,0 +1,103 @@ +"Eliminate the guesswork and quality goes up." + + + ------- + DILLO + ------- + + These notes are written with a view to make it less hard, not +easier yet ;), to get into Dillo development. + When I first got into it, I was totally unaware of the browser +internals. Now that I've made my way deep into the core of it, +(we rewrote it 90% and modified the rest), is time to write some +documentation, just to make a less steep learning curve for new +developers. + + --Jcid + + + + -------- + OVERVIEW + -------- + + Dillo can be viewed as the sum of five main parts: + + 1.- Dillo Widget: A custom widget, FLTK2 based, that holds the +neccesary data structures and mechanisms for graphical rendering. +(Described in Dw*.txt, dw*.c files among the sources.) + + 2.- Dillo Cache: Integrated with a signal driven Input/Output +engine that handles file descriptor activity, the cache acts as +the main abstraction layer between rendering and networking. + Every URL, whether cached or not, must be retrieved using +a_Cache_open_url (Described briefly in Cache.txt, source +contained in cache.c). + IO is described in IO.txt (recommended), source in IO/. + + 3.- The HTML parser: A streamed parser that joins the Dillo +Widget and the Cache functionality to make browsing possible +(Described in HtmlParser.txt, source mainly inside html.c). + + 4.- Image processing code: The part that handles image +retrieving, decoding, caching and displaying. (Described in +Images.txt. Sources: image.c, dw_image.c, dicache.c, gif.c, +jpeg.c and png.c) + + 5.- The dpi framework: a gateway to interface the browser with +external programs (Example: the bookmarks server plugin). +Dpi spec: http://www.dillo.org/dpi1.html + + + ------------------------- + HOW IS THE PAGE RENDERED? + ------------------------- + +(A short description of the internal function calling process) + + When the user requests a new URL, a_Interface_entry_open_url +is queried to do the job; it calls a_Nav_push (The highest level +URL dispatcher); a_Nav_push updates current browsing history and +calls Nav_open_url. Nav_open_url closes all open connections by +calling a_Interface_stop and a_Interface_stop, and then calls +a_Capi_open_url wich calls a_Cache_open_url (or the dpi module if +this gateway is used). + + If Cache_search hits (due to a cached url :), the client is +fed with cached data, but if the URL isn't cached yet, a new CCC +(Concomitant Control Chain) is created and commited to fetch the +URL. Note that a_Cache_open_url will return the requested URL, +whether cached or not. + + The next CCC link is dynamically assigned by examining the +URL's protocol. It can be: + + a_Http_ccc + a_File_ccc + a_About_ccc + a_Plugin_ccc (not implemented yet) + + + If we have a HTTP URL, a_Http_ccc will succeed, and the http +module will be linked; it will create the proper HTTP query and +link the IO module to submit and deliver the answer. + + Note that as the Content-type of the URL is not always known +in advance, the answering branch decides where to dispatch it to +upon HTTP header arrival. + + + What happens then? + + Well, the html parser gets fed, and proper functions are +called for each tag (to parse and call the appropriate methods) +and the whole page is contructed in a streamed way. + Somewhere in the middle of it, resize and repaint functions +are activated and idle functions draw to screen what has been +processed. + + (The process for images is described in Images.txt) + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/Dpid.txt Sun Oct 07 00:36:34 2007 +0200 @@ -0,0 +1,454 @@ +Aug 2003, Jorge Arellano Cid, + Ferdi Franceschini -- +Last update: Dec 2004 + + + ------ + dpid + ------ + +------------- +Nomenclature: +------------- + + dpi: + generic term referring to dillo's plugin system (version1). + + dpi1: + specific term for dillo's plugin spec version 1. + at: http://www.dillo.org/dpi1.html + + dpi program: + any plugin program itself. + + dpi framework: + the code base inside and outside dillo that makes dpi1 + working possible (it doesn't include dpi programs). + + dpip: + dillo plugin protocol. The HTML/XML like set of command tags + and information that goes inside the communication sockets. + Note: not yet fully defined, but functional. + Note2: it was designed to be extensible. + + dpid: + dillo plugin daemon. + + server plugin: + A plugin that is capable of accepting connections on a socket. Dpid will + never run more than one instance of a server plugin at a time. + + filter plugin: + Any program/script that can read or write to stdio. If you can write a + shell script you can write one of these (see examples at the end). + Warning, dpid will run multiple instances of filter plugins if requested. + This is safe if the plugin only writes to stdout which is what the filter + type dpis do at the moment. + +----------- +About dpid: +----------- + + * dpid is a program which manages dpi connections. + * dpid is a daemon that serves dillo using unix domain + sockets (UDS). + * dpid launches dpi programs and arranges socket communication + between the dpi program and dillo. + + The concept and motivation is similar to that of inetd. The +plugin manager (dpid) listens for a service request on a Unix +domain socket and returns the socket name of a plugin that +handles the service. It also watches sockets of inactive plugins +and starts them when a connection is requested. + + +----------------------------------------------------------- +What's the problem with managing dpi programs inside dillo? +----------------------------------------------------------- + + That's the other way to handle it, but it started to show some +problems (briefly outlined here): + + * When having two or more running instances of Dillo, one + should prevail, and take control of dpi managing (but all + dillos carry the managing code). + * If the managing dillo exits, it must pass control to another + instance, or leave it void if there's no other dillo running! + * The need to synchronise all the running instances of + dillo arises. + * If the controlling instance finishes and quits, all the + dpi-program PIDs are lost. + * Terminating hanged dpis is hard if it's not done with signals + (PIDs) + * Forks can be expensive (Dillo had to fork its dpis). + * When a managing dillo exits, the new one is no longer the + parent of the forked dpis. + * If the Unix domain sockets for the dpis were to be named + randomly, it gets very hard to recover their names if the + controlling instance of dillo exits and another must "take + over" the managing. + * It increments dillo's core size. + * ... + + That's why the managing daemon scheme was chosen. + + +---------------------- +What does dpid handle? +---------------------- + + It solves all the above mentioned shortcomings and also can do: + + * Multiple dillos: + dpid can communicate and serve more than one instance + of dillo. + + * Multiple dillo windows: + two or more windows of the same dillo instance accessing dpis + at the same time. + + * Different implementations of the same service + dpi programs ("dpis") are just an implementation of a + service. There's no problem in having more than one for the + same service. + + * Upgrading a service: + to a new version or implementation without requiring + bringing down the dpid or patching dillo's core. + + + And finally, being aware that this design can support the +following functions is very helpful: + + SCHEME Example + ------------------------------------------------------------ + * "one demand/one response" man, preferences, ... + * "resident while working" downloads, mp3, ... + * "resident until TERM signal" bookmarks, ... + + * "one client only" cd burner, ... + * "one client per instance" man, ... + * "multiple clients/one instance" downloads, cookies ... + + +-------- +Features +-------- + * Dpi programs go in: "EPREFIX/dillo/dpi" or "~/.dillo/dpi". The binaries + are named <name>.dpi as "bookmarks.dpi" and <name>.filter.dpi as in + "hello.filter.dpi". The ".filter" plugins simply read and write to stdio + and can be implemented with a shell script easily. + * Register/update/remove dpis from list of available dpis when a + <dpi cmd='register_all'> is received. + * dpid terminates when it receives a <dpi cmd='DpiBye'> command. + * dpis can be terminated with a <dpi cmd='DpiBye'> command. + * dpidc control program for dpid, currently allows register and stop. + + +----- +todo: +----- + + These features are already designed, waiting for implementation: + + * How to register/update/remove/ individual dpis? + * How to kill dpis? (signals) + + How: + + A useful and flexible way is to have a "control program" for +dpid (it avoids having to find its PID among others). + + Let's say: + + dpidc [register | upgrade | stop | ...] + + It can talk to a dpid UDS that serves for that (the same that +dillo would use). That way we may also have a dpidc dpi! :-) + + Seriously, what I like from this approach is that it is very +flexible and can be implemented incrementally ("dpidc register" +is enough to start). + + It also avoids the burden of having to periodically check the +dpis directory structure for changes). + + It also lets shell scripts an easy way to do the "dirty" work +of installing dpis; as is required with distros' package +systems. + +<note> + How do we tell a crashed dpi? That's the question. + We're thinking about using the "lease" concept (as in JINI). +</note> + + +----------------- +How does it work? +----------------- + +o on startup dpid reads dpidrc for the path to the dpi directory + (usually EPREFIX/lib/dillo/dpi). ~/.dillo/dpi is scanned first. + +o both directories are scanned for the list of available plugins. + ~/.dillo/dpi overrides system-wide dpis. + +o ~/.dillo/dpi_socket_dir is then checked for the name of the dpi socket + directory, if dpi_socket_dir does not exist it will be created. + +o next it creates Unix domain sockets for the available plugins and + then listens for service requests on its own socket (dpid.srs) + and for connections to the sockets of inactive plugins. + +o dpid returns the name of a plugin's socket when a client (dillo) + requests a service. + +o if the requested plugin is a 'server' then + 1) dpid stops watching the socket for activity + 2) forks and starts the plugin + 3) resumes watching the socket when the plugin exits + +o if the requested plugin is a 'filter' then + 1) dpid accepts the connection + 2) duplicates the connection on stdio + 3) forks and starts the plugin + 4) continues to watch the socket for new connections + + + + +--------------------------- +dpi service process diagram +--------------------------- + + These drawings should be worth a thousand words! :) + + +(I) + .--- s1 s2 s3 ... sn + | + [dpid] [dillo] + | + '--- srs + + The dpid is running listening on several sockets. + + +(II) + .--- s1 s2 s3 ... sn + | + [dpid] [dillo] + | | + '--- srs ------------------' + + dillo needs a service so it connects to the service request + socket of the dpid (srs) and asks for the socket name of the + required plugin (using dpip). + + +(III) + .--- s1 s2 s3 ... sn + | | + [dpid] | [dillo] + | | | + '--- srs '---------------' + + then it connects to that socket (s3, still serviced by dpid!) + + +(IV) + .--- s1 s2 s3 ... sn + | | + .[dpid] | [dillo] + . | | | + . '--- srs '---------------' + . + .............[dpi program] + + when s3 has activity (incoming data), dpid forks the dpi + program for it... + + +(V) + .--- s1 s2 (s3) ... sn + | + [dpid] [dillo] + | | + '--- srs .---------------' + | + [dpi program] + + ... and lets it "to take over" the socket. + + Once there's a socket channel for dpi and dillo, the whole +communication process takes place until the task is done. When +the dpi program exits, dpid resumes listening on the socket (s3). + + +----------------------------------------------- +How are the unix-domain-sockets for dpis named? +----------------------------------------------- + + Let's say we have two users, "fred" and "joe". + + When Fred's dillo starts its dpid, the dpid creates the +following directory (rwx------): + + /tmp/fred-XXXXXX + + using mkdtemp(). + + and saves that filename within "~/.dillo/dpi_socket_dir". + + That way, another dillo instance of user Fred can easily find +the running dpid's service request socket at: + + /tmp/fred-XXXXXX/dpid.srs + + (because it is saved in "~/.dillo/dpi_socket_dir"). + + Now, we have a dpi directory per user, and its permissions are +locked so only the user has access, thus the following directory +tree structure should pose no problems: + + /tmp/fred-XXXXXX/bookmarks + /downloads + /cookies + /ftp + ... + dpid.srs + + If user Joe starts his dillo, the same happens for him: + + /tmp/joe-XXXXXX/bookmarks + /downloads + /cookies + /ftp + ... + dpid.srs + + + What should dpid do at start time: + + Check if both, ~/.dillo/dpi_socket_dir and its directory, exist + (it can also check the ownership and permissions). + + If (both exist) + use them! + else + delete ~/.dillo/dpi_socket_dir + create another /tmp/<user>-XXXXXX directory + save the new directory name into ~/.dillo/dpi_socket_dir + (we could also add some paranoid level checks) + + To some degree, this scheme solves the tmpnam issue, different +users of dillo at the same time, multiple dillo instances, +polluting /tmp (cosmetic), and reasonably accounts for an +eventual dillo or dpid crash. + + It has worked very well so far! + + +-------------------------------- +So, how do I make my own plugin? +-------------------------------- + + First, at least, read the "Developing a dillo plugin" section +of dpi1 spec! :-) + + Note that the dpi1 spec may not be absolutely accurate, but the +main ideas remain. + + Once you've got the concepts, contrast them with the drawings +in this document. Once it all makes sense, start playing with +hello.dpi, you can run it by starting dillo with + dillo dpi:/hello/ +or entering + dpi:/hello/ +as the url. Then try to understand how it works (use the drawings) +and finally look at its code. + + Really, the order is not that important, what really matters is +to do it all. + + Start modifying hello.dpi, and then some more. When you feel +like trying new things, review the code of the other plugins for +ideas. + + The hardest part is to try to modify the dpi framework code +inside dillo; you have been warned! It already supports a lot of +functionality, but if you need to do some very custom stuff, try +extending the "chat" command. + + +--------------------------------- +Examples: Simple 'filter' plugins +--------------------------------- + + For a quick and dirty introduction to dpis try the following shell scripts. + + #!/bin/sh + + read -d'>' dpip_tag # Read dillo's request + + # Don't forget the empty line after the Content-type + cat <<EOF + <dpi cmd='start_send_page' url='dpi:/hi/hi.filter.dpi'> + Content-type: text + + EOF + + echo Hi + + Of course you should use html in a real application (perl makes this easy). + + A more useful example uses the "si" system info viewer: + + #!/bin/sh + # si - System Information Viewer + + read -d'>' dpip_tag + + # We don't need to send the Content-type because "si --html" does this + # for us. + cat <<EOF + <dpi cmd='start_send_page' url='dpi:/si/si.dpi.filter'> + EOF + + si --html + + just make sure that you have si installed or you wont get far. + +To try out the examples create two directories for the scripts under your home directory as follows: + mkdir -p ~/.dillo/dpi/hi + mkdir -p ~/.dillo/dpi/si + +then create the scripts and put them in the dpi service directories so that you end up with + ~/.dillo/dpi/hi/hi.filter.dpi + ~/.dillo/dpi/si/si.filter.dpi + +Don't forget to make them executable. + +If dpid is already running register the new plugins with + dpidc register + +You can now test them by entering + dpi:/hi/ +or + dpi:/si/ +as the url. Or simply passing the url to dillo on startup + + dillo dpi:/si/ + + + You can edit the files in place while dpid is running and reload them in +dillo to see the result, however if you change the file name or add a new +script you must run 'dpidc register'. + +WARNING +Multiple instances of a filter plugin may be run concurrently, this could be a +problem if your plugin records data in a file, however it is safe if you simply +write to stdout. Alternatively you could write a 'server' plugin instead as +they are guaranteed not to run concurrently. + >>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<< +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/Dw.txt Sun Oct 07 00:36:34 2007 +0200 @@ -0,0 +1,383 @@ +Jan 2001, S.Geerken@ping.de +Last update: Dec 2004 + +================ +Dw: Dillo Widget +================ + +NOTE (Aug 2004): The rendering has changed quite much, and many other +documents are out of date, in ways described in DwRendering.txt. They +will be updated some day. + +Dw is mainly the module for rendering HTML. It provides a framework +for widgets, based on the Gtk+ object framework, and is very similar +to Gtk+, so that experiences in using and extending Gtk+ help very +much in understanding Dw. There is some documentation at www.gtk.org +(and probably on your local harddisk, somewhere in /usr/doc/*gtk*), +you should especially have read the chapter "Writing Your Own +Widgets" in the tutorial. + + +Why Not Gtk+? +============= + +There are two reasons for designing a new model instead of simply +using Gtk+ objects: + + 1. Most important, Gtk+ widgets are limited in size, because X + windows are so. + 2. There are a few extensions which are due to the different needs + for HTML rendering compared to GUI's. (Of course, this could + have been solved by defining a new object derived from + GtkWidget.) + + +Notes On Naming +=============== + +According to the naming standards, functions beginning with "a_Dw_" +may be used outside of Dw, while, as an extention, functions used +within Dw (e.g. p_Dw_widget_queue_resize) are prefixed with "p_Dw_". +[todo: This could be included in NC_design.txt.] + +Non-static functions beginning with "Dw_" are only used between +GtkDwViewport and DwWidget (e.g. Dw_gtk_viewport_remove_dw), they +belong to the core of Dw. And, of course, functions only used within a +sub-module (e.g. a specific widget) start with "Dw_" and are static +(e.g. Dw_page_find_line_index). + +Dw widgets and some other structures have the prefix "Dw", while Gtk+ +widgets in Dw have the prefix "GtkDw", but functions of them begin +with "Dw_gtk_" or "a_Dw_gtk", respectively. + + +Basic Overview +============== + +Dw widgets are objects derived from DwWidget, which itself derives +from GtkObject. DwWidget is quite similar to GtkWidget, the main +difference is that Dw widgets are always windowless and that they are +presented in a viewport, so there is no need to limit the size. Much +of the functionality normally provided by the X server is simulated +by Dw. + +The interface between Gtk+ and Dw is the Gtk+ widget GtkDwViewport, +which contains (at most) one top-level Dw widget. + +A Few Definitions: + + - world coordinates: coordinates relative to the upper left corner + of the whole scrolled area ("the world") + - viewport coordinates: coordinates relative to the upper left + corner of the visible area + - widget coordinates: coordinates relative to the upper left corner + of the widget + +Dw widgets draw into the viewport window, and must adhere to +*viewport coordinates*: the "world" is only an abstract term, there +is no window for it. When GtkDwViewport processes expose events, they +are automatically delivered to the Dw widgets. Redrawing requests due +to scrolling of the viewport is done by the base object GtkLayout, +you will not find any code for this in Dw. + +Mouse events also contain viewport coordinates. Dw will try to find +the right Dw widget to deliver the event to. + +Resizing the GtkDwViewport will not resize the top-level Dw widget, +but the latter will get some hints, so that, e.g., the page widget +rewraps the lines at the appropriate width. + +See DwWidget.txt for more details. + + +Embedding Gtk+ Widgets In Dw +---------------------------- +Dw Widgets may embed Gtk+ widgets, this is done by the Dw widget +DwEmbedGtk. For Gtk+, these embedded Gtk+ widgets are themselves +children of the GtkDwViewport, since Gtk+ does not care about Dw. + +Of course, embedded Gtk+ widgets are again limited in size, but but +in position: GtkDwViewport is derived from GtkLayout which is exactly +designed for positioning widgets in an infinite scrolled area. + + +How To Get The Top-Level Dw Widget From A BrowserWindow +------------------------------------------------------- +The member "docwin" of BrowserWindow points on a GtkDwScrolledWindow, +which contains a GtkDwScrolledFrame, which contains a GtkDwViewport. +The member "child" of the latter points on the top-level Dw widget, +or may be NULL. The top-level Dw is (currently) a DwPage (HTML and +plain text documents) or a DwImage (images). + +There is a function a_Dw_gtk_scrolled_window_get_dw for this. + + +Sizes +----- +A feature adapted from the old Dw are baselines. As well DwAllocation +as DwRequisition do not have a height member, but instead ascent and +descent, both positive or zero. (Originally I removed this, but there +will be a few widgets in future depending on this, e.g., math +formulas.) + +Unlike in Gtk, sizes of zero are allowed. The upper limit for the +size of a widget is 2^31 (this will be enough to show the contents of +a small library in a web page). + + +Resizing +======== + +From outside: When writing a new widget, you should implement the +signal "size_request". When the widget changes its size, it should +call p_Dw_widget_queue_resize, as in a_Dw_image_size. See "Incremental +Resizing" below for a way to increase the speed. + +Even if the implementation of "size_request" gets quite expensive, +you do not have to check whether the size has changed, this is done +by a_Dw_widget_size_request. + +Inside: q_Dw_widget_queue_resize will set the DW_NEEDS_RESIZE flag, a +further call of a_Dw_widget_size_request will only then emit the +"size_request" signal. Furthermore, mark_size_change and +mark_extremes_change are called (see below). After that, the resizing +is done in an idle loop, this prevents too many size requests. The +algorithm is quite simple: any widget with a child which needs +resizing, needs resizing, thus all parents up to top-level widget are +marked. + +Incremental Resizing +--------------------- +A widget may calculate its size based on size calculations already +done before. In this case, a widget must exactly know the reasons, why +a call of size_request is necessary. To make use of this, a widget +must implement the following: + + 1. There is a member in DwWidget, called parent_ref, which is + totally under control of the parent widget (and so sometimes not + used at all). It is necessary to define how parent_ref is used + by a specific parent widget, and it has to be set to the correct + value whenever necessary. + + 2. The widget must implement mark_size_change and + mark_extremes_change, these methods are called in two cases: + + a) directly after q_Dw_widget_queue_resize, with the argument + ref was passed to q_Dw_widget_queue_resize, and + b) if a child widget has called q_Dw_widget_queue_resize, + with the value of the parent_ref member of this child. + +This way, a widget can exactly keep track on size changes, and so +implement resizing in a faster way. A good example on how to use this +is the DwPage widget, see DwPage.txt for details. + + +Anchors and Scrolling +===================== + +Anchors +------- +todo: This section is out of sync with the actual code. + +To set the anchor a page is viewed at, you can use one of the +following functions: + + - void a_Dw_gtk_viewport_set_anchor (GtkDwViewport *viewport, + gchar *anchor) + + Scroll directly to an anchor. The anchor does not need to exist + already, see below. + + - void a_Dw_gtk_viewport_queue_anchor (GtkDwViewport *viewport, + gchar *anchor) + + Set the anchor for the next top-level DwWidget (the next call + of a_Dw_gtk_viewport_add_dw). + +There are wrappers, a_Dw_gtk_scrolled_window_queue_anchor and +a_Dw_gtk_scrolled_window_set_anchor. + +After a_Dw_gtk_viewport_set_anchor has been called (indirectly by +Nav_open_url, or by a_Dw_gtk_viewport_add_dw), changes of anchor +positions (e.g., if widgets change there size or the anchor was not +known before) will correct the viewport adjustment (in function +p_Dw_gtk_viewport_update_anchor), but only as long as the user did not +change it directly. Look at Dw_gtk_scrolled_window_init for details +about the latter. + +Use p_Dw_widget_set_anchor to add anchors to a widget, see +DwWidget.txt. + +Scrolling +--------- +Here is an overview on more functions for scrolling: + + - To scroll to a given position, there are two possibilities: + a_Dw_gtk_viewport_set_scrolling_position simply scrolls to this + position, while Dw_gtk_viewport_scroll_to has more facilities: + you specify a rectangle you want to see, and the way how it is + seen (at the border, centered, or just scroll as much as + necessary, that it is seen). If you have a widget, you can also + use Dw_widget_scroll_to. There is also a wrapper for + GtkDwScrolledWindow, + a_Dw_gtk_scrolled_window_set_scrolling_position, and two + functions for getting the position, + a_Dw_gtk_scrolled_window_get_scrolling_position_x, and + a_Dw_gtk_scrolled_window_get_scrolling_position_y. + + - If you have a region, and want to display it, use + a_Dw_iterator_scroll_to. For example, the findtext module makes + use of it. There are equivalents for DwExtIterator and + DwWordIterator. See comments on and in the function for more + informations. + + - If you just want to determine where some content is allocated, + represented by an iterator, you can use + a_Dw_iterator_get_allocation. There are equivalents for + DwExtIterator and DwWordIterator. + + +The Objects +=========== + +This is the hierarchy of all objects of Dw: + + (GtkObject) + +-DwWidget + | +----DwBullet + | +----DwContainer + | | `----DwPage + | +----DwEmbedGtk + | +----DwHruler + | `----DwImage + `----(GtkWidget) + `----(GtkContainer) + +----(GtkBin) + | +----(GtkScrolledWindow) + | | `----GtkDwScrolledWindow + | `----GtkDwScrolledFrame + `----(GtkLayout) + `----GtkDwViewport + +Objects in parentheses are part of Gtk+, not of Dw. + + +DwBullet +-------- +Simple widget used for unnumbered list (<ul>). + + +DwContainer +----------- +The base object for Dw widgets which contain other Dw widgets. As in +Gtk+, containers are responsible for storing the children, there is +no common data structure. There are a few signals: + + - void add (DwContainer *container, + DwWidget *child); + + Currently not used, but may be in future. + + - void remove (DwContainer *container, + DwWidget *widget); + + *Recognize* that a widget is destroyed, i.e., an implementation + should remove *the pointer* from the list or so, but not + destroy the child widget. It is called by Dw_widget_shutdown. + + - void forall (DwContainer *container, + DwCallback callback, + gpointer callback_data); + + Process callback for all children, in the form + (*callback)(child, callback_data). + + The include_internals of the Gtk+ equivalent was not adapted, + since it is used for more sophisticated purposes not needed in + Dw. + + +DwEmbedGtk +---------- +This Dw widget is used to embed Gtk+ widgets into Dw container +widgets. The Gtk+ widget is set by a_Dw_embed_gtk_add_gtk, and can +simply be removed by destroying it. + +If the DwEmbedGtk contains no Gtk+ widget, it always returns 0x0x0 as +size, so, for speed reasons, first add the Gtk+ widget into the +DwEmbedGtk, and then the DwEmbedGtk into the other Dw widget, as at +the end of Html_tag_open_input. + + +DwHruler +-------- +Simple widget used for the <hr> tag. + + +DwImage +------- +Widget for displaying image. See DwImage.txt for details. + + +DwPage +------ +A widget for displaying texts. See DwPage.txt for details. + + +DwTable +------- +A container widget for rendering tables. See DwTable.txt for details. + + +DwWidget +-------- +The base object for all Dw widgets. See DwWidget.txt for details. + + +GtkDwScrolledWindow +------------------- +Adds a few functionalities to GtkScrolledWindow: it creates the +GtkDwScrolledFrame and the GtkDwViewport, connects some signals, and +provides some wrappers for using the GtkDwViewport. + + +GtkDwScrolledFrame +------------------ +General purpose scrolled widget containing another scrolled widget, +adding a border and a focus frame. Furthermore, it processes key +presses and mouse drags (button 2, as in Gimp) to move the viewport. + +There are two signals (except "set_scroll_adjustments"), +"user_hchanged" and "user_vchanged", which are emitted when the user +changed the viewport adjustments horizontally/vertically by using the +keys or button 2 dragging. + + +GtkDwViewport +------------- +The interface between Gtk+ and Dw. It is responsible for displaying +Dw Widgets and processing their events. It is derived from GtkLayout, +to make embedding Gtk+ widgets into Dw widgets simpler, see the +documentation of GtkLayout in the Gtk+ tutorial for details. + +GtkDwViewport contains at most one top-level Dw Widget, if it exists. +The Gtk+ methods of GtkDwViewport are more or less mapped on the +methods of the DwWidget. In detail: + + - Dw_gtk_viewport_size_allocate will call a_Dw_widget_set_width, + a_Dw_widget_set_ascent (with allocation->height) and + a_Dw_widget_set_descent (with zero as argument), and then allocate + the Dw widget at the size returned by a_Dw_widget_size_request. + + - Dw_gtk_viewport_draw and Dw_gtk_viewport_expose will call + a_Dw_widget_draw, which will emit the "draw" signal. + + - Handling of mouse events is mostly done in Dw_widget_mouse_event, + see DwWidget.txt for details. Note that the functions return + FALSE, if the event was not processed, so that they are delivered + to the parent widget(s) of the GtkDwViewport, this scheme e.g. + prevents dragging of the viewport (done by GtkScrolledFrame) when + pressing mouse button 2 on a link. + +You may call gtk_container_set_border_width for a border around the +scrolled area.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/DwImage.txt Sun Oct 07 00:36:34 2007 +0200 @@ -0,0 +1,201 @@ +Jan 2001, S.Geerken@ping.de +Last update: Dec 2004 + +======= +DwImage +======= + +A widget for displaying images and handling image maps. + + +Image Maps +========== + +Client Side Image Maps +---------------------- +You must first create a list of image maps: Allocate a DwImageMapList, +and initialize it by calling a_Dw_image_map_list_init. Adding a map is +done by a_Dw_image_map_list_add_map. a_Dw_image_map_list_add_shape +adds a shape to the last map. For the meaning of the link argument, +see Section "Signals". + +Image maps are referred by a URL (not only by a name). But currently, +the image map list is stored in DilloHtmlLB and there is no +possibility to parse documents without rendering, so images can only +use maps defined in the same document. + +To use a map in an image, call a_Dw_image_set_usemap with the image, +the map list, and the URL of the map. Passing the whole list makes it +possible to use maps parsed after the image is created. + + +Server Side Image Maps +---------------------- +To use images for server side image maps, you must call +a_Dw_image_set_ismap and the style must contain a valid link +element. See section "Signals" for more details. + + +Signals +======= + +There are five signals, which can be connected to process actions with +links. All have at least three arguments: + + - link is the link element of the DwStyle (server side image maps) + or DwImageMapShape (client side image maps). The value is an + integer, which is currently only used for hypertext links. But + generally, it depends on the signal callback how this value is + used. + + - x and y are, when server side image maps are used, the relative + coordinates of the mouse pointer, otherwise always -1. + +Note that, unlike by DwPage before, no cursors are set. Instead, the +signal callback function has to do this. + +The signals: + + - void link_entered (DwImage *image, + gint link, gint x, gint y) + + Emitted when the link the mouse pointer is over has + changed. "Changed" includes link, x and y, so this signal is also + emitted each time the pointer is moved within a server side image + map. If the pointer is outside of a link, all arguments have the + value -1. + + + - void link_pressed (DwImage *image, + gint link, gint x, gint y, + GdkEventButton *event) + + Emitted when the user presses a mouse button _inside_ a link, + this signal is never emitted with link = -1. You can use the + event to get information about the button, shift keys, etc. + + + - void link_released (DwImage *image, + gint link, gint x, gint y, + GdkEventButton *event) + + - void link_clicked (DwImage *image, + gint link, gint x, gint y, + GdkEventButton *event) + + Analogue to link_pressed. + + - void void (*image_pressed) (DwImage *page, + GdkEventButton *event) + + Emitted when the user presses the mouse button on an image which + has no related map. In some cases, it may be neccessary to + suppress event processing by a_Dw_widget_set_button_sensitive(). + + +Future Extentions +================= + +(See also Imgbuf.txt, what is named DilloImageBuffer here, has been +implemented under the name Imgbuf.) + +These are some ideas for a different design, which will solve several +problems (image transparency, memory usage when implementing a global +size factor): + +1. Instead of a guchar array, a new data type, DilloImageBuffer, + should be used (DICacheEntry::ImageBuffer and DwImage::buffer). Any + access is done by function calls. Copying the lines (in + a_Image_write) is done by a_Image_buffer_copy_line, etc. The call to + Image_line becomes obsolete, since DilloImageBuffer will deal with + different types: indexed, RGB, gray, RGBA, gray-alpha(?). This may + be useful for a more efficient implementation of DilloImageBuffer. + +2. The modules Png, Jpeg, Gif, Image and DICache deal with the + original image size (read by the decoders), while DwImage gets the + "viewed" size (original size, multiplied by the global image + scaling factor) from DilloImageBuffer. + +3. For DwImage, there are further methods which replace the current + direct access. Note to worth: + + - Scaled buffers are shared, reference counters are used. Copying + rows will automatically also affect the related scaled buffers. + + - There are two methods for drawing, one called after expose events + (Dw_image_draw) and another called by a_Dw_image_draw_row. The + exact rules, how the buffer is scaled (this can, e.g., differ by a + pixel or so), is hidden by DilloImageBuffer. + + - As noted above, all DwImage code is based on the viewed size. + +4. The global image scaling factor is used in two places. The HTML + parser must apply it on the WIDTH and HEIGHT attributes of the + <IMG> tag and DilloImageBuffer must use it to scale the inherent + size of an image. There are two modes, which the user can switch + by a dillorc option: + + (i) The original image data is preserved, and an additional scaled + buffer is created: + + +-------+ +------------------+ additional + | Image | -- copy --> | DilloImageBuffer | --> scaled + +-------+ rows | (original size) | buffers + +------------------+ + | ^ + | | + scale requests + each row for scaled + | buffers + | | + v | + +------------------+ + | DilloImageBuffer | + | (viewed size) | + +------------------+ + ^ + | + +---------+ + | DwImage | + +---------+ + + (ii) The original data gets lost just after scaling: + + +-------+ +------------------+ + | Image | -- copy --> | DilloImageBuffer | --> scaled + +-------+ rows | (viewed size) | buffers + +------------------+ + ^ + | + +---------+ + | DwImage | + +---------+ + + (ii) uses generally less memory, while in some cases leads to a + lower rendering quality, as in this example: + + "foo.png" has a size of 100x100 pixels, the image scaling factor is + 50%, and the following HTML sniplet is rendered: + + <img src="foo.png"> + <img src="foo.png" width=200 height=200> + + The first image is displayed at a size of 50x50, the second at + 100x100. (i) will, for the second, use the original buffer, but + (ii) will enlarge the buffer, which was scaled down before, so + resulting in a "pixelized" image. + +5. Any implementation of DilloImageBuffer will handle transparency + independent of the background, i.e., the background colour will not + be used anymore. The first implementation may be based on GdkRGB + and (when needed) dithered clipping bitmaps. Better implementations + may then be developed in the future. + +6. Background images: The modules Image and DICache do no longer + access the DwImage directly, all calls are replaced by an + Interface, which is then implemented by DwImage and an appropriate + structure for background images (part of DwStyle). The interface is + in C realized by a struct of function pointers, and a generic + pointer on DwImage, etc. + +7. If someone really needs it, animated GIF's may be considered.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/DwPage.txt Sun Oct 07 00:36:34 2007 +0200 @@ -0,0 +1,152 @@ +Nov 2001, S.Geerken@ping.de +Last update: Dec 2004 + +====== +DwPage +====== + +A widget for displaying texts. It is (currently) the main widget for +rendering HTML documents. + + +Signals +======= + +DwPage defines the same signals as DwImage, except "image_pressed", +with the exception that the coordinates are always -1. See +DwImage.txt for more details. + + +Collapsing Spaces +================= + +The idea behind this is that every text box has a specific vertical +space around and that they are combined to one space, according to +rules stated below. A rule is either a paragraph within a DwPage +widget, or a DwPage within a DwPage widget, in a single line; the +latter is used for indented boxes and list items. + +The rules: + + 1. If a box is following another, the space between them is the + maximum of both box spaces: + + +---------+ + |/////////| + |/////////| +---------+ + +---------+ |/////////| + | A | |/////////| + +---------+ +---------+ + |/////////| | A | + |/////////| +---------+ + +---------+ are combined like this: |/////////| + |XXXXXXXXX| + +---------+ +---------+ + |\\\\\\\\\| | B | + +---------+ +---------+ + | B | |\\\\\\\\\| + +---------+ +---------+ + |\\\\\\\\\| + +---------+ + + 2. a) If one box is the first box within another, the upper space + of these boxes collapse. b) The analogue is the case for the + last box: + + +---------+ If B and C are put into A, + |/////////| the result is: + |/////////| + +---------+ +---------+ +---------+ + | A | <--+-- |\\\\\\\\\| |/////////| + +---------+ ¦ +---------+ |XXXXXXXXX| + |/////////| | | B | +---------+ + |/////////| | +---------+ | B | + +---------+ | |\\\\\\\\\| +---------+ + | +---------+ |\\\\\\\\\| + | |\\\\\\\\\| + | +---------+ |\\\\\\\\\| + `-- |\\\\\\\\\| +---------+ + |\\\\\\\\\| | C | + |\\\\\\\\\| +---------+ + +---------+ |\\\\\\\\\| + | C | |XXXXXXXXX| + +---------+ |XXXXXXXXX| + |\\\\\\\\\| +---------+ + |\\\\\\\\\| + |\\\\\\\\\| + +---------+ + +For achieving this, there are some features of DwPage: + + - Consequent breaks are automatically combined, according to + rule 1. See the code of a_Dw_page_add_break for details. + + - If a break is added as the first word of the DwPage within + another DwPage, collapsing according to rule 2a is done + automatically. See the code of a_Dw_page_add_break. + + - To collapse spaces according to rule 2b, + a_Dw_page_hand_over_break must be called for the *inner* + widget. The HTML parser does this in Html_eventually_pop_dw. + + +Collapsing Margins +================== + +Collapsing margins, as defined in the CSS2 specification, are, +supported in addition to collapsing spaces. Also, spaces and margins +collapse themselves. I.e., the space between two paragraphs is the +maximum of the space calculated as described in "Collapsing Spaces" +and the space calculated according to the rules for collapsing margins. + +(This is an intermediate hybrid state, collapsing spaces are used in +the current version of dillo, while I implemented collapsing margins +for CSS and integrated it already into the main trunk. For a pure +CSS-based dillo, collapsing spaces will not be needed anymore, and may +be removed for simplicity.) + + +Some Internals +============== + +There are two lists, words and lines. The word list is quite static; +only new words may be added. A word is either text, a widget, a break +or an anchor. Anchors are stored in the text, because it may be +necessary to correct the scroller positions at rewrapping. + +Lines refer to the word list (first and last), they are completely +redundant, i.e., they can be rebuilt from the words. Lines can be +rewrapped either completely or partially (see "Incremental Resizing" +below). For the latter purpose, several values are accumulated in the +lines. See the file "dw_page.h" for details. + + +Incremental Resizing +-------------------- +DwPage makes use of incremental resizing as described in Dw.txt, +section "Resizing". The parent_ref is, for children of a DwPage, +simply the number of the line. + +Generally, there are three cases which may change the size of the +widget: + + 1. The available size of the widget has changed, e.g., because the + user has changed the size of the browser window. In this case, + it is necessary to rewrap all the lines. + + 2. A child widget has changed its size. In this case, only a rewrap + down from the line where this widget is located is necessary. + + (This case is very important for tables. Tables are quite at the + bottom, so that a partial rewrap is relevant. Otherwise, tables + change their size quite often, so that this is necessary for a + fast, non-blocking rendering) + + 3. A word (or widget, break etc.) is added to the page. This makes + it possible to reuse the old size by simply adjusting the + current width and height, so no rewrapping is necessary. + +The state of the size calculation is stored in wrap_ref within DwPage, +which has the value -1 if no rewrapping of lines necessary, or +otherwise the line from which a rewrap is necessary. +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/DwRender.txt Sun Oct 07 00:36:34 2007 +0200 @@ -0,0 +1,620 @@ +Aug 2004, S.Geerken@ping.de + +=========================== + Dw Render Abstraction +=========================== + +This document describes the rendering abstraction used in Dw. At the +time this document was written, some other documents about Dw were out +of date, and have to be rewritten. + +Sometimes, you will find remarks about the old design (with one +concrete Gtk+ widget instead of the layout/multiple rendering views); +those are useful for those, who are already familiar with the old +design. Furthermore, it makes the explanation often simpler, because +the new design is a bit more complex. + +Naming +------ +As stated in "Dw.txt", the prefix "p_Dw_" is used for functions used +within the whole Dw module, but not outside. Typically, these are +protected functions, which are called by inherited classes. E.g., a +specific widget will have to call p_Dw_widget_queue_resize(), but this +function should not called outside from Dw. + +The "Dw_" prefix is not only used for functions, which use is +restricted to a sub-module, but also for functions used only within +the core of Dw. The distinction between both can simply made, whether +the function is declared as static or not. The core of Dw consists of +the modules Dw_widget and Dw_render, anything else is inherited from +these two modules (widgets, platforms, views). As an example, +Dw_gtk_viewport_queue_resize() is only called in the Dw_widget module, +it should not be called by a widget implementation. + + +Overview +======== + +Rendering of Dw is done in a way resembling the model-view pattern, at +least formally. Actually, the counterpart of the model, the layout +(DwRenderLayout), does a bit more than a typical model, namely +calculating the layout, and the views do a bit less than a typical +view, i.e. only the actual drawing. + +Additionally, there is a structure representing common properties of +the platform, views generally work only together with one specific +platform. A platform is typically related to the underlying UI +toolkit, but other uses may be thought of. + +The general structure looks like this: + + 1 +------------------+ + .---->| DwRenderPlatform | + +----------------+ 1 / +------------------+ + | DwRenderLayout |--< ^ 1 + +----------------+ \ | * + 1 ^ | 1 \ +--------------+ + | | `---->| DwRenderView | + | | * +--------------+ + | | + layout | | toplevel_dw + | | + * | V 0..1 + +----------+ 0..1 + | DwWidget |--. parent + +----------+ | + * | | + `-------' + (children) + +(This is a bit simplified, actually, only DwContainer has child +widgets, and the relation is only defined in an abstract way). + +DwRenderLayout and DwWidget (including sub classes) are platform and +view independant, i.e., it should be possible to adopt them into +another platform, after suitable implementations of DwRenderPlatform +and DwRenderView have been developed. + +(The only exception is DwEmbedGtk, a widget which, in the old design, +embeds Gtk+ widgets into the DwWidget tree. This will still remain a +platform specific widget, see notes in the section "UI Widgets". + +Furthermore, this design does not yet cover DwStyle, which is still +bound to the Gtk+ platform. It may be simply replaced for other +platforms, but this will lose the possibility to have multiple +implementations of DwRenderPlatform running within the same program. +The same aplies to DwTooltip and Imgbuf.) + +This new design helps to archieve two important goals: + + 1. Abstraction of the actual rendering. Currently, we only have the + normal viewport, but a list of planned implementations can be + found below in this text. + + 2. It makes different views of the same document simple, e.g. the + normal viewport and the preview window. + + 3. It makes portability simpler. + +Vieports are handles by this design, but only in a rather abstract +way, and may be removed completely, i.e., they will be only part of +specific view implementations. This also means, that the distinction +between world coordinates and viewport coordinates vanishes from most +parts of Dw. + + +World +===== + +The world is the whole area, in which content is rendered. For a view +without a viewport, this is the whole itself. A view with a viewport +provides a way, so that the user may see some part of the world within +a (in most cases) smaller window, the viewport. + +The world may have a base line, so that the worls size is described by +three numbers, width, ascent and descent. + +Any view must implement the method set_world_size(), which is called, +whenever the world size changes. For viewports, this will change +scroll bars etc., for views without viewport, this will normally +change the size of the view itself. (Although on this level, "view +size" is not defined. This should not be confused with the viewport +size!) + + +Drawing +======= + +A view must implement several drawing methods, which work on the whole +world. If it is neccesary to convert them (e.g. in DwGtkViewport), +this is done in a way fully transparent to DwWidget and +DwRenderingLayout, instead, this is done by the view implementation. + +There exist following situations: + + - A view gets an expose event: It will delegate this to the + rendering layout, which will then pass it to the widgets, with + the view as a parameter. Eventually, the widgets will call + drawing methods of the view. + + - A widget requests a redraw: In this case, the widget will + delegate this to the layout. The drawing requests are queued, and + compressed. in an this idle function, DwWidget::draw is called + for the toplevel widget, for each view. + + (This is still something to consider, the queueing may be moved + again into the view implementations.) + +If the draw method of a widget is implemented in a way that it may +draw outside of the widget's allocation, it should draw into a +clipping view. A clipping view is a rendering view related to the +actual rendering view, which guarantees that the parts drawn outside +are discarded. At the end, the clipping view is merged into the actual +view. Sample code for widget DwFoo: + + void Dw_foo_draw (DwWidget *widget, + DwRenderView *view, + DwRectangle *area) + { + DwRenderView *clip_view; + + /* 1. Create a clipping view. */ + clip_view = + p_Dw_render_view_get_clipping_view (view, + widget->allocation.x, + widget->allocation.y, + widget->allocation.width + DW_WIDGET_HEIGHT (widget)); + + /* 2. Draw into clip_view. */ + Dw_render_view_do_some_drawing (clip_view, ...); + + /* 3. Draw the children, they receive the clipping view as argument. */ + for (<all relevant children>) { + if (p_Dw_widget_intersect (button->child, area, &child_area)) + p_Dw_widget_draw (child, clip_view, child_area); + } + + p_Dw_render_view_merge_clipping_view (view, clip_view); + } + +A drawing process is always embedded into calls of +DwRenderView::start_drawing() and DwRenderView::finish_drawing(). An +implementation of this are backing pixmaps, to prevent flickering. + + +Viewports and Scrolling Positions +================================= + +Although the design implies that the usage of viewports should be +fully transparent to the Dw_render module, this cannot be fully +archived, for the following reasons: + + 1. Some features, which are used on the level of DwWidget, + e.g. anchors, refer to scrolling positions. + + 2. Some code in DwWidget is currently tightly bound to viewports. + This may be change, by delegating some of this functionality to + viewports, and defining scrolling positions in a more abstract + way. + +Therefor, DwRenderLayout keeps track of the viewport size, the +viewport position, and even the thickness of the scrollbars (or, +generally, "viewport marker"), they are relevant, see below. These +sizes are always equal in all views. However, a given view may not use +viewports at all, and there may be the case, that no view related to a +layout uses viewports, in this case, the viewport size is not defined +at all. + +Unlike world sized, viewports are not considered to have a base line, +i.e., they are described by only two numbers, width and height. + +Viewport Size +------------- +All viewport sizes and positions are the same in all views, which uses +viewports. There are two cases, in which the viewport size changes: + + 1. As an reaction on a user event, e.g. when the user changes the + window size. In this case, the affected view delegates this + change to the layout, by calling + p_Dw_render_layout_vieport_size_changed(). All other views are + told about this, by calling DwRenderView::set_viewport_size(). + + 2. The viewport size may also depend on the visibility of UI + widgets, which depend on the world size, e.g scrollbars, + generally called "viewport markers". This is described in an own + section. + +After the creation of the layout, the viewport size is undefined. When +a view is attached to a layout, and this view is already to be able to +define its viewport size, it may already call +p_Dw_render_layout_vieport_size_changed() within the implementation of +set_layout. If not, it may do this, as soon as the viewport size gets +known. + +Each call of p_Dw_render_layout_vieport_size_changed() will change the +viewport size of all other views, which use viewports, so this +function has to be called with care. + +If there is no view attached, which used viewports, the viewport size +remains undefined. + +Viewport Markers +---------------- +Viewport markers are UI widgets, which display to the user the +relation of the world size and the widget size. Most commonly, +scrollbars will be used. + +When they are not needed, they are hidden, as in the following figure: + + + +--------------------+ + | This is only a | + | very short text. | + | | + | | + | | + +--------------------+ + +but shown, as soon as the world size exceeds the viewport size: + + +------------------+-+ + | In this example, |^| + | there is some |#| + | more text, so |#| + | that the | | + | vertical |v| + +------------------+-+ + +A view using viewports must provide, how large the differences +are. Generally, there are four cases, from the combinations of whether +the world width is smaller (-) or greater (+) than the viewport width, +and whether the world height is smaller (-) or greater (+) than the +viewport height. So there are eight numbers, the horizontal difference +dh, and the vertical difference dv, for the cases --, -+, +-, and ++. + +For scrollbars, the values are rather simple: + + - dh is 0 for the cases -- and -+, and the thickness of the + vertical scrollbar in the cases +- and ++. + + - dv is 0 for the cases -- and +-, and the thickness of the + horizontal scrollbar in the cases -+ and ++. + +For any view implementation, the following rules must be fullfeeded +(dx means either dh or dv): + + - dx(-+) >= d(--) + - dx(++) >= d(+-) + - dx(+-) >= d(--) + - dx(++) >= d(-+) + +In short, when smaller world dimensions (-) grow (switch to +), the +differences may not become less. + +The sizes of viewport markers are part of the viewport size, the +method DwRenderView::set_viewport_size() has four parameters: + + - two for the size of the viewport, *including* the markers + (i.e. the markers never change the size), and + + - two, which denote the differences between the above and the + actual viewport size, caused by the markers. If a value of these + is 0, the respective marker is hidden, if it is greater than 0, + it is shown. In the latter case, the maximun is calculated, and + passed to all views. + +(Actually, the decision, whether the markers are visible or not, is a +bit more complicated, since the vieport size also defines the size +hints for the topmost widget, which may affect the widget size, and so +the world size. Handling this problem is done within DwRenderLayout, +look at the comments there.) + +Scrolling Positions +------------------- +The scrolling position is the world position at the upper left corner +of the viewport. Views using viewports must + + 1. change this value on request, and + 2. tell other changes to the layout, e.g. caused by user events. + +Applications of scrolling positions (anchors, test search etc.) are +handled by the layout, in a way fully transparent to the views. + + +An Example with Nested Views +============================ +The following example refers to graphical plugins, which are not yet +realized (I have some working proof-of-concept code), but which will +most likely follow the design, which is here shortly described, as +needed to understand the example (since there is no specification of +graphical plugins yet). I included this, to demonstrate, how nested +layouts can be used. + +Graphical plugins will communicate with dillo via two protocols, dpi1 +(for anything not directly related to rendering), and a new protocol, +which is an extension of the XEmbed protocol (see somewhere at +http://freedesktop.org, this is the protocol, which GtkPlug and +GtkSocket use). Within dillo, a socket window will be created, which +window id will be (via dpi1?) passed to the plugin. The plugin will +then create a plugin window, in which the contents of a web recource +is shown, which dillo cannot show natively. + +XEmbed will be extended, so that the plugins may make use of the +extensions, which the Dw size model adds to the XEmbed size +model. Such a plugin behaves (on an abstract level) like a DwWidget, +so following extensions are necessary: + + - a plugin may not simply have a size, but instead distinguish + between ascent and descent, + - a plugin may return width extremes, and + - it is possible to send size hints to the plugin. + +Within Dw, the socket will be realized by a special plugin, +DwSocketGtk (or a respective widget for other platforms), which is a +sub class of DwEmbedGtk, and embeds another UI widget, which will +provide the socket window (for Gtk+, either GtkSocket, or a sub class +of this). + +The plugins may be implemented independently of Dw, they either do not +support the extensions to XEmbed (then, the respective features behave +in a default way), or they may contain there own implementation. +However, Dw may be extracted from dillo, to become an own library. A +plugin using this library may then use a special type of view, +GtkDwFlatView (for plugins based on Gtk+, actually, the UI toolkit for +dillo and the plugin must not be the same, since the protocol will be +UI toolkit independant.) + +This will lead to a structure like this: + + top_layout:DwRenderLayout ----- top_page:DwPage + / \ | + :GtkDwPlatform top_view:GtkDwView `- table:DwTable + | + `- cell:DwTableCell + | + `- socket:DwSocketGtk + | + DILLO gtk_socket:GtkSocket + . +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - . (extension of + . XEmbed) + PLUGIN + plugin_layout:DwRenderLayout ----- dw_flat_view:GtkDwFlatView + \ + `------- foo:DwFoo + +GtkDwFlatView is both an extension of GtkSocket, as well as an +implementation of DwRenderView. + +This case must be equivalent to the case, that the widget "foo" is a +direct child of the widget "cell", since all objects between them only +delegate all functionality. Size hints must so sent as in the +following scenario: + + 1. The view "top_view" receieves an event, which will change the + viewport size, and delegates this to the layout. + + 2. The layout will make size hints of this viewport size, i.e., it + calls the set_* methods of the widget "top_page". + + 3. DwPage::set_* will queue a resize request, which is delegated + to the layout. + + 4. Handling the resize request is done within a idle loop. Here, + size_request is called for the widget "top_page", to determine + the preferred size. + + 5. DwPage::size_request will depend on the size hints, especially, + it will use the hinted size to determine the word wrap width. + Within DwPage::size_request, size hints will be sent to the + child widgets. The size hints sent to the children are those + sent to the page, minus the respective border widths (margins, + borders, paddings). (How the ascent and descent hints should + generally be delegated to the children, is still a matter of + consideration, and may change.) + + 6. DwTable::size_request, which is called within this context, has + a different way to delegate the size hints to the children: + ascent and descent are handled the same way, but the widths are + calculated from the column widths, which are calculated within + DwTable::size_request. + + 7. Via the widget "cell", finally the widget "socket" receives + appropriate size hints. These must be (equally) delegated to + the widget "foo", this is done in a way described in the + following steps. + + 8. The size hints are transmitted via the protocol extending + XEmbed. The Gtk+ widget "dw_flat_view" receives them (via the + widget "gtk_socket"), and delegates them to the respective + layout "plugin_layout". (TODO: How is this done? What has to be + done is to send the size hints to the toplevel widget, but a + view has no access to it.) + + 9. The layout "plugin_layout" will then delegate this (what ever + "this" means), as size hints, to the widget "foo". + + 10. The widget "foo" will queue a size_request, which is delegated + to the layout. In the idle function handling this request, the + recalculation of the widget size will change the world size, + which is delegated to the view "dw_flat_view". + + 11. For GtkDwFlatView, the world size is the view size. For this + reason, it changes its size, to fit the world size. This size + is send to the DwSocket, which will then request a size + request. + + +UI Widgets +========== +A note before: This chapter refers often to Gtk+ as base UI toolkit, +just to make naming simpler, For other UI toolkits, the same, mostly +only with other names, applies. + +In some cases, it is necessary to embed widgets from the UI toolkit +into the view, e.g. to realize HTML forms in dillo. + +The Dw_render module provides no interface at all, instead, this is +completely left to the platform implementations. Below, two design +approaches are discussed, which have following in common: + + 1. There is a special Dw widget, which embeds something related to + the UI widgets (below called DwEmbedGtk). + + 2. This Dw widget, the platform, and the views are tightly bound, + beyond the methods, which the respective interfaces provide. The + Dw widget can simply refer to the platform by + (DwWidget::render_layout->platform, and the platform may refer + to the views, when DwPlatform::attach_view and + DwPlatform::detach_view are implemented. + +General Problems +---------------- +For most UI toolkits, there have to be multiple instances of widgets +in different views. Furthermore, there may be, on the same platform, +different classes for the same widgets. Consider this simple example: + + :DwRenderLayout ------------------- :DwPage + / \ | + ,----' `----. dw:DwEmbedGtk + / \ + view1:GtkDwViewport view2:GtkDwViewport + | | + gtk1:GtkButton gtk2:GtkButton + +This structure represents a page with one button in it, which is, in +the DwWidget tree, represented by the DwEmbedGtk "dw", and, in the +views "view1" and "view2", by the Gtk+ widgets "gtk1" and "gtk2", +respectively. The old approach, where the UI widget (in this case +GtkButton) is not directly applicable, since there must be multiple +instances of this UI widget. + +Here is a more complex example: + + :DwRenderLayout ------------------- :DwPage + / \ | + ,----' `----. dw:DwEmbedGtk + / \ + view1:GtkDwFooView view2:GtkDwBarView + | | + gtk1:GtkFooButton gtk2:GtkBarButton + +In this case, the different views GtkDwFooView and GtkDwBarView deal +with different classes for buttons, GtkFooButton and GtkBarButton. + +Simple Approach +--------------- +Within dillo, the following limitations are reasonable: + + 1. There is only one view instance, which actually needs UI widgets + (GtkDwViewport for Gtk+). There may be multiple views, but these + additional views do not need instances of widgets, e.g. in the + preview, a UI widget is simply shown as a grey box. + + 2. There is only one type of UI widget, i.e. normal Gtk+ widgets. + +Because of these limitations, the implementation of UI widgets is +currently quite simple in dillo. As before, the widget DwEmbedGtk +refers to an instance of a concrete Gtk+ widget. This Gtk+ widget is +told to the platform, of which DwEmbedGtk knows, that it is an +instance of GtkDwPlatform. GtkDwPlatform will add this Gtk+ widget to +the single view, which needs it, and DwEmbedGtk will be responsible of +allocating etc. of the Gtk+ widget. + +Advanced Approach +----------------- +This is a short overview of an approach, which will overcome the +limitations of the simple approach, but with the costs of a greater +complexity. It will be detailed, in the case, that it is implemented. + + +------------+ factory +---------------------+ + | DwEmbedGtk | ---------> | DwGtkWidgetFactory | + +------------+ 1 1 +---------------------+ + | create_foo_widget() | + | create_bar_widget() | + +---------------------+ + . . . + /_\ /_\ /_\ + | | | + - - - - - - - - - - - - - - - - - . + | | + +---------------------+ +---------------------+ | + | DwGtkButtonFactory | | DwGtkListFactoty | (other ...) + +---------------------+ +---------------------+ + | create_foo_widget() | | create_foo_widget() | + | create_bar_widget() | | create_bar_widget() | + +---------------------+ | add_list_item(...) | + +---------------------+ + +DwEmbedGtk refers to a factory, which creates the UI widgets for each +view. For each general widget type (e.g. button, list, ...), there is +an implementation of this interface. + +This interface DwGtkWidgetFactory contains different method for +different views. E.g., when a button is shown, and so DwEmbedGtk +refers to a DwGtkButtonFactoty, GtkDwFooView may need a GtkFooButton, +which is created by create_foo_widget(), while GtkDwBarView may call +create_bar_widget(), to get a GtkBarButton. (This design still makes +it hard to add new views, which then need, say, GtkBazButtons.) + +The concrete factories may contain additional methods, in the diagram +above, DwGtkListFactory must provide a function to add items to the +lists. This method will add a item to all list widget, which were +created by this factory. + + +More Ideas for View Implementations +=================================== + +Preview Window +-------------- +The status bar gets a new button, on which the user may click to get a +small image of the small page, in which he can select the viewport +position by dragging a rubber-band rectangle. The actual scaling +factor will probably depend on the aspect ratio of the page. + +(This has already been implemented for Gtk+, as GtkDwPreview and +GtkDwPreviewButton.) + +Graphical Plugin +---------------- +See section "An Example with Nested Views" for explanations. + +====================================================================== + +Alternative design for handling UI widgets: + +- There is a platform *independant* widget, the platform dependencies + are within the factories. + + DwEmbedUI::draw + -> DwRenderView::draw_ui_widget(..., factory) + +Implementation of "draw_ui_widget" in a preview view: + -> draw some gray boxes etc. + +Implementation of "draw_ui_widget" in a normal "bar" view (for platform "foo"): + -> determine that is is a factory for a "baz" widget? + -> (BarFactory*)factory->get_foo_bar_widget(this) + +This method either returns an already created widget, or creates one +with the current state of the factory. "This" is taken as a key. + +---- + + | general | widget specific +----------------------+------------------+------------------------ + platform independant | nothing? | e.g. adding list items +----------------------+------------------+------------------------ + platform dependant | e.g. creating a | ??? + | widget, or | + | informations | + | about drawing in | + | a preview | + +====================================================================== + +Abstraction of DwStyle +---------------------- +structures needed:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/DwStyle.txt Sun Oct 07 00:36:34 2007 +0200 @@ -0,0 +1,310 @@ +Apr 2001, S.Geerken@ping.de +Last update: Dec 2004 + +======= +DwStyle +======= + +Styles of Dillo Widgets + + +Note +==== + +DwStyle has derived from DwPageAttr, and its current structure is very +similar to it. In the future, there will be some changes and extensions. +Namely: + + - image maps will be handled differently (done), + - margins, borders, paddings (done), + - background colors/images, and + - cursors and tooltips will perhaps move into DwStyle. + +Furthermore, widgets will probably refer to different styles for +different states. + + +Overview +======== + +DwStyle provides some resources and attributes for drawing widgets, as +well as for parts of a widget (e.g., DwPage uses DwStyle's for its +words). Creating a style is done by filling a DwStyle with the +attributes (except the ref_count), and calling Dw_style_new: + + DwStyle style_attrs, *style; + + style_attrs.foo = bar; + // etc. + style = a_Dw_style_new (&style_attrs, random_window); + // do something with style + +After this, the attributes of style should not be changed anymore, +since styles are often shared between different widgets etc. (see +below). Most times, you simply copy the attributes of another style +and modify them: + + style_attrs = *another_style; + style_attrs.foo = bar; + style = a_Dw_style_new (&style_attrs, random_window); + +The font structure can be created by Dw_style_font_new, in a similar +way (the GdkFont in font_attrs will be ignored), and colors by +Dw_style_color_new, passing 0xrrggbb as an argument. Note that fonts +and colors are only intended to be used in conjunction with DwStyle. + + +Lengths and Percentages +======================= + +DwStyleLength is a simple data type for lengths and percentages: + + - A length refers to an absolute measurement. It is used to + represent the HTML type %Pixels; and the CSS type <length>. + + For CSS lenghts, there are two units: (i) pixels and absolute + units, which have to be converted to pixels (a pixel is, unlike + in the CSS specification, treated as absolute unit), and (ii) the + relative units "em" and "ex" (see below). + + - A percentage refers to a value relative to another value. It is + used for the HTML type %Length; (except %Pixels;), and the CSS + type <percentage>. + + - A relative length can be used in lists of HTML MultiLengths. + +Since many values in CSS may be either lengths or percentages, a +single type is very useful. + +Useful macros and functions +--------------------------- +Macros for creating lengths: + + DW_STYLE_CREATE_LENGTH (n) Returns a length of n pixels. + + DW_STYLE_CREATE_EX_LENGTH (n) Returns a length of n times the + 'x-height' + + DW_STYLE_CREATE_EM_LENGTH (n) Returns a length of n times the + 'font-size' + + DW_STYLE_CREATE_PERCENTAGE (n) Returns a percentage, n is relative + to 1, not to 100. + + DW_STYLE_CREATE_RELATIVE (n) Returns a relative length. + + DW_STYLE_UNDEF_LENGTH Used to indicate unspecified sizes, + errors, and the end of a list of + lengths. + +Furthermore, there are some functions in html.c: + + DwStyleLength Html_parse_length (gchar *attr); + + Returns a length or a percentage, or DW_STYLE_UNDEF_LENGTH in + case of an error. + + DwStyleLength* Html_parse_multi_length (gchar *attr); + + Returns a vector of lengths/percentages. The caller has to free + the result when it is not longer used. + +Macros for examining lengths: + + DW_STYLE_IS_LENGTH (l) Returns TRUE if l is a length. + + DW_STYLE_IS_PERCENTAGE (l) Returns TRUE if l is a percentage. + + DW_STYLE_IS_RELATIVE (l) Returns TRUE if l is a relative + length. + + DW_STYLE_GET_LENGTH (l, f) Returns the value of a length in + pixels, as an integer. f is the + font, this is used if l is based on + font sizes. + + DW_STYLE_GET_PERCENTAGE (l) Returns the value of a percentage, + relative to 1, as a float. + + DW_STYLE_GET_RELATIVE (l) Returns the value of a relative + length, as a float. + + +Representation +-------------- +Notes: + + 1. This is not part of the interface and may change! Use the + macros described above. + 2. Negative numbers may not work yet. + +DwStyleLength is represented by an integer (n is the number of bits of +an integer): + + - Undefined lengths are represented by 0. + + - Lenghts in pixel: + + +---+ - - - +---+---+---+---+ + | int value | 0 | 1 | + +---+ - - - +---+---+---+---+ + n-1 3 2 1 0 + + - Lengths in in x-height: + + +---+ - - - +---+---+---+---+ + | real value | 0 | 1 | 1 | + +---+ - - - +---+---+---+---+ + n-1 3 2 1 0 + + - Lengths in in font-size: + + +---+ - - - +---+---+---+---+ + | real value | 1 | 1 | 1 | + +---+ - - - +---+---+---+---+ + n-1 3 2 1 0 + + - Percentages: + + +---+ - - - +---+---+---+---+ + | real value | 0 | 1 | 0 | + +---+ - - - +---+---+---+---+ + n-1 3 2 1 0 + + - Relative lengths: + + +---+ - - - +---+---+---+---+ + | real value | 1 | 1 | 0 | + +---+ - - - +---+---+---+---+ + n-1 3 2 1 0 + +A "real value" is a fixed point number consisting of (m is the number +of bits of the value, not the whole integer): + + +---+ - - - +---+---+ - - - +---+ + | integer part | rest | + +---+ - - - +---+---+ - - - +---+ + m 16 15 0 + +For *internal* use, there are two converting macros, +DW_STYLE_REAL_TO_FLOAT and DW_STYLE_FLOAT_TO_REAL. + + +DwStyle Boxes +============= + +The CSS Box Model +----------------- +For borders, margins etc., DwStyle uses the box model defined by +CSS2. DwStyle contains some members defining these attributes. A +widget must use these values for any calculation of sizes. There are +some helper functions (see dw_style.h). A DwStyle box looks quite +similar to a CSS box: + + + ,-- margin.left + | ,-- border.left + | | ,-- padding.left + |---+---+---| + +---------------------------------------+ --- + | | | margin.top + | +-------------------------------+ | -+- + | | Border | | | border.top + | | +-----------------------+ | | -+- + | | | Padding | | | | padding.top + new widget | | | +---------------+ | | | --- + allocation -->| | | | | | | | + | | | | Content | | | | + former widget ------------>| | | | | + allocation | | | +---------------+ | | | --- + | | | | | | | margin.bottom + | | +-----------------------+ | | -+- + | | | | | border.bottom + | +-------------------------------+ | -+- + | | | padding.bottom + +---------------------------------------+ --- + |---+---+---| + padding.right --' | | + border.right --' | + margin.right --' + +Background colors +----------------- +The background color is stored in style->background_color, which be +NULL (the background color of the parent widget is shining through). + +For toplevel widgets, this color is set as the background color of the +viewport, for other widgets, a filled rectangle is drawn, covering the +content and padding. (This is compliant with CSS2, the background +color of the toplevel element covers the whole canvas.) + +Drawing +------- +There is a new function Dw_widget_draw_widget_box, which should be +called at the beginning of Dw_foo_draw. For parts referring to styles +(e.g., words in a page), Dw_widget_draw_box should be used. + + +Notes on Memory Management +========================== + +Memory management is done by reference counting, a_Dw_style_new +returns a pointer to DwStyle with an increased reference counter, so +you should care about calling Dw_style_unref if it is not used +anymore. You do *not* need to care about the reference counters of +fonts and styles. + +In detail: + + - a_Dw_style_ref is called in + + * a_Dw_widget_set_style, to assign a style to a widget, + + * a_Dw_page_add_text, a_Dw_page_add_widget, + a_Dw_page_add_anchor, to assign a style to a word, + + * and Html_push_tag (often the reference counter is again + decreased shortly after this). + + - a_Dw_unref_style is called in: + + * Dw_page_destroy, Dw_widget_destroy, Html_cleanup_tag, + Html_pop_tag, Html_close, + + * a_Dw_widget_set_style, Html_set_top_font (and several + Html_tag_open_... functions), these functions overwrite an + existing style. + + +HTML Stack +========== + +(This is not DwStyle specific, but may be useful if you are working on +the HTML parser.) + +The topmost element of the HTML stack contains a (reference to a) +style which will be used to add the text to the current page. If you +use a style only for a short while (see Html_tag_open_frame for an +example), you may use it this way: + + style_attrs = *html->stack[html->stack_top].style; + style_attrs.foo = bar; + style = a_Dw_style_new (&style_attrs, random_window); + +Do not forget to unref it afterwards. A good choice for random_window +is html->bw->main_window->window. + +In many cases, you want to set the style for the content of an element +(e.g., <A>). Then you must store it in the stack: + + DwStyle style_attrs, *old_style; + + old_style = html->stack[html->stack_top].style; + style_attrs = *old_style; + style_attrs.foo = bar; + html->stack[html->stack_top].style = + a_Dw_style_new (&style_attrs, random_window); + a_Dw_style_unref (old_style); + +The macro HTML_SET_TOP_ATTR can be used for single attributes, for +changing more attributes, this code should be copied for efficiency.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/DwTable.txt Sun Oct 07 00:36:34 2007 +0200 @@ -0,0 +1,205 @@ +May 2001, S.Geerken@ping.de +Last update: Dec 2004 + +======= +DwTable +======= + +A container widget for rendering tables. + + +The DwTable Widget +================== + +DwTable is a container widget for rendering tables. It aligns other +DwWidgets (normally DwPage), according to the following rules: + + 1. All columns have have the same width W, except: + + - W is less than the minimal column width, or + - W is greater than the maximal column width. + + Furthermore, W is + + - less than all minimal widths of columns not having W as + width, and + - greater than all maximal widths of columns not having W as + width. + + 2. The table tries to use exactly the whole available width, except + if it is not possible, because the it is less/greater than the + minimal/maximal table width. + +This is simple to implement for columns with COLSPAN == 1, using +a_Dw_get_extremes for getting the minimal and maximal widths. For +arbitrary COLSPAN values, an approach described in "Subtables" is +used to get optimal results (as described above) in most cases, while +the rendering remains fast. + + +Subtables +========= + +A table is divided into subtables, which do not (in most cases) share +spanning cells, until single columns are left. Cells spanning the +whole width are removed before dividing further. Example: + + +---+-------+---+ + | A | B | C | + +---+-------+---+ + | D | E | + +---+-------+---+ + | F | G | H | + +---+-------+---+ + ' ' ` ` + ' ' ` ` + +---+-------+ +---+ + | A | B | | C | + +---+-------+ +---+ + removed --> | D | | E | + +---+-------+ +---+ + | F | G | | H | + +---+-------+ +---+ + ' ' ` ` final + ' ' ` ` + +---+ +-------+ + | A | | B | <-. + +---+ +-------+ >- removed + | F | | G | <-' + +---+ +-------+ + final ' ' ` ` + ' ' ` ` + [empty] [empty] + final final + +There is a structure, DwTableSub, for holding all the information. It +is rebuilt when new cells are added. Do not confuse this with nested +tables, these are represented by the Dw widget hierarchy. + +If table cells overlap horizontally, they are (virtually) divided. The +minimal and maximal widths are apportioned to the other columns +(resulting in a non optimal layout): + + +-------+---+---+ + | A | B | C | + +---+---+---+---+ + | D | E | + +---+-----------+ + ' ' ` ` + ' ' ` ` + +-------+ +---+---+ + | A | | B | C | + +---+---+ +---+---+ + | D |1/3| | 2/3 E | + | | E | | | + +---+---+ +-------+ + +Example for a non-optimal case +------------------------------ +The HTML document fragment + + <table> + <tr> + <td colspan="2">Text + <td>LongText + <tr> + <td>Text + <td colspan="2">LongText + </table> + +will result in: + + | 0 | 1 | 2 | + + +------------+----------+ + | Text | LongText | + +------+-----+----------+ + | Text | LongText | + +------+----------------+ + +The width of column 1 is determined by the half of the minimal width +of the LongText. An optimal rendering would be something like: + + ,- 1 + | 0 || 2 | + + +-------+----------+ + | Text | LongText | + +------++----------+ + | Text | LongText | + +------+-----------+ + + +Algorithms +========== + +Calculating extremes +-------------------- +The extremes of all subtables are calculated by +Dw_table_sub_get_extremes and stored in DwTableSub: + + minimal/maximal width (sub table) = + - for single column: maximum of all minimal/maximal widths + - otherwise: maximum of + 1. all minimal/maximal widths of cells spanning + the whole width, and + 2. the sum of the minimal/maximal widths of the + sub-subtables + + In step 1, the width argument is used to adjust the maximum + and minimum width of the whole subtable and mark it as fixed. + +todo: describe percentages. + +Calculating column widths +------------------------- +The calculation is based on a fixed width, which is, at the top, the +width set by a_Dw_widget_set_width. This is corrected by the minimal and +maximal width of the whole table, and, if given, the width attribute +of the table. At each level, the available width is always between the +minimal and the maximal width of the subtable. + +For single columns, the width is the passed fixed width. Otherwise: + + 1. Calculate relative widths, they effect the minimal and maximal + widths. (Temporally, not permanently!) + + 2. The sum of these corrected minima may be greater as the fixed + width of the subtable. In this case, decrease them again to + match exactly the fixed width, then use them as sub-subtable + fixed widths and finish. Otherwise, continue: + + 3. If the extremes of the spanning widths of the subtable are + greater than the sum of sub-subtables extremes, adjust the + extremes of sub-subtables which are not fixed, i.e., where no + width argument (either percentage or fixed) freezes the width. + + 4. Use an iteration on the subtables, to determine the column + widths, see Dw_table_sub_calc_col_widths for details. + + 5. After this, apply this recursively on all subtables and pass the + subtable width as fixed width. + + +Borders, Paddings, Spacing +========================== + +Currently, DwTable supports only the separated borders model (see CSS +specification). Borders, paddings, spacing is done by creating DwStyle +structures with values equivalent to following CSS: + + TABLE { + border: outset <table-border>; + border-collapse: separate; + border-spacing: <table-cellspacing> + background-color: <table-bgcolor> + } + + TD TH { + border: inset <table-border>; + padding: <table-cellspacing> + background-color: <td/th-bgcolor> + } + +Here, <foo-bar> refers to the attribute bar of the tag foo. See +Html_open_table and Html_open_table_cell for more details.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/DwWidget.txt Sun Oct 07 00:36:34 2007 +0200 @@ -0,0 +1,339 @@ +Jan 2001, S.Geerken@ping.de +Last update: Dec 2004 + +======== +DwWidget +======== + +The base object for all Dw widgets. + + +Structures +========== + +DwRectangle +----------- +A replacement for GdkRectangle, the only difference is the use of 32 +instead of 16 bit integers. + + +DwAllocation, DwRequisition +--------------------------- +Similar to GtkAllocation and GtkRequisition. Instead of a height, you +have two members, ascent and descent. + + +DwExtremes +---------- +A structure containing the minimal and maximal width of a widget. See +get_extremes below for details. + + +DwWidget +-------- +Some members you may use: + + parent The parent widget. NULL for toplevel widgets. + + flags See below. + + style The style attached to the widget, this must + always be defined, but is not created + automatically. Instead, this has to be done + immediately after creating the widget + (e.g., in a_Web_dispatch_by_type). This style + contains attributes and resources for general + drawing. See DwStyle.txt for details. + +These members should only be used within the "core" (GtkDw*, DwWidget +and DwEmbedGtk): + + viewport The viewport containing the widget. Defined + for all widgets. + + allocation, + requisition, + extremes, + user_requisition These are used to optimize several wrappers, + see below. + + anchors_table See notes on achors. + +Flags +----- +Flags can be set and unset with DW_WIDGET_SET_FLAGS and +DW_WIDGET_UNSET_FLAGS. For reading flags use the macros DW_WIDGET_... + + DW_NEEDS_RESIZE + DW_EXTREMES_CHANGED Denotes that the widget must be resized. Used + only internally. See Dw.txt and the source + for more details. + + DW_NEEDS_ALLOCATE Set to overide the optimation in + a_Dw_widget_size_allocate. Used only + internally. + + DW_REALIZED Set when the widget is realized. Should be + used to prevent crashes in certain + situations. + +Following flags describe characteristics of widgets and are typically +set in the init function: + + DW_USES_HINTS A widget with this flag set has a complex way + to deal with sizes, and should + + - implement the functions set_width, + set_ascent, set_descent, and + get_extremes, and + - deal completely with width and height + in widget->style. + + Examples are DwPage and DwTable. Other + widgets, like DwImage and DwHRuler, are much + simpler and don't have to set this flag. For + these widgets, much of the size calculation + is done by the parent widget. + + This flag is unset by default. + + DW_HAS_CONTENT If this flag is set, more space is reserved + for the widget in some circumstances. E.g., + if an image has a width of 100%, it makes + sense to use more space within a table cell, + as compared to a horizontal ruler, which does + not "have a content". + + This flag is set by default. + + +Signal Prototypes +================= + + - void size_request (DwWidget *widget, + DwRequisition *requisition); + + Similar to Gtk. + + void get_extremes (DwWidget *widget, + DwExtremes *extremes); + + Return the maximal and minimal width of the widget, equivalent + to the requisition width after calling set_width with zero and + infinitive, respectively. This is important for fast table + rendering. Simple widgets do not have to implement this; the + default is the requisition width for both values. + + - void size_allocate (DwWidget *widget, + DwAllocation *allocation); + + Similar in Gtk. Note: allocation has world coordinates. + + - void set_width (DwWidget *widget, + guint32 width); + + - void set_height (DwWidget *widget, + guint32 height); + + These are hints by the caller, which *may* influence the size + returned by size_request. The implementation should call + Dw_widget_queue_resize if necessary. In most cases, these + signals do not have to be implemented. Currently, only the + DwPage widget uses this to determine the width for rewrapping + text (note that the resulting width returned by + Dw_page_size_request may be _bigger_) and relative sizes of the + children. + + - void draw (DwWidget *widget, + DwRectangle *area, + GdkEventExpose *event); + + Draw the widget's content in the specified area. It may either + be caused by an expose event, or by an internal drawing request + (e.g., followed by resizing of widgets). In the first case, you + get the *original* expose event as third argument. In the + latter, event is NULL. The area argument has widget + coordinates. A DwContainer is responsible for drawing its + children. + + (Since DwWidget's are always windowless, there was no need for + two signals, "draw" and "expose_event".) + + - void realize (DwWidget *widget); + + Create all necessary X resources. Called when either the + viewport (top-level widgets) or, respectively, the parent Dw + widget is realized, or an widget is added to an already + realized Dw widget/viewport. + + - void unrealize (DwWidget *widget); + + Remove created X resources. + + - gint button_press_event (DwWidget *widget, + guint32 x, + guint32 y, + GdkEventButton *event); + + This signal is emitted when the user presses a mouse button in + a DwWidget. x and y are the coordinates relative to the origin + of the widget, event is the *original* event, which may, e.g., + be used to determine the number of the pressed button, the state + of the shift keys, etc. The implementation of this signal + should return TRUE, if the event has been processed, otherwise + FALSE. + + A DwContainer is *not* responsible for delivering button press + events to its children. Instead, Dw first emits the + button_press_event signal for the most inner widgets and + continues this for the parents, until TRUE is returned. + + - gint button_release_event (DwWidget *widget, + guint32 x, + guint32 y, + GdkEventButton *event); + + Compare button_press_event. + + - gint motion_notify_event (DwWidget *widget, + guint32 x, + guint32 y, + GdkEventMotion *event); + + Compare button_press_event. event may be NULL when the call was + caused by something different than a "real" motion notify event. + E.g., either when widgets are moved (not yet implemented), or the + viewport. + + - gint enter_notify_event (DwWidget *widget, + DwWidget *last_widget, + GdkEventMotion *event); + + These "events" are simulated based on motion nofify events. + event is the *original* event (may also be NULL in some cases). + last_widget is the widget in which the pointer was in before. + + - gint leave_notify_event (DwWidget *widget, + DwWidget *next_widget, + GdkEventMotion *event); + + Compare enter_notify_event. next_widget is the widget the + pointer is now in. + + +Useful Internal Functions and Macros +==================================== + + - gint Dw_widget_intersect (DwWidget *widget, + DwRectangle *area, + DwRectangle *intersection); + + Calculates the intersection of widget->allocation and area, + returned in intersection (in widget coordinates!). Typically + used by containers when drawing their children. Returns whether + intersection is not empty. + + - gint32 Dw_widget_x_viewport_to_world (DwWidget *widget, + gint16 viewport_x); + + - gint32 Dw_widget_y_viewport_to_world (DwWidget *widget, + gint16 viewport_y); + + - gint16 Dw_widget_x_world_to_viewport (DwWidget *widget, + gint32 world_x); + + - gint16 Dw_widget_y_world_to_viewport (DwWidget *widget, + gint32 world_y); + + These functions convert between world and viewport coordinates. + + - void Dw_widget_queue_draw (DwWidget *widget); + + - void Dw_widget_queue_draw_area (DwWidget *widget, + gint32 x, + gint32 y, + guint32 width, + guint32 height); + + - void Dw_widget_queue_clear (DwWidget *widget); + + - void Dw_widget_queue_clear_area (DwWidget *widget, + gint32 x, + gint32 y, + guint32 width, + guint32 height); + + Equivalents to the Gtk+ functions. They (currently) result in a + call of gtk_widget_xxx_area with the viewport as first + argument. x and y are widget coordinates. + + - void Dw_widget_queue_resize (DwWidget *widget, + gint ref, + gboolean extremes_changed); + + Similar to gtk_widget_queue_resize. Call this function when the + widget has changed its size. The next call to + Dw_xxx_size_request should then return the new size. + + See Dw.txt for explanation on how to use the ref argument, + extremes_changed specifies whether the extremes have changed + (the latter is often not the case for an implementations of + set_{width|ascent|descent}). + + - void Dw_widget_set_anchor (DwWidget *widget, + gchar *name, + int pos); + + Add an anchor to a widget. The name will not be copied, it has + to be stored elsewhere (DwPage e.g. stores it in the DwPageWord + structure). + + - void a_Dw_widget_set_cursor (DwWidget *widget, + GdkCursor *cursor) + + Set the cursor for a DwWidget. cursor has to be stored + elsewhere, it is not copied (and not destroyed). If cursor is + NULL, the cursor of the parent widget is used. + + (This will probably be changed in the future and replaced by a + common style mechanism.) + + - DW_WIDGET_WINDOW (widget) + + Returns the window a widget should draw into. + + +External Functions +================== + + - void a_Dw_widget_set_usize (DwWidget *widget, + guint32 width, + guint32 ascent, + guint32 descent); + + Override the "desired" size of a widget. Further calls of + a_Dw_widget_request_size will return these values, except those + specified as -1. A possible use shows Html_add_widget in + html.c. + + (This will probably be removed. Instead DwStyle should be used.) + + + - void a_Dw_widget_set_bg_color (DwWidget *widget, + gint32 color); + + Set the background color of a widget. This works currently only + for the top-level widget. In this case, the background color of + the GtkDwViewport is changed. In future, background colors for + all widgets will be needed, e.g., for table cells (will be + DwPage's), this will (probably) be based on filled rectangles. + + - void a_Dw_widget_scroll_to (DwWidget *widget, + int pos) + + Scroll viewport to pos (vertical widget coordinate). + +There are furthermore wrappers for the signals, in some cases they +are optimized and/or provide further functionality. In (almost) no +case should you emit the signals directly. See dw_widget.c for more +details.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/HtmlParser.txt Sun Oct 07 00:36:34 2007 +0200 @@ -0,0 +1,116 @@ + October 2001, --Jcid + Last update: Dec 2004 + + --------------- + THE HTML PARSER + --------------- + + + Dillo's parser is more than just a HTML parser, it does XHTML +and plain text also. It has parsing 'modes' that define its +behaviour while working: + + typedef enum { + DILLO_HTML_PARSE_MODE_INIT, + DILLO_HTML_PARSE_MODE_STASH, + DILLO_HTML_PARSE_MODE_STASH_AND_BODY, + DILLO_HTML_PARSE_MODE_BODY, + DILLO_HTML_PARSE_MODE_VERBATIM, + DILLO_HTML_PARSE_MODE_PRE + } DilloHtmlParseMode; + + + The parser works upon a token-grained basis, i.e., the data +stream is parsed into tokens and the parser is fed with them. The +process is simple: whenever the cache has new data, it gets +passed to Html_write, which groups data into tokens and calls the +appropriate functions for the token type (TAG, SPACE or WORD). + + Note: when in DILLO_HTML_PARSE_MODE_VERBATIM, the parser +doesn't try to split the data stream into tokens anymore, it +simply collects until the closing tag. + +------ +TOKENS +------ + + * A chunk of WHITE SPACE --> Html_process_space + + + * TAG --> Html_process_tag + + The tag-start is defined by two adjacent characters: + + first : '<' + second: ALPHA | '/' | '!' | '?' + + Note: comments are discarded ( <!-- ... --> ) + + + The tag's end is not as easy to find, nor to deal with!: + + 1) The HTML 4.01 sec. 3.2.2 states that "Attribute/value + pairs appear before the final '>' of an element's start tag", + but it doesn't define how to discriminate the "final" '>'. + + 2) '<' and '>' should be escaped as '<' and '>' inside + attribute values. + + 3) The XML SPEC for XHTML states: + AttrValue ::== '"' ([^<&"] | Reference)* '"' | + "'" ([^<&'] | Reference)* "'" + + Current parser honors the XML SPEC. + + As it's a common mistake for human authors to mistype or + forget one of the quote marks of an attribute value; the + parser solves the problem with a look-ahead technique + (otherwise the parser could skip significative amounts of + well written HTML). + + + + * WORD --> Html_process_word + + A word is anything that doesn't start with SPACE, and that's + outside of a tag, up to the first SPACE or tag start. + + SPACE = ' ' | \n | \r | \t | \f | \v + + +----------------- +THE PARSING STACK +----------------- + + The parsing state of the document is kept in a stack: + + struct _DilloHtml { + [...] + DilloHtmlState *stack; + gint stack_top; /* Index to the top of the stack [0 based] */ + gint stack_max; + [...] + }; + + struct _DilloHtmlState { + char *tag; + DwStyle *style, *table_cell_style; + DilloHtmlParseMode parse_mode; + DilloHtmlTableMode table_mode; + gint list_level; + gint list_number; + DwWidget *page, *table; + gint32 current_bg_color; + }; + + + Basically, when a TAG is processed, a new state is pushed into +the 'stack' and its 'style' is set to reflect the desired +appearance (details in DwStyle.txt). + + That way, when a word is processed later (added to the Dw), all +the information is within the top state. + + Closing TAGs just pop the stack. + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/IO.txt Sun Oct 07 00:36:34 2007 +0200 @@ -0,0 +1,468 @@ + +This is the updated base of a paper I wrote with Horst. +It provides a good introduction to Dillo's internals. +(Highly recommended if you plan to patch or develop in Dillo) + +It may not be exactly accurate (it's quite old), but it explains +the theory behind in some detail, so it's more than recommended +reading material. +--Jcid + + +----------------------------------------------------- +Parallel network programming of the Dillo web browser +----------------------------------------------------- + + Jorge Arellano-Cid <jcid@dillo.org> + Horst H. von Brand <vonbrand@inf.utfsm.cl> + + +-------- +Abstract +-------- + + Network programs face several delay sources when sending or +retrieving data. This is particularly problematic in programs +which interact directly with the user, most notably web browsers. +We present a hybrid approach using threads communicated through +pipes and signal driven I/O, which allows a non-blocking main +thread and overlapping waiting times. + + +------------ +Introduction +------------ + + The Dillo project didn't start from scratch but mainly working +on the code base of gzilla (a light web browser written by Raph +Levien). As the project went by, the code of the whole source was +standardized, and the networking engine was replaced with a new, +faster design. Later, the parser was changed, the streamed +handling of data and its error control was put under the control +of the CCC (Concomitant Control Chain), and the old widget system +was replaced with a new one (Dw). The source code is currently +regarded as "very stable beta", and is available at +<http://www.dillo.org>. Dillo is a project licensed under the GNU +General Public License. + + This paper covers basic design aspects of the hybrid approach +that the Dillo web browser uses to solve several latency +problems. After introducing the main delay-sources, the main +points of the hybrid design will be addressed. + + +------------- +Delay sources +------------- + + Network programs face several delay-sources while sending or +retrieving data. In the particular case of a web browser, they +are found in: + + DNS querying: + The time required to solve a name. + + Initiating the TCP connection: + The three way handshake of the TCP protocol. + + Sending the query: + The time spent uploading queries to the remote server. + + Retrieving data: + The time spent expecting and receiving the query answer. + + Closing the TCP connection: + The four packet-sending closing sequence of the TCP protocol. + + In a WAN context, every single item of this list has an +associated delay that is non deterministic and often measured in +seconds. If we add several connections per browsed page (each one +requiring at least the 4 last steps), the total latency can be +considerable. + + +----------------------------------- +The traditional (blocking) approach +----------------------------------- + + The main problems with the blocking approach are: + + When issuing an operation that can't be completed + immediately, the process is put to sleep waiting for + completion, and the program doesn't do any other + processing in the meantime. + + When waiting for a specific socket operation to complete, + packets that belong to other connections may be arriving, + and have to wait for service. + + Web browsers handle many small transactions, + if waiting times are not overlapped + the latency perceived by the user can be very annoying. + + If the user interface is just put to sleep during network + operations, the program becomes unresponsive, confusing + and perhaps alarming the user. + + Not overlapping waiting times and processing makes + graphical rendering (which is arguably the central function + of a browser) unnecessarily slow. + + +--------------------- +Dillo's hybrid design +--------------------- + + Dillo uses threads and signal driven I/O extensively to +overlap waiting times and computation. Handling the user +interface in a thread that never blocks gives a good interactive +``feel.'' The use of GTK+, a sophisticated widget framework for +graphical user interfaces, helped very much to accomplish this +goal. All the interface, rendering and I/O engine was built upon +its facilities. + + The design is said to be ``hybrid'' because it uses threads +for DNS querying and reading local files, and signal driven I/O +for TCP connections. The threaded DNS scheme is potentially +concurrent (this depends on underlying hardware), while the I/O +handling (both local files and remote connections) is +definitively parallel. + + To simplify the structure of the browser, local files are +encapsulated into HTTP streams and presented to the rest of the +browser as such, in exactly the same way a remote connection is +handled. To create this illusion, a thread is launched. This +thread opens a pipe to the browser, it then synthesizes an +appropriate HTTP header, sends it together with the file to the +browser proper. In this way, all the browser sees is a handle, +the data on it can come from a remote connection or from a local +file. + + To handle a remote connection is more complex. In this case, +the browser asks the cache manager for the URL. The name in the +URL has to be resolved through the DNS engine, a socket TCP +connection must be established, the HTTP request has to be sent, +and finally the result retrieved. Each of the steps mentioned +could give rise to errors, which have to be handled and somehow +communicated to the rest of the program. For performance reasons, +it is critical that responses are cached locally, so the remote +connection doesn't directly hand over the data to the browser; +the response is passed to the cache manager which then relays it +to the rest of the browser. The DNS engine caches DNS responses, +and either answers them from the cache or by querying the DNS. +Querying is done in a separate thread, so that the rest of the +browser isn't blocked by long waits here. + + The activities mentioned do not happen strictly in the order +stated above. It is even possible that several URLs are being +handled at the same time, in order to overlap waiting and +downloading. The functions called directly from the user +interface have to return quickly to maintain interactive +response. Sometimes they return connection handlers that haven't +been completely set up yet. As stated, I/O is signal-driven, when +one of the descriptors is ready for data transfer (reading or +writing), it wakes up the I/O engine. + + Data transfer between threads inside the browser is handled by +pipes, shared memory is little used. This almost obviates the +need for explicit synchronization, which is one of the main areas +of complexity and bugs in concurrent programs. Dillo handles its +threads in a way that its developers can think of it as running +on a single thread of control. This is accomplished by making the +DNS engine call-backs happen within the main thread, and by +isolating file loading with pipes. + + Using threads in this way has three big advantages: + + The browser doesn't block when one of its child threads + blocks. In particular, the user interface is responsive + even while resolving a name or downloading a file. + + Developers don't need to deal with complex concurrent + concerns. Concurrency is hard to handle, and few developers + are adept at this. This gives access a much larger pool of + potential developers, something which can be critical + in an open-source development project. + + By making the code mostly sequential, debugging the code + with traditional tools like gdb is possible. Debugging + parallel programs is very hard, and appropriate tools are + hard to come by. + + Because of simplicity and portability concerns, DNS querying +is done in a separate thread. The standard C library doesn't +provide a function for making DNS queries that don't block. The +alternative is to implement a new, custom DNS querying function +that doesn't block. This is certainly a complex task, integrating +this mechanism into the thread structure of the program is much +simpler. + + Using a thread and a pipe to read a local file adds a +buffering step to the process (and a certain latency), but it has +a couple of significative advantages: + + By handling local files in the same way as remote + connections, a significant amount of code is reused. + + A preprocessing step of the file data can be added easily, + if needed. In fact, the file is encapsulated into an HTTP + data stream. + + +----------- +DNS queries +----------- + + Dillo handles DNS queries with threads, letting a child thread +wait until the DNS server answers the request. When the answer +arrives, a call-back function is called, and the program resumes +what it was doing at DNS-request time. The interesting thing is +that the call-back happens in the main thread, while the child +thread simply exits when done. This is implemented through a +server-channel design. + + +The server channel +------------------ + + There is one thread for each channel, and each channel can +have multiple clients. When the program requests an IP address, +the server first looks for a cached match; if it hits, the client +call-back is invoked immediately, but if not, the client is put +into a queue, a thread is spawned to query the DNS, and a GTK+ +idle client is set to poll the channel 5~times per second for +completion, and when it finally succeeds, every client of that +channel is serviced. + + This scheme allows all the further processing to continue on +the same thread it began: the main thread. + + +------------------------ +Handling TCP connections +------------------------ + + Establishing a TCP connection requires the well known +three-way handshake packet-sending sequence. Depending on network +traffic and several other issues, significant delay can occur at +this phase. + + Dillo handles the connection by a non blocking socket scheme. +Basically, a socket file descriptor of AF_INET type is requested +and set to non-blocking I/O. When the DNS server has resolved the +name, the socket connection process begins by calling connect(2); + {We use the Unix convention of identifying the manual section + where the concept is described, in this case + section 2 (system calls).} +which returns immediately with an EINPROGRESS error. + + After the connection reaches the EINPROGRESS ``state,'' the +socket waits in background until connection succeeds (or fails), +when that happens, a callback function is awaked to perform the +following steps: set the I/O engine to send the query and expect +its answer (both in background). + + The advantage of this scheme is that every required step is +quickly done without blocking the browser. Finally, the socket +will generate a signal whenever I/O is possible. + + +---------------- +Handling queries +---------------- + + In the case of a HTTP URL, queries typically translate into a +short transmission (the HTTP query) and a lengthy retrieval +process. Queries are not always short though, specially when +requesting forms (all the form data is attached within the +query), and also when requesting CGI programs. + + Regardless of query length, query sending is handled in +background. The thread that was initiated at TCP connecting time +has all the transmission framework already set up; at this point, +packet sending is just a matter of waiting for the +write signal (G_IO_OUT) to come and then sending the data. When +the socket gets ready for transmission, the data is sent using +IO_write. + + +-------------- +Receiving data +-------------- + + Although conceptually similar to sending queries, retrieving +data is very different as the data received can easily exceed the +size of the query by many orders of magnitude (for example when +downloading images or files). This is one of the main sources of +latency, the retrieval can take several seconds or even minutes +when downloading large files. + + The data retrieving process for a single file, that began by +setting up the expecting framework at TCP connecting time, simply +waits for the read signal (G_IO_IN). When it happens, the +low-level I/O engine gets called, the data is read into +pre-allocated buffers and the appropriate call-backs are +performed. Technically, whenever a G_IO_IN event is generated, +data is received from the socket file descriptor, by using the +IO_read function. This iterative process finishes upon EOF (or on +an error condition). + + +---------------------- +Closing the connection +---------------------- + + Closing a TCP connection requires four data segments, not an +impressive amount but twice the round trip time, which can be +substantial. When data retrieval finishes, socket closing is +triggered. There's nothing but a IO_close_fd call on the socket's +file descriptor. This process was originally designed to split +the four segment close into two partial closes, one when query +sending is done and the other when all data is in. This scheme is +not currently used because the write close also stops the reading +part. + + +The low-level I/O engine +------------------------ + + Dillo I/O is carried out in the background. This is achieved +by using low level file descriptors and signals. Anytime a file +descriptor shows activity, a signal is raised and the signal +handler takes care of the I/O. + + The low-level I/O engine ("I/O engine" from here on) was +designed as an internal abstraction layer for background file +descriptor activity. It is intended to be used by the cache +module only; higher level routines should ask the cache for its +URLs. Every operation that is meant to be carried out in +background should be handled by the I/O engine. In the case of +TCP sockets, they are created and submitted to the I/O engine for +any further processing. + + The submitting process (client) must fill a request structure +and let the I/O engine handle the file descriptor activity, until +it receives a call-back for finally processing the data. This is +better understood by examining the request structure: + + typedef struct { + gint Key; /* Primary Key (for klist) */ + gint Op; /* IORead | IOWrite | IOWrites */ + gint FD; /* Current File Descriptor */ + gint Flags; /* Flag array */ + glong Status; /* Number of bytes read, or -errno code */ + + void *Buf; /* Buffer place */ + size_t BufSize; /* Buffer length */ + void *BufStart; /* PRIVATE: only used inside IO.c! */ + + void *ExtData; /* External data reference (not used by IO.c) */ + void *Info; /* CCC Info structure for this IO */ + GIOChannel *GioCh; /* IO channel */ + guint watch_id; /* glib's event source id */ + } IOData_t; + + To request an I/O operation, this structure must be filled and +passed to the I/O engine. + + 'Op' and 'Buf' and 'BufSize' MUST be provided. + + 'ExtData' MAY be provided. + + 'Status', 'FD' and 'GioCh' are set by I/O engine internal +routines. + + When there is new data in the file descriptor, 'IO_callback' +gets called (by glib). Only after the I/O engine finishes +processing the data are the upper layers notified. + + +The I/O engine transfer buffer +------------------------------ + + The 'Buf' and 'BufSize' fields of the request structure +provide the transfer buffer for each operation. This buffer must +be set by the client (to increase performance by avoiding copying +data). + + On reads, the client specifies the amount and where to place +the retrieved data; on writes, it specifies the amount and source +of the data segment that is to be sent. Although this scheme +increases complexity, it has proven very fast and powerful. For +instance, when the size of a document is known in advance, a +buffer for all the data can be allocated at once, eliminating the +need for multiple memory reallocations. Even more, if the size is +known and the data transfer is taking the form of multiple small +chunks of data, the client only needs to update 'Buf' and +BufSize' to point to the next byte in its large preallocated +reception buffer (by adding the chunk size to 'Buf'). On the +other hand, if the size of the transfer isn't known in advance, +the reception buffer can remain untouched until the connection +closes, but the client must then accomplish the usual buffer +copying and reallocation. + + The I/O engine also lets the client specify a full length +transfer buffer when sending data. It doesn't matter (from the +client's point of view) if the data fits in a single packet or +not, it's the I/O engine's job to divide it into smaller chunks +if needed and to perform the operation accordingly. + + +------------------------------------------ +Handling multiple simultaneous connections +------------------------------------------ + + The previous sections describe the internal work for a single +connection, the I/O engine handles several of them in parallel. +This is the normal downloading behavior of a web page. Normally, +after retrieving the main document (HTML code), several +references to other files (typically images) and sometimes even +to other sites (mostly advertising today) are found inside the +page. In order to parse and complete the page rendering, those +other documents must be fetched and displayed, so it is not +uncommon to have multiple downloading connections (every one +requiring the whole fetching process) happening at the same time. + + Even though socket activity can reach a hectic pace, the +browser never blocks. Note also that the I/O engine is the one +that directs the execution flow of the program by triggering a +call-back chain whenever a file descriptor operation succeeds or +fails. + + A key point for this multiple call-back chained I/O engine is +that every single function in the chain must be guaranteed to +return quickly. Otherwise, the whole system blocks until it +returns. + + +----------- +Conclusions +----------- + + Dillo is currently in very stable beta state. It already shows +impressive performance, and its interactive ``feel'' is much +better than that of other web browsers. + + The modular structure of Dillo, and its reliance on GTK1 allow +it to be very small. Not every feature of HTML-4.01 has been +implemented yet, but no significant problems are foreseen in +doing this. + + The fact that Dillo's central I/O engine is written using +advanced features of POSIX and TCP/IP networking makes its +performance possible, but on the other hand this also means that +only a fraction of the interested hackers are able to work on it. + + A simple code base is critical when trying to attract hackers +to work on a project like this one. Using the GTK+ framework +helped both in creating the graphical user interface and in +handling the concurrency inside the browser. By having threads +communicate through pipes the need for explicit synchronization +is almost completely eliminated, and with it most of the +complexity of concurrent programming disappears. + + A clean, strictly applied layering approach based on clear +abstractions is vital in each programming project. A good, +supportive framework is of much help here. + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/Images.txt Sun Oct 07 00:36:34 2007 +0200 @@ -0,0 +1,114 @@ + February 2001, --Jcid + + ------ + IMAGES + ------ + +* When a image tag is found within a HTML page, Html_tag_open_img +handles it by: + + - Parsing & getting attribute values. + - Creating a new image structure (DilloImage) and its + associated widget (DwImage). + i.e. If 'Image' is the var for the structure, then + 'Image->dw' is the widget. + - Requesting the image to be feeded by the cache. + - Sending some info to the browser interface. + +* The cache can either request the image data from the net, or +feed it directly from the dicache (decompressed image cache). + +* Both processes are somewhat different because the first one +requires to decode the image data into RGB format, and the second +one has the whole data already decoded. + +* Regardless of the RGB-data feeding method, the decoded data is +passed to the widget (DwImage) and drawn by GdkRGB in a streamed +way. + Note that INDEXED images are also decoded into RGB format. + + +--------------------- +Fetching from the net +--------------------- + +* a_Cache_open_url initiates the resource request, and when +finally the answer arrives, the HTTP header is examined for MIME +type and either the GIF or PNG or JPEG decoder is set to handle +the incoming data stream. + Decoding functions: a_Gif_image, a_Jpeg_image and a_Png_image. + +* The decoding function calls the following dicache methods as +the data is processed (listed in order): + + a_Dicache_set_parms + a_Dicache_set_cmap (only for indexed-GIF images) + a_Dicache_write + a_Dicache_close + +* The dicache methods call the necessary functions to connect +with the widget code. This is done by calling image.c functions: + + a_Image_set_parms + a_Image_set_cmap + a_Image_write + a_Image_close + +* The functions in image.c make the required a_Dw_image_... +calls. + + +------------------------- +Fetching from the dicache +------------------------- + +* a_Cache_open_url tests the cache for the image, and directly +enqueues a cache client for it, without asking the network for +the data. When the client queue is processed (a bit later), the +decoder is selected based on the cache entry Type. + +* When the decoder is called, it tests the dicache for the image; +if the image is found, then it sets a_Dicache_callback as the +handling function and gets out of the way (no image decoding is +needed). + +* Later on, the DwImage buffer is set to reference the +dicache-entry's buffer and the rest of the functions calls is +driven by a_Dicache_callback. + + +----------- +Misc. notes +----------- + +* Repeated images generate new cache clients, but only one of +them (the first) is handled with a_Dicache_* functions, the rest +is done with a_Dicache_callback.. + +* The cache-client callback is set when the Content-type of the +image is got. It can be: a_Png_image, a_Gif_image or a_Jpeg_image +Those are called 'decoders' because their main function is to +translate the original data into RGB format. + +* Later on, the decoder can substitute itself, if it finds the +image has been already decoded, with a_Dicache_callback function. +This avoids decoding it twice. + +* The dicache-entry and the Image structure hold bit arrays that +represent which rows had been decoded. + +* The image processing can be found in the following sources: + + - image.[ch] + - dicache.[ch] + - gif.[ch], png.[ch], jpeg.[ch] + - dw_image.[ch] + +* Bear in mind that there are three data structures for image +code: + + - DilloImage (image.h) + - DwImage (dw_image.h) + - DICacheEntry (dicache.h) + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/Imgbuf.txt Sun Oct 07 00:36:34 2007 +0200 @@ -0,0 +1,177 @@ +Aug 2004, S.Geerken@ping.de + +============= +Image Buffers +============= + +General +======= + +Image buffers depend on the platform (see DwRender.txt), but have a +general, platform independant interface, which is described in this +section. The next section describes the Gdk version of Imgbuf. + +The structure ImgBuf will become part of the image processing, between +image data decoding and the widget DwImage. Its purposes are + + 1. storing the image data, + 2. handling scaled versions of this buffer, and + 3. drawing. + +The latter must be done independently from the window. + +Storing Image Data +------------------ +Imgbuf supports five image types, which are listed in the table +below. The representation defines, how the colors are stored within +the data, which is passed to a_Imgbuf_copy_row(). + + | bytes per | + type | pixel | representation + ---------------+-----------+------------------------- + RGB | 3 | red, green, blue + RGBA | 4 | red, green, blue, alpha + gray | 1 | gray value + indexed | 1 | index to colormap + indexed alpha | 1 | index to colormap + +The last two types need a colormap, which is set by +a_Imgbuf_set_cmap(), which must be called before +a_Imgbuf_copy_row(). This function expects the colors as 32 bit +unsigned integers, which have the format 0xrrbbgg (for indexed +images), or 0xaarrggbb (for indexed alpha), respectively. + +Scaling +------- +The buffer with the original size, which was created by +a_Imgbuf_new(), is called root buffer. Imgbuf provides the ability to +scale buffers. Generally, both root buffers, as well as scaled +buffers, may be shared, memory management is done by reference +counters. + +Via a_Imgbuf_get_scaled_buf(), you can retrieve a scaled buffer. The +way, how this function works in detail, is described in the code, but +generally, something like this works always, in an efficient way: + + old_buf = cur_buf; + cur_buf = a_Imgbuf_get_scaled_buf(old_buf, with, height); + a_Imgbuf_unref (old_buf); + +Old_buf may both be a root buffer, or a scaled buffer. + +(As an exception, there should always be a reference on the root +buffer, since scaled buffers cannot exist without the root buffer, but +on the other side, do not hold references on it. So, if in the example +above, old_buf would be a root buffer, and there would, at the +beginning, only be one reference on it, new_buf would also be +destroyed, along with old_buf. Therefore, an external reference must +be added to the root buffer, which is in dillo done within the dicache +module.) + +The root buffer keeps a list of all children, and all operations +operating on the image data (a_Imgbuf_copy_row() and +a_Imgbuf_set_cmap()) are delegated to the scaled buffers, when +processed, and inherited, when a new scaled buffer is created. This +means, that they must only be performed for the root buffer. + +Drawing +------- +There are two situations, when drawing is necessary: + + 1. To react on expose events, the function a_Imgbuf_draw() can be + used. Notice that the exact signature of this function is + platform dependant. + + 2. When a row has been copied, it has to be drawn. To determine the + area, which has to be drawn, the function + a_Imgbuf_get_row_area() should be used. In dillo, the dicache + module will first call a_Img_copy_row(), and then call + a_Dw_image_draw_row() for the images connected to this image + buffer. a_Dw_image_draw_row() will then call + p_Dw_widget_queue_draw(), with an area determined by + a_Imgbuf_get_row_area(). + + +The Gdk Implementation +====================== + +The Gdk implementation is used by the Gtk+ platform. [... todo] + + +Global Scalers +============== + +In some cases, there is a context, where images have to be scaled +often, by a relatively constant factor. For example, the preview +window (GtkDwPreview) draws images via the Imgbuf draw functions, but +uses scaled buffers. Scaling such a buffer each time it is needed, +causes huge performance losses. On the other hand, if the preview +window would keep these scaled buffers (e.g. by lazy mapping of the +original buffer to the scaled buffer), the scaled buffers get never +freed, since the view is not told about, when the original buffer is +not needed anymore. (n.b., that currently, the scaled buffers are +destroyed, when the original buffer is destroyed, but this may change, +and even this would leave "zombies" in this mapping structure, where +the values refer to dead pointers). + +It is sufficient, that references on the scaled buffers are referred +somehow, so that they do not get destroyed between different +usages. The caller (in this case the preview) simply requests a scaled +buffer, but the Imgbuf returns this from the list of already scaled +buffers. + +These references are hold by special structures, which are called +"scalers". There are two types of scalers, local scalers, which are +bound to image buffers, and global scalers, which refer to multiple +scalers. + +What happens in different situations: + + - The caller (e.g. the preview) requests a scaled buffer. For this, + it uses a special method, which also passes the global image + scaler, which was created before (for the preview, there is a 1-1 + association). The Imgbuf uses this global image scaler, to + identify the caller, and keeps a list of them. If this global + scaler is not yet in the list, it is added, and a local scaler is + created. + + + + - + +There are three images in the page, i1a, i1b, and i2. I1a and i1b +refer to the same image recource, represented by the root image buffer +iba, which original size is 200 x 200. I1a is displayed in original +size, while i1b is displayed at 100 x 100. I2 refers to an other +recource, ibb, which has the size 300 x 300. I2 is shown in original +size. + + + :DwRenderLayout ------------------- :DwPage ----------. + / \ | + ,----' `----. ,------ i1a:DwImage --+ + / \ | | + view1:GtkDwViewport view2:GtkDwPreview | ,---- i1b:DwImage --| + | | | | + ,------------------------------' | | ,-- i2: DwImage --' + | | | | + | ,-------------------------------------' | | + | | ,--------------------------------' | + | | | ,----' + | | | | + | V | V + | iba:Imgbuf | ibb:Imgbuf -- 30x30 + | | | V | ^ + | | +- 100x100 ,- 20x20 ,- 10x10 | | + | | | | ^ | ^ | | + | | `----------+----|---' | `--. ,--' + | | ,--------------' | | | + | | | ,------------------' | | + | | | | | | + | lca:ImgbufLSc lcb:ImgbufLSc + | (factor 1/10) (factor 1/10) + | \ / + | `-----------. ,-------------------' + | \ / + `------------------> scl:ImgbufGSc + (factor 1/10)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/Makefile.am Sun Oct 07 00:36:34 2007 +0200 @@ -0,0 +1,19 @@ +EXTRA_DIST = \ + Cache.txt \ + Cookies.txt \ + Dillo.txt \ + Dw.txt \ + DwImage.txt \ + DwPage.txt \ + DwRender.txt \ + DwStyle.txt \ + DwTable.txt \ + DwWidget.txt \ + HtmlParser.txt \ + IO.txt \ + Images.txt \ + Imgbuf.txt \ + NC_design.txt \ + Selection.txt \ + Dpid.txt \ + README
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/NC_design.txt Sun Oct 07 00:36:34 2007 +0200 @@ -0,0 +1,80 @@ + + _________________________________________________________________ + + Naming&Coding design + _________________________________________________________________ + + Dillo's code is divided into modules. For instance: bookmark, cache, + dicache, gif. + + Lets think of a module named "menu", then: + * Every internal routine of the module, should start with "Menu_" + prefix. + * "Menu_" prefixed functions are not meant to be called from outside + the module. + * If the function is to be exported to other modules (i.e. it will + be called from the outside), it should be wrapped with an "a_" + prefix. + + For instance: if the function name is "Menu_create", then it's an + internal function, but if we need to call it from the outside, then it + should be renamed to "a_Menu_create". + + Why the "a_" prefix? + Because of historical reasons. + And it reads better "a_Menu_create" than "d_Menu_create" cause the + first one suggests "a Menu create" function! + + Another way of understanding this is thinking of "a_" prefixed + functions as Dillo's internal library, and the rest ("Menu_" prefixed + in our example) as a private module-library. + + Indentation: Source code must be indented with 3 blank spaces, no Tabs. + Why? + Because different editors expand or treat tabs in several ways; 8 + spaces being the most common, but that makes code really wide and + we'll try to keep it within the 80 columns bounds (printer friendly). + + Function commenting: + + Every single function of the module should start with a short comment + that explains it's purpose; three lines must be enough, but if you + think it requires more, enlarge it. + +/* + * Try finding the url in the cache. If it hits, send the contents + * to the caller. If it misses, set up a new connection. + */ +int a_Cache_open_url(const char *url, void *Data) +{ + ... + ... + ... +} + + We also have the BUG: and todo: tags. + Use them within source code comments to spot hidden issues. For + instance: + +/* BUG: this counter is not accurate */ +++i; + +/* todo: get color from the right place */ +a = color; + _________________________________________________________________ + + What do we get with this? + + * A clear module API for Dillo; every function prefixed "a_" is to + be used outside the module. + * A way for identifying where the function came from (the + capitalized word is the module name). + * An inner ADT (Abstract data type) for the module. That can be + isolated, tested and replaced independently. + * A two stage instance for bug-fixing. You can change the exported + function algorithms while someone else fixes the internal + module-ADT! + * A coding standard ;) + _________________________________________________________________ + + Naming&Coding design by Jorge Arellano Cid
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/README Sun Oct 07 00:36:34 2007 +0200 @@ -0,0 +1,53 @@ +README: Last update Oct 2007 --jcid + + This documents need a review. They were current with dillo1 and +now, with dillo2, most of them are obsolete, specially Dw*txt, but +Dw2 is fully documented in html using doxygen. + + The other documents will be reviewed when I have some time. They +will give you an overview of what's going on but take them with a +pinch of salt. + + Of course I'd like to have these as doxygen files too! +If somebody wants to make this convertion, please let me know +to assign higher priority to updating these docs. + +-- +Jorge.- + + -------------------------------------------------------------------------- + FILE DESCRIPTION STATE + -------------------------------------------------------------------------- + NC_design.txt Naming&Coding design (Be sure to Current + read it before any other doc) + Dillo.txt General overview of the program Current + IO.txt Extensive introduction Current + Cache.txt Informative description Current + Images.txt Image handling and processing Current + HtmlParser.txt A versatile parser Current + Dw.txt The New Dillo Widget (Overview) Current + DwRendering.txt Dw Rendering Abstraction Current + DwWidget.txt The base object of Dw Current + DwImage.txt Dillo Widget image handling Incomplete + DwPage.txt Dillo Widget page (shortly) Incomplete + DwStyle.txt Styles of Dillo Widgets Pending + DwTable.txt Tables in dillo Current + Imgbuf.txt Image buffers Pending + Selection.txt Selections, and link activation Current (?) + Cookies.txt Explains how to enable cookies Current + Dpid.txt Dillo plugin daemon Current + -------------------------------------------------------------------------- + [This documents cover dillo's internal working. They're NOT a user manual] + -------------------------------------------------------------------------- + + + * Ah!, there's a small program (srch) within the src/ dir. It searches + tokens within the whole code (*.[ch]). It has proven very useful. + Ex: ./srch a_Image_write + ./srch todo: + + * Please submit your patches with 'diff -pru'. + + + Happy coding! + --Jcid
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/Selection.txt Sun Oct 07 00:36:34 2007 +0200 @@ -0,0 +1,149 @@ +Apr 2003, S.Geerken@ping.de +Last update: Dec 2004 + +========= +Selection +========= + +The selection module (selection.[ch]) handles selections, as well as +activation of links, which is closely related. + + +General Overview +================ + +The selection module defines a structure "Selection", which is +associated to GtkDwViewport, and so to a widget tree. The selection +state is controlled by "abstract events", which are sent by single +widgets by calling one of the following functions: + + a_Selection_button_press for button press events, + a_Selection_button_release for button release events, and + a_Selection_button_motion for motion events (with pressed mouse + button). + +The widget must construct simple iterators (DwIterator), which will be +transferred to extended iterators (DwExtIterator), see below for more +details. All event handling functions have the same signature, the +arguments in detail are: + + - DwIterator *it the iterator pointing on the item under + the mouse pointer, + - gint char_pos the exact (character) position within + the iterator, + - gint link if this item is associated with a link, + its number (see DwImage, section + "signals" for the meaning), otherwise + -1, + - GdkEventButton *event the event itself; only the button is + used, + - gboolean within_content TRUE, if there is some selectable + content unter the mouse cursor; if set + to FALSE, the "full screen" feature is + used on double click. + +In some cases, char_pos would be difficult to determine. E.g., when +the DwPage widget decides that the user is pointing on a position +_at_the_end_ of an image (DwImage), it constructs a simple iterator +pointing on this image widget. In a simple iterator, that fact that +the pointer is at the end, would be represented by char_pos == 1. But +when transferring this simple iterator into an extended iterator, this +simple iterator is discarded and instead the stack has an iterator +pointing to text at the top. As a result, only the first letter of the +ALT text would be copied. + +To avoid this problem, widgets should in this case pass SELECTION_EOW +(end of word) as char_pos, which is then automatically reduced to the +actual length of the extended(!) iterator. + +The return value is the same as in DwWidget event handling methods. +I.e., in most cases, they should simply return it. The events +"link_pressed", "link_released" and "link_clicked" (but not +"link_entered") are emitted by these functions, so that widgets which +let the selection module handle links, should only emit "link_entered" +for themselves. (See DwImage.txt for a description of this.) + + +Selection State +=============== + +Selection interferes with handling the activation of links, so the +latter is also handled by the selection module. Details are based on +following guidelines: + + 1. It should be simple to select links and to start selection in + links. The rule to distinguish between link activation and + selection is that the selection starts as soon as the user leaves + the link. (This is, IMO, a useful feature. Even after drag and + drop has been implemented in dillo, this should be somehow + preserved.) + + 2. The selection should stay as long as possible, i.e., the old + selection is only cleared when a new selection is started. + +The latter leads to a model with two states: the selection state and +the link handling state. + +The general selection works, for events not pointing on links, like +this (numbers in parantheses after the event denote the button, "n" +means arbitrary button): + + motion(1) + ,-----. + | | + press(1) on non-link V | + NONE -----------------------> SELECTING <----------------. + ^ | | + | | release(1) | + | | | press(1) + | no V yes | + `----------------------- Anything selected? --------> SELECTED + +The selected region is represented by two DwExtIterators. + +Links are handled by a different state machine: + + ,-----------------------------. + | | + | Switch to selection + | (SELECTING) for n == 1. + | ^ + | | no + | | yes + | Still the same link? --. + | ^ | + | | | + | | motion(n) | + V press(n) on links | | + NONE ---------------------> PRESSED(n) <-----' + ^ | + | | release(n) + | | + | V yes + | Still the same link? -----------------. + | | | + | | no V + | V Send "clicked" signal. + | Switch to selection | + | (SELECTED) for n == 1. | + | | | + |`----------------------------' | + | | + `----------------------------------------------------------' + +Switching to selection simply means that the selection state will +eventually be SELECTED/SELECTING, with the original and the actual +position making up the selection region. This happens for button 1, +events with buttons other than 1 do not affect selection at all. + + +TODO +==== + +* a_Selection_button_motion currently always assumes that button 1 has + been pressed (since otherwise it would not do anything). This should + be made a bit cleaner. + +* The selection should be cleared, when the user selects something + somewhere else (perhaps switched into "non-active" mode, as some + Gtk+ widgets do).
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dpi/Makefile.am Sun Oct 07 00:36:34 2007 +0200 @@ -0,0 +1,37 @@ +bookmarksdir = $(libdir)/dillo/dpi/bookmarks +downloadsdir = $(libdir)/dillo/dpi/downloads +ftpdir = $(libdir)/dillo/dpi/ftp +httpsdir = $(libdir)/dillo/dpi/https +hellodir = $(libdir)/dillo/dpi/hello +filedir = $(libdir)/dillo/dpi/file +cookiesdir = $(libdir)/dillo/dpi/cookies +datauridir = $(libdir)/dillo/dpi/datauri +bookmarks_PROGRAMS = bookmarks.dpi +downloads_PROGRAMS = downloads.dpi +ftp_PROGRAMS = ftp.filter.dpi +https_PROGRAMS = https.filter.dpi +hello_PROGRAMS = hello.filter.dpi +file_PROGRAMS = file.dpi +cookies_PROGRAMS = cookies.dpi +datauri_PROGRAMS = datauri.filter.dpi + +bookmarks_dpi_LDADD = ../dpip/libDpip.a ../dlib/libDlib.a +downloads_dpi_LDADD = @LIBFLTK_LIBS@ ../dpip/libDpip.a ../dlib/libDlib.a +ftp_filter_dpi_LDADD = ../dpip/libDpip.a ../dlib/libDlib.a +https_filter_dpi_LDADD = @LIBSSL_LIBS@ ../dpip/libDpip.a ../dlib/libDlib.a +hello_filter_dpi_LDADD = ../dpip/libDpip.a ../dlib/libDlib.a +file_dpi_LDADD = @LIBPTHREAD_LIBS@ ../dpip/libDpip.a ../dlib/libDlib.a +cookies_dpi_LDADD = ../dpip/libDpip.a ../dlib/libDlib.a +datauri_filter_dpi_LDADD = ../dpip/libDpip.a ../dlib/libDlib.a + +file_dpi_LDFLAGS = @LIBPTHREAD_LDFLAGS@ + +bookmarks_dpi_SOURCES = bookmarks.c dpiutil.c dpiutil.h +downloads_dpi_SOURCES = downloads.cc dpiutil.c dpiutil.h +ftp_filter_dpi_SOURCES = ftp.c dpiutil.c dpiutil.h +https_filter_dpi_SOURCES = https.c dpiutil.c dpiutil.h +hello_filter_dpi_SOURCES = hello.c dpiutil.c dpiutil.h +file_dpi_SOURCES = file.c dpiutil.c dpiutil.h +cookies_dpi_SOURCES = cookies.c dpiutil.c dpiutil.h +datauri_filter_dpi_SOURCES = datauri.c dpiutil.c dpiutil.h +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dpi/bookmarks.c Sun Oct 07 00:36:34 2007 +0200 @@ -0,0 +1,1716 @@ +/* + * Bookmarks server (chat version). + * + * NOTE: this code illustrates how to make a dpi-program. + * + * Copyright 2002-2006 Jorge Arellano Cid <jcid@dillo.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + */ + +/* Todo: this server is not assembling the received packets. + * This means it currently expects dillo to send full dpi tags + * within the socket; if that fails, everything stops. + * This is not hard to fix, mainly is a matter of expecting the + * final '>' of a tag. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <stddef.h> +#include <string.h> +#include <unistd.h> +#include <errno.h> +#include <ctype.h> +#include <sys/socket.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/un.h> +#include <time.h> +#include <netdb.h> +#include <fcntl.h> +#include <signal.h> +#include "../dpip/dpip.h" +#include "dpiutil.h" + + +/* + * Debugging macros + */ +#define _MSG(...) +#define MSG(...) printf("[bookmarks dpi]: " __VA_ARGS__) + +/* This one is tricky, some sources state it should include the byte + * for the terminating NULL, and others say it shouldn't. */ +# define D_SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *) 0)->sun_path) \ + + strlen ((ptr)->sun_path)) + +#define DOCTYPE \ + "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'>\n" + +/* + * Notes on character escaping: + * - Basically things are saved unescaped and escaped when in memory. + * - &<>"' are escaped in titles and sections and saved unescaped. + * - ' is escaped as %27 in URLs and saved escaped. + */ +typedef struct { + int key; + int section; + char *url; + char *title; +} BmRec; + +typedef struct { + int section; + char *title; + + int o_sec; /* private, for normalization */ +} BmSec; + + +/* + * Local data + */ +static char *Header = "Content-type: text/html\n\n"; +static char *BmFile = NULL; +static time_t BmFileTimeStamp = 0; +static Dlist *B_bms = NULL; +static int bm_key = 0; + +static Dlist *B_secs = NULL; +static int sec_key = 0; + +static int MODIFY_PAGE_NUM = 1; + + +/* + * Forward declarations + */ + + +/* -- HTML templates ------------------------------------------------------- */ + +char *mainpage_header = +DOCTYPE +"<html>\n" +"<head>\n" +"<title>Bookmarks</title>\n" +"</head>\n" +"<body bgcolor='#778899' link='black' vlink='brown'>\n" +"<table border='1' cellpadding='0' width='100%'>\n" +" <tr><td>\n" +" <table width='100%' bgcolor='#b4b4b4'>\n" +" <tr>\n" +" <td> Bookmarks::</td>\n" +" <td width='100%' align='right'>\n" +" [<a href='dpi:/bm/modify'>modify</a>]\n" +" </td></tr>\n" +" </table></td></tr>\n" +"</table>\n" +"<br>\n"; + +char *modifypage_header = +DOCTYPE +"<html>\n" +"<head>\n" +"<title>Bookmarks</title>\n" +"</head>\n" +"<body bgcolor='#778899' link='black' vlink='brown'>\n" +"<table border='1' cellpadding='0' width='100%'>\n" +" <tr><td>\n" +" <table width='100%' bgcolor='#b4b4b4'>\n" +" <tr>\n" +" <td> Bookmarks :: modify</td></tr>\n" +" </table></td></tr> \n" +"</table> \n" +"\n" +"<form>\n" +"<table width='100%' border='1' cellpadding='0'>\n" +" <tr><td>\n" +" <table width='100%' bgcolor='teal'>\n" +" <tr>\n" +" <td><b>Select an operation </b></td>\n" +" <td><select name='operation'>\n" +" <option value='none' selected>--\n" +" <option value='delete'>Delete\n" +" <option value='move'>Move\n" +" <option value='modify'>Modify\n" +" <option value='add_sec'>Add Section\n" +" <option value='add_url'>Add URL\n" +" </select></td>\n" +" <td><b>, mark its operands, and </b></td>\n" +" <td><input type='submit' name='submit' value='submit.'></td>\n" +" <td width='100%'></td>\n" +" </tr>\n" +" </table></td></tr>\n" +"</table>\n"; + +char *mainpage_sections_header = +"<table border='1' cellpadding='0' cellspacing='20' width='100%'>\n" +" <tr valign='top'>\n" +" <td>\n" +" <table bgcolor='#b4b4b4' border='2' cellpadding='4' cellspacing='1'>\n" +" <tr><td>\n" +" <table width='100%' bgcolor='#b4b4b4'>\n" +" <tr><td><small>Sections:</small></td></tr></table></td></tr>\n"; + +char *modifypage_sections_header = +"<table border='1' cellpadding='0' cellspacing='20' width='100%'>\n" +" <tr valign='top'>\n" +" <td>\n" +" <table bgcolor='#b4b4b4' border='1'>\n" +" <tr><td>\n" +" <table width='100%' bgcolor='#b4b4b4'>\n" +" <tr><td><small>Sections:</small></td></tr></table></td></tr>\n"; + +char *mainpage_sections_item = +" <tr><td align='center'>\n" +" <a href='#s%d'>%s</a></td></tr>\n"; + +char *modifypage_sections_item = +" <tr><td>\n" +" <table width='100%%' bgcolor='#b4b4b4'cellspacing='0' cellpadding='0'>\n" +" <tr align='center'>" +" <td width='1%%'><input type='checkbox' name='s%d'></td>\n" +" <td><a href='#s%d'>%s</a></td></tr></table></td></tr>\n"; + +char *mainpage_sections_footer = +" </table>\n"; + +char *modifypage_sections_footer = +" </table>\n"; + +char *mainpage_middle1 = +" </td>\n" +" <td width='100%'>\n"; + +char *modifypage_middle1 = +" </td>\n" +" <td width='100%'>\n"; + +char *mainpage_section_card_header = +" <a name='s%d'></a>\n" +" <table bgcolor='#bfbfbf' width='100%%' cellspacing='2'>\n" +" <tr>\n" +" <td bgcolor='#bf0c0c'><font color='white'><b>\n" +" %s </b></font></td>\n" +" <td bgcolor='white' width='100%%'> </td></tr>\n"; + +char *modifypage_section_card_header = +" <a name='s%d'></a>\n" +" <table bgcolor='#bfbfbf' width='100%%' cellspacing='2'>\n" +" <tr>\n" +" <td bgcolor='#bf0c0c'><font color='white'><b>\n" +" %s </b></font></td>\n" +" <td bgcolor='white' width='100%%'> </td></tr>\n"; + +char *mainpage_section_card_item = +" <tr><td colspan='2'>\n" +" <a href='%s'>%s</a> </td></tr>\n"; + +char *modifypage_section_card_item = +" <tr>\n" +" <td colspan='2'><input type='checkbox' name='url%d'>\n" +" <a href='%s'>%s</a></td></tr>\n"; + +char *mainpage_section_card_footer = +" </table>\n" +" <hr>\n"; + +char *modifypage_section_card_footer = +" </table>\n" +" <hr>\n"; + +char *mainpage_footer = +" </td>\n" +" </tr>\n" +"</table>\n" +"</body>\n" +"</html>\n"; + +char *modifypage_footer = +" </td>\n" +" </tr>\n" +"</table>\n" +"</form>\n" +"</body>\n" +"</html>\n"; + +/* ------------------------------------------------------------------------- */ +char *modifypage_add_section_page = +DOCTYPE +"<html>\n" +"<head>\n" +"<title>Bookmarks</title>\n" +"</head>\n" +"<body bgcolor='#778899' link='black' vlink='brown'>\n" +"<table border='1' cellpadding='0' width='100%'>\n" +" <tr><td colspan='2'>\n" +" <table bgcolor='#b4b4b4' width='100%'>\n" +" <tr><td bgcolor='#b4b4b4'> Modify bookmarks:: add section\n" +" </td></tr></table></td></tr>\n" +"</table>\n" +"<br>\n" +"<form>\n" +" <input type='hidden' name='operation' value='add_section'>\n" +"<table border='1' width='100%'>\n" +" <tr>\n" +" <td bgcolor='olive'><b>New section:</b></td>\n" +" <td bgcolor='white' width='100%'></td></tr>\n" +"</table>\n" +"<table width='100%' cellpadding='10'>\n" +"<tr><td>\n" +" <table width='100%' bgcolor='teal'>\n" +" <tr>\n" +" <td>Title:</td>\n" +" <td><input type='text' name='title' size='64'></td></tr>\n" +" </table>\n" +" </td></tr>\n" +"</table>\n" +"<table width='100%' cellpadding='4' border='0'>\n" +"<tr><td bgcolor='#a0a0a0'>\n" +" <input type='submit' name='submit' value='submit.'></td></tr>\n" +"</table>\n" +"</form>\n" +"</body>\n" +"</html>\n" +"\n"; + +/* ------------------------------------------------------------------------- */ +char *modifypage_update_header = +DOCTYPE +"<html>\n" +"<head>\n" +"<title>Bookmarks</title>\n" +"</head>\n" +"<body bgcolor='#778899' link='black' vlink='brown'>\n" +"<table border='1' cellpadding='0' width='100%'>\n" +" <tr><td colspan='2'>\n" +" <table bgcolor='#b4b4b4' width='100%'>\n" +" <tr><td bgcolor='#b4b4b4'> Modify bookmarks:: update\n" +" </td></tr></table></td></tr>\n" +"</table>\n" +"<br>\n" +"<form>\n" +"<input type='hidden' name='operation' value='modify2'>\n"; + +char *modifypage_update_title = +"<table border='1' width='100%%'>\n" +" <tr>\n" +" <td bgcolor='olive'><b>%s</b></td>\n" +" <td bgcolor='white' width='100%%'></td></tr>\n" +"</table>\n"; + +char *modifypage_update_item_header = +"<table width='100%' cellpadding='10'>\n"; + +char *modifypage_update_item = +"<tr><td>\n" +" <table width='100%%' bgcolor='teal'>\n" +" <tr>\n" +" <td>Title:</td>\n" +" <td><input type='text' name='title%d' size='64'\n" +" value='%s'></td></tr>\n" +" <tr>\n" +" <td>URL:</td>\n" +" <td>%s</td></tr>\n" +" </table>\n" +" </td></tr>\n"; + +char *modifypage_update_item2 = +"<tr><td>\n" +" <table width='100%%' bgcolor='teal'>\n" +" <tr>\n" +" <td>Title:</td>\n" +" <td><input type='text' name='s%d' size='64'\n" +" value='%s'></td></tr>\n" +" </table>\n" +" </td></tr>\n"; + +char *modifypage_update_item_footer = +"</table>\n"; + +char *modifypage_update_footer = +"<table width='100%' cellpadding='4' border='0'>\n" +"<tr><td bgcolor='#a0a0a0'>\n" +" <input type='submit' name='submit' value='submit.'></td></tr>\n" +"</table>\n" +"</form>\n" +"</body>\n" +"</html>\n"; + +/* ------------------------------------------------------------------------- */ +char *modifypage_add_url = +DOCTYPE +"<html>\n" +"<head>\n" +"<title>Bookmarks</title>\n" +"</head>\n" +"<body bgcolor='#778899' link='black' vlink='brown'>\n" +"<table border='1' cellpadding='0' width='100%'>\n" +" <tr><td colspan='2'>\n" +" <table bgcolor='#b4b4b4' width='100%'>\n" +" <tr><td bgcolor='#b4b4b4'> Modify bookmarks:: add url\n" +" </td></tr></table></td></tr>\n" +"</table>\n" +"<br>\n" +"<form>\n" +"<input type='hidden' name='operation' value='add_url2'>\n" +"<table border='1' width='100%'>\n" +" <tr>\n" +" <td bgcolor='olive'><b>Add url:</b></td>\n" +" <td bgcolor='white' width='100%'></td></tr>\n" +"</table>\n" +"<table width='100%' cellpadding='10'>\n" +"<tr><td>\n" +" <table width='100%' bgcolor='teal'>\n" +" <tr>\n" +" <td>Title:</td>\n" +" <td><input type='text' name='title' size='64'></td></tr>\n" +" <tr>\n" +" <td>URL:</td>\n" +" <td><input type='text' name='url' size='64'></td></tr>\n" +" </table>\n" +" </td></tr>\n" +"</table>\n" +"<table width='100%' cellpadding='4' border='0'>\n" +"<tr><td bgcolor='#a0a0a0'>\n" +" <input type='submit' name='submit' value='submit.'></td></tr>\n" +"</table>\n" +"</form>\n" +"</body>\n" +"</html>\n"; + + +/* ------------------------------------------------------------------------- */ + +/* + * Return a new string with spaces changed with + */ +static char *make_one_line_str(char *str) +{ + char *new_str; + int i, j, n; + + for (i = 0, n = 0; str[i]; ++i) + if (str[i] == ' ') + ++n; + + new_str = dNew(char, strlen(str) + 6*n + 1); + new_str[0] = 0; + + for (i = 0, j = 0; str[i]; ++i) { + if (str[i] == ' ') { + strcpy(new_str + j, " "); + j += 6; + } else { + new_str[j] = str[i]; + new_str[++j] = 0; + } + } + + return new_str; +} + +/* + * Given an urlencoded string, return it to the original version. + */ +static void Unencode_str(char *e_str) +{ + char *p, *e; + + for (p = e = e_str; *e; e++, p++) { + if (*e == '+') { + *p = ' '; + } else if (*e == '%') { + if (dStrncasecmp(e, "%0D%0A", 6) == 0) { + *p = '\n'; + e += 5; + } else { + *p = (isdigit(e[1]) ? (e[1] - '0') : (e[1] - 'A' + 10)) * 16 + + (isdigit(e[2]) ? (e[2] - '0') : (e[2] - 'A' + 10)); + e += 2; + } + } else { + *p = *e; + } + } + *p = 0; +} + +/* + * Send a short message to dillo's status bar. + */ +static int Bmsrv_dpi_send_status_msg(SockHandler *sh, char *str) +{ + int st; + char *d_cmd; + + d_cmd = a_Dpip_build_cmd("cmd=%s msg=%s", "send_status_message", str); + st = sock_handler_write_str(sh, 1, d_cmd); + dFree(d_cmd); + return st; +} + +/* -- ADT for bookmarks ---------------------------------------------------- */ +/* + * Compare function for searching a bookmark by its key + */ +static int Bms_node_by_key_cmp(const void *node, const void *key) +{ + return ((BmRec *)node)->key - VOIDP2INT(key); +} + +/* + * Compare function for searching a bookmark by section + */ +static int Bms_node_by_section_cmp(const void *node, const void *key) +{ + return ((BmRec *)node)->section - VOIDP2INT(key); +} + +/* + * Compare function for searching a section by its number + */ +static int Bms_sec_by_number_cmp(const void *node, const void *key) +{ + return ((BmSec *)node)->section - VOIDP2INT(key); +} + +/* + * Return the Bm record by key + */ +static BmRec *Bms_get(int key) +{ + return dList_find_custom(B_bms, INT2VOIDP(key), Bms_node_by_key_cmp); +} + +/* + * Return the Section record by key + */ +static BmSec *Bms_get_sec(int key) +{ + return dList_find_custom(B_secs, INT2VOIDP(key), Bms_sec_by_number_cmp); +} + +/* + * Add a bookmark + */ +static void Bms_add(int section, char *url, char *title) +{ + BmRec *bm_node; + + bm_node = dNew(BmRec, 1); + bm_node->key = ++bm_key; + bm_node->section = section; + bm_node->url = Escape_uri_str(url, "'"); + bm_node->title = Escape_html_str(title); + dList_append(B_bms, bm_node); +} + +/* + * Add a section + */ +static void Bms_sec_add(char *title) +{ + BmSec *sec_node; + + sec_node = dNew(BmSec, 1); + sec_node->section = sec_key++; + sec_node->title = Escape_html_str(title); + dList_append(B_secs, sec_node); +} + +/* + * Delete a bookmark by its key + */ +static void Bms_del(int key) +{ + BmRec *bm_node; + + bm_node = dList_find_custom(B_bms, INT2VOIDP(key), Bms_node_by_key_cmp); + if (bm_node) { + dList_remove(B_bms, bm_node); + dFree(bm_node->title); + dFree(bm_node->url); + dFree(bm_node); + } + if (dList_length(B_bms) == 0) + bm_key = 0; +} + +/* + * Delete a section and its bookmarks by section number + */ +static void Bms_sec_del(int section) +{ + BmSec *sec_node; + BmRec *bm_node; + + sec_node = dList_find_custom(B_secs, INT2VOIDP(section), + Bms_sec_by_number_cmp); + if (sec_node) { + dList_remove(B_secs, sec_node); + dFree(sec_node->title); + dFree(sec_node); + + /* iterate B_bms and remove those that match the section */ + while ((bm_node = dList_find_custom(B_bms, INT2VOIDP(section), + Bms_node_by_section_cmp))) { + Bms_del(bm_node->key); + } + } + if (dList_length(B_secs) == 0) + sec_key = 0; +} + +/* + * Move a bookmark to another section + */ +static void Bms_move(int key, int target_section) +{ + BmRec *bm_node; + + bm_node = dList_find_custom(B_bms, INT2VOIDP(key), Bms_node_by_key_cmp); + if (bm_node) { + bm_node->section = target_section; + } +} + +/* + * Update a bookmark title by key + */ +static void Bms_update_title(int key, char *n_title) +{ + BmRec *bm_node; + + bm_node = dList_find_custom(B_bms, INT2VOIDP(key), Bms_node_by_key_cmp); + if (bm_node) { + dFree(bm_node->title); + bm_node->title = Escape_html_str(n_title); + } +} + +/* + * Update a section title by key + */ +static void Bms_update_sec_title(int key, char *n_title) +{ + BmSec *sec_node; + + sec_node = dList_find_custom(B_secs, INT2VOIDP(key), Bms_sec_by_number_cmp); + if (sec_node) { + dFree(sec_node->title); + sec_node->title = Escape_html_str(n_title); + } +} + +/* + * Free all the bookmarks data (bookmarks and sections) + */ +static void Bms_free(void) +{ + BmRec *bm_node; + BmSec *sec_node; + + /* free B_bms */ + while ((bm_node = dList_nth_data(B_bms, 0))) { + Bms_del(bm_node->key); + } + /* free B_secs */ + while ((sec_node = dList_nth_data(B_secs, 0))) { + Bms_sec_del(sec_node->section); + } +} + +/* + * Enforce increasing correlative section numbers with no jumps. + */ +static void Bms_normalize(void) +{ + BmRec *bm_node; + BmSec *sec_node; + int i, j; + + /* we need at least one section */ + if (dList_length(B_secs) == 0) + Bms_sec_add("Unclassified"); + + /* make correlative section numbers */ + for (i = 0; (sec_node = dList_nth_data(B_secs, i)); ++i) { + sec_node->o_sec = sec_node->section; + sec_node->section = i; + } + + /* iterate B_secs and make the changes in B_bms */ + for (i = 0; (sec_node = dList_nth_data(B_secs, i)); ++i) { + if (sec_node->section != sec_node->o_sec) { + /* update section numbers */ + for (j = 0; (bm_node = dList_nth_data(B_bms, j)); ++j) { + if (bm_node->section == sec_node->o_sec) + bm_node->section = sec_node->section; + } + } + } +} + +/* -- Load bookmarks file -------------------------------------------------- */ + +/* + * If there's no "bm.txt", create one from "bookmarks.html". + */ +static void Bms_check_import(void) +{ + char *OldBmFile; + char *cmd1 = + "echo \":s0: Unclassified\" > %s"; + char *cmd2 = + "grep -i \"href\" %s | " + "sed -e 's/<li><A HREF=\"/s0 /' -e 's/\">/ /' -e 's/<.*$//' >> %s"; + Dstr *dstr = dStr_new(""); + + + if (access(BmFile, F_OK) != 0) { + OldBmFile = dStrconcat(dGethomedir(), "/.dillo/bookmarks.html", NULL); + if (access(OldBmFile, F_OK) == 0) { + dStr_sprintf(dstr, cmd1, BmFile); + system(dstr->str); + dStr_sprintf(dstr, cmd2, OldBmFile, BmFile); + system(dstr->str); + dStr_free(dstr, TRUE); + dFree(OldBmFile); + } + } +} + +/* + * Load bookmarks data from a file + */ +static int Bms_load(void) +{ + FILE *BmTxt; + char *buf, *p, *url, *title, *u_title; + int section; + struct stat TimeStamp; + + /* clear current bookmarks */ + Bms_free(); + + /* open bm file */ + if (!(BmTxt = fopen(BmFile, "r"))) { + perror("[fopen]"); + return 1; + } + + /* load bm file into memory */ + while ((buf = dGetline(BmTxt)) != NULL) { + if (buf[0] == 's') { + /* get section, url and title */ + section = strtol(buf + 1, NULL, 10); + p = strchr(buf, ' '); *p = 0; + url = ++p; + p = strchr(p, ' '); *p = 0; + title = ++p; + p = strchr(p, '\n'); *p = 0; + u_title = Unescape_html_str(title); + Bms_add(section, url, u_title); + dFree(u_title); + + } else if (buf[0] == ':' && buf[1] == 's') { + /* section = strtol(buf + 2, NULL, 10); */ + p = strchr(buf + 2, ' '); + title = ++p; + p = strchr(p, '\n'); *p = 0; + Bms_sec_add(title); + + } else { + MSG("Syntax error in bookmarks file:\n %s", buf); + } + dFree(buf); + } + fclose(BmTxt); + + /* keep track of the timestamp */ + stat(BmFile, &TimeStamp); + BmFileTimeStamp = TimeStamp.st_mtime; + + return 0; +} + +/* + * Load bookmarks data if: + * - file timestamp is newer than ours or + * - we haven't loaded anything yet :) + */ +static int Bms_cond_load(void) +{ + int st = 0; + struct stat TimeStamp; + + if (stat(BmFile, &TimeStamp) != 0) { + /* try to import... */ + Bms_check_import(); + if (stat(BmFile, &TimeStamp) != 0) + TimeStamp.st_mtime = 0; + } + + if (!BmFileTimeStamp || !dList_length(B_bms) || !dList_length(B_secs) || + BmFileTimeStamp < TimeStamp.st_mtime) { + Bms_load(); + st = 1; + } + return st; +} + +/* -- Save bookmarks file -------------------------------------------------- */ + +/* + * Update the bookmarks file from memory contents + * Return code: { 0:OK, 1:Abort } + */ +static int Bms_save(void) +{ + FILE *BmTxt; + BmRec *bm_node; + BmSec *sec_node; + struct stat BmStat; + char *u_title; + int i, j; + Dstr *dstr = dStr_new(""); + + /* make a safety backup */ + if (stat(BmFile, &BmStat) == 0 && BmStat.st_size > 256) { + char *BmFileBak = dStrconcat(BmFile, ".bak", NULL); + rename(BmFile, BmFileBak); + dFree(BmFileBak); + } + + /* open bm file */ + if (!(BmTxt = fopen(BmFile, "w"))) { + perror("[fopen]"); + return 1; + } + + /* normalize */ + Bms_normalize(); + + /* save sections */ + for (i = 0; (sec_node = dList_nth_data(B_secs, i)); ++i) { + u_title = Unescape_html_str(sec_node->title); + dStr_sprintf(dstr, ":s%d: %s\n", sec_node->section, u_title); + fwrite(dstr->str, (size_t)dstr->len, 1, BmTxt); + dFree(u_title); + } + + /* save bookmarks (section url title) */ + for (i = 0; (sec_node = dList_nth_data(B_secs, i)); ++i) { + for (j = 0; (bm_node = dList_nth_data(B_bms, j)); ++j) { + if (bm_node->section == sec_node->section) { + u_title = Unescape_html_str(bm_node->title); + dStr_sprintf(dstr, "s%d %s %s\n", + bm_node->section, bm_node->url, u_title); + fwrite(dstr->str, (size_t)dstr->len, 1, BmTxt); + dFree(u_title); + } + } + } + + dStr_free(dstr, TRUE); + fclose(BmTxt); + + /* keep track of the timestamp */ + stat(BmFile, &BmStat); + BmFileTimeStamp = BmStat.st_mtime; + + return 0; +} + +/* -- Add bookmark --------------------------------------------------------- */ + +/* + * Add a new bookmark to DB :) + */ +static int Bmsrv_add_bm(SockHandler *sh, char *url, char *title) +{ + char *u_title; + char *msg="Added bookmark!"; + int section = 0; + + /* Add in memory */ + u_title = Unescape_html_str(title); + Bms_add(section, url, u_title); + dFree(u_title); + + /* Write to file */ + Bms_save(); + + if (Bmsrv_dpi_send_status_msg(sh, msg)) + return 1; + + return 0; +} + +/* -- Modify --------------------------------------------------------------- */ + +/* + * Count how many sections and urls were marked in a request + */ +static void Bmsrv_count_urls_and_sections(char *url, int *n_sec, int *n_url) +{ + char *p, *q; + int i; + + /* Check marked urls and sections */ + *n_sec = *n_url = 0; + i