pax_global_header00006660000000000000000000000064130377461640014525gustar00rootroot0000000000000052 comment=822ffa2dd1c493f98fbb00cfc40953b1bc98651c seed-webkit2-4.0.0+20161014+6c77960+dfsg1/000077500000000000000000000000001303774616400166265ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/.clang-format000066400000000000000000000003551303774616400212040ustar00rootroot00000000000000BasedOnStyle: Mozilla IndentWidth: 4 BinPackParameters: false BinPackArguments: true AlignAfterOpenBracket: true PenaltyBreakBeforeFirstCallParameter: 100 PointerAlignment: Left SpaceAfterCStyleCast: true BreakBeforeBinaryOperators: All seed-webkit2-4.0.0+20161014+6c77960+dfsg1/.ycm_extra_conf.py000066400000000000000000000071411303774616400222610ustar00rootroot00000000000000# This is the default copy of the YCM file # To use you, you need a compile_commands.json file with inscructions to build # each file. # # To create that file using autotools please check https://github.com/rizsotto/Bear import os import ycm_core # These are the compilation flags that will be used in case there's no # compilation database set (by default, one is not set). # CHANGE THIS LIST OF FLAGS. YES, THIS IS THE DROID YOU HAVE BEEN LOOKING FOR. flags = [ '-Wall', '-Wextra', '-Werror', ] # Set this to the absolute path to the folder (NOT the file!) containing the # compile_commands.json file to use that instead of 'flags'. See here for # more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html # # You can get CMake to generate this file for you by adding: # set( CMAKE_EXPORT_COMPILE_COMMANDS 1 ) # to your CMakeLists.txt file. # # Most projects will NOT need to set this to anything; you can just change the # 'flags' list of compilation flags. Notice that YCM itself uses that approach. compilation_database_folder = os.path.abspath(os.path.dirname(__file__)) if os.path.exists( compilation_database_folder ): database = ycm_core.CompilationDatabase( compilation_database_folder ) else: database = None SOURCE_EXTENSIONS = [ '.cpp', '.cxx', '.cc', '.c', '.m', '.mm' ] def DirectoryOfThisScript(): return os.path.dirname( os.path.abspath( __file__ ) ) def MakeRelativePathsInFlagsAbsolute( flags, working_directory ): if not working_directory: return list( flags ) new_flags = [] make_next_absolute = False path_flags = [ '-isystem', '-I', '-iquote', '--sysroot=' ] for flag in flags: new_flag = flag if make_next_absolute: make_next_absolute = False if not flag.startswith( '/' ): new_flag = os.path.join( working_directory, flag ) for path_flag in path_flags: if flag == path_flag: make_next_absolute = True break if flag.startswith( path_flag ): path = flag[ len( path_flag ): ] new_flag = path_flag + os.path.join( working_directory, path ) break if new_flag: new_flags.append( new_flag ) return new_flags def IsHeaderFile( filename ): extension = os.path.splitext( filename )[ 1 ] return extension in [ '.h', '.hxx', '.hpp', '.hh' ] def GetCompilationInfoForFile( filename ): # The compilation_commands.json file generated by CMake does not have entries # for header files. So we do our best by asking the db for flags for a # corresponding source file, if any. If one exists, the flags for that file # should be good enough. if IsHeaderFile( filename ): basename = os.path.splitext( filename )[ 0 ] for extension in SOURCE_EXTENSIONS: replacement_file = basename + extension if os.path.exists( replacement_file ): compilation_info = database.GetCompilationInfoForFile( replacement_file ) if compilation_info.compiler_flags_: return compilation_info return None return database.GetCompilationInfoForFile( filename ) def FlagsForFile( filename, **kwargs ): if database: # Bear in mind that compilation_info.compiler_flags_ does NOT return a # python list, but a "list-like" StringVec object compilation_info = GetCompilationInfoForFile( filename ) if not compilation_info: return None final_flags = MakeRelativePathsInFlagsAbsolute( compilation_info.compiler_flags_, compilation_info.compiler_working_dir_ ) else: relative_to = DirectoryOfThisScript() final_flags = MakeRelativePathsInFlagsAbsolute( flags, relative_to ) return { 'flags': final_flags, 'do_cache': True } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/AUTHORS000066400000000000000000000001751303774616400177010ustar00rootroot00000000000000* Robert Carr * Tim Horton * Matt Arsenault seed-webkit2-4.0.0+20161014+6c77960+dfsg1/COPYING000066400000000000000000000613141303774616400176660ustar00rootroot00000000000000 GNU LIBRARY GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the library GPL. It is numbered 2 because it goes with version 2 of the ordinary GPL.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Library General Public License, applies to some specially designated Free Software Foundation software, and to any other libraries whose authors decide to use it. You can use it for your libraries, 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 this service 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 make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library, or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link a program with the library, you must provide complete object files to the recipients so that they can relink them with the library, after making changes to the library and recompiling it. And you must show them these terms so they know their rights. Our method of protecting your rights has two steps: (1) copyright the library, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the library. Also, for each distributor's protection, we want to make certain that everyone understands that there is no warranty for this free library. If the library is modified by someone else and passed on, we want its recipients to know that what they have is not the original version, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that companies distributing free software will individually obtain patent licenses, thus in effect transforming the program into proprietary software. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License, which was designed for utility programs. This license, the GNU Library General Public License, applies to certain designated libraries. This license is quite different from the ordinary one; be sure to read it in full, and don't assume that anything in it is the same as in the ordinary license. The reason we have a separate public license for some libraries is that they blur the distinction we usually make between modifying or adding to a program and simply using it. Linking a program with a library, without changing the library, is in some sense simply using the library, and is analogous to running a utility program or application program. However, in a textual and legal sense, the linked executable is a combined work, a derivative of the original library, and the ordinary General Public License treats it as such. Because of this blurred distinction, using the ordinary General Public License for libraries did not effectively promote software sharing, because most developers did not use the libraries. We concluded that weaker conditions might promote sharing better. However, unrestricted linking of non-free programs would deprive the users of those programs of all benefit from the free status of the libraries themselves. This Library General Public License is intended to permit developers of non-free programs to use free libraries, while preserving your freedom as a user of such programs to change the free libraries that are incorporated in them. (We have not seen how to achieve this as regards changes in header files, but we have achieved it as regards changes in the actual functions of the Library.) The hope is that this will lead to faster development of free libraries. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, while the latter only works together with the library. Note that it is possible for a library to be covered by the ordinary General Public License rather than by this special one. GNU LIBRARY GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Library General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also compile or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. c) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. d) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), 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 distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Library 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 Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "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 LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY 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 LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA. Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! seed-webkit2-4.0.0+20161014+6c77960+dfsg1/ChangeLog000066400000000000000000000002711303774616400204000ustar00rootroot000000000000002009-04-17 Your Name * *: The ChangeLog is auto-generated when releasing. If you are seeing this, use 'git log' for a detailed list of changes. seed-webkit2-4.0.0+20161014+6c77960+dfsg1/DEVELOPERS000066400000000000000000000011701303774616400202200ustar00rootroot00000000000000=== DEVELOPERS === ==== Coding Style ==== To contribute to seed, the developers needs to be aware of some coding style rules. It's basically based on the coding style from Mozilla [https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Coding_Style] with a few differences. So, tl:dl: * Use four spaces to indent. * Indent after brakets * Pointers always on left of var name, glues to the type. To ease the developer's life, there's a .clang-format to autoformat the source code. Developers are invited to used that tool before submitting a patch. To use that tool, call: clang-format -i filename.c seed-webkit2-4.0.0+20161014+6c77960+dfsg1/MAINTAINERS000066400000000000000000000003741303774616400203270ustar00rootroot00000000000000Robert Carr E-mail: racarr@svn.gnome.org Userid: racarr Tim Horton E-mail: hortont@svn.gnome.org Userid: hortont Alan Knowles E-mail: alan@roojs.com Userid: alank Danilo Cesar Lemes de Paula E-mail: danilocesar.dp+seed@gmail.com Userid: danilocesar seed-webkit2-4.0.0+20161014+6c77960+dfsg1/Makefile.am000066400000000000000000000053111303774616400206620ustar00rootroot00000000000000## Process this file with automake to produce Makefile.in ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS} DISTCHECK_CONFIGURE_FLAGS = --enable-introspection --enable-gtk-doc SUBDIRS = po \ jsextensions \ libseed \ libgjs-private \ src \ modules \ tests \ doc doc_DATA = \ README \ COPYING \ AUTHORS \ ChangeLog \ INSTALL pkgconfig_DATA = seed.pc pkgconfigdir = $(libdir)/pkgconfig man_MANS = doc/seed.1 EXTRA_DIST = $(pkgconfig_DATA) profile-reset: find -name '*.gcda' -delete profile: profile-reset check cp libseed/*.c libseed/.libs/ if PROFILE_MODULES cp modules/readline/*.c modules/readline/.libs/ cp modules/example/*.c modules/example/.libs/ cp modules/sqlite/*.c modules/sqlite/.libs/ cp modules/canvas/*.c modules/canvas/.libs/ cp modules/Multiprocessing/*.c modules/Multiprocessing/.libs/ endif cd libseed/.libs ; gcov *.c if PROFILE_MODULES cd modules/cairo/.libs ; gcov *.c cd modules/canvas/.libs ; gcov *.c cd modules/dbus/.libs ; gcov *.c cd modules/example/.libs ; gcov *.c cd modules/gettext/.libs ; gcov *.c cd modules/gtkbuilder/.libs ; gcov *.c cd modules/libxml/.libs ; gcov *.c cd modules/os/.libs ; gcov *.c cd modules/readline/.libs ; gcov *.c cd modules/sandbox/.libs ; gcov *.c cd modules/sqlite/.libs ; gcov *.c endif if PROFILE_MODULES cp modules/gjs/system/*.c modules/system/.libs/ endif profile-gui: profile if PROFILE_MODULES lcov --directory libseed/.libs --directory modules/cairo/.libs --directory modules/canvas/.libs --directory modules/dbus/.libs --directory modules/example/.libs --directory modules/system/.libs --directory modules/gettext/.libs --directory modules/gtkbuilder/.libs --directory modules/libxml/.libs --directory modules/os/.libs --directory modules/readline/.libs --directory modules/sandbox/.libs --directory modules/sqlite/.libs --capture --output-file seed.info else lcov --directory libseed/.libs --capture --output-file seed.info endif cp seed.info /tmp/ cd /tmp ; genhtml seed.info ; gnome-open index.html # Copy all the spec files. Of course, only one is actually used. # Generate the ChangeLog from the output of 'git log'. dist-hook: for specfile in *.spec; do \ if test -f $$specfile; then \ cp -p $$specfile $(distdir); \ fi \ done @if test -d "$(srcdir)/.git"; \ then \ echo Creating ChangeLog && \ ( cd "$(top_srcdir)" && \ echo '# Generated by Makefile. Do not edit.'; echo; \ $(top_srcdir)/missing --run git log --stat ) > ChangeLog.tmp \ && mv -f ChangeLog.tmp $(top_distdir)/ChangeLog \ || ( rm -f ChangeLog.tmp ; \ echo Failed to generate ChangeLog >&2 ); \ else \ echo A git clone is required to generate a ChangeLog >&2; \ fi CLEANFILES = \ .ycm_extra_conf.pyc \ $(NULL) -include $(top_srcdir)/git.mk seed-webkit2-4.0.0+20161014+6c77960+dfsg1/NEWS000066400000000000000000000350251303774616400173320ustar00rootroot00000000000000== Seed 3.8.0 (2013.04.16) == * See ChangeLog for detailed list of changes == Seed 3.1.1 (2011.05.17) == * Add preliminary support for FreeBSD and OpenBSD, at least * Fix DBus module build problems * Fix typo in documentation * Fix build-time errors with recent dash as sh * Update Seed to follow recent gobject-introspection changes == Seed 3.0.0, "Evacuate the Dancefloor" (2011.04.01) == * Allow the creation of constrained SeedEngine contexts * Expose seed_value_(to|from)_gi_argument and seed_value_to_gvalue as public API * Make seed.h C++ friendly * Take GTK+ version into account in the prefix path == Seed 2.91.90 (2011.02.22) == * Fix build with GTK+3 * Change soname for GTK+3 version == Seed 2.31.91, "Write About Love" (2010.08.30) == * Seed now optionally supports both WebKitGtk+-1.0 and 3.0 * Dynamic Object module - provides support for implementing underlying object callbacks in JavaScript (see commit d31aca) * Implement caller-allocated out arguments * Expose seed_value_from_gvalue() through the API * Fix unusable seed_object_copy_property_names() * Fix various build system issues == Seed 2.31.5, "Elephant" (2010.07.11) == * Seed now requires WebKitGtk+-3.0, built against Gtk+-3.0 * Support for passing GObjects as userdata * Support for redirection of Seed.print via set_print_handler * Support __script_path__ within Seed sandboxes * Fixes to importer to not expose toString/valueOf files * Additional warnings in various potential error cases == Seed 2.31.1, "The Black Album" (2010.03.29) == * Support for returning arrays of GTypes * Support for GError types in various places * Rework out arguments - old style still works, also returns dictionary with keys named after parameters * Support initialization using an existing JSGlobalContext == Seed 2.30.0, "Piano Man" (2010.03.29) == * Second stable release! == Seed 2.29.91, "Greatest Hits" (2010.02.23) == * Support void * arguments * Support connecting to notify:: signals everywhere == Seed 2.29.90, "Fort Nightly" (2010.02.08) == * To avoid potential filename collisions, the imports system now supports: imports['somedir/somefile.js'] (Alan Knowles) * Fix crash involving gtk_tree_model_get_value (Alan Knowles) * Fix subtle crash in DBus bindings (Rob Taylor) == Seed 2.29.5.3, "Twist and Shout" (2010.01.11) == * Pass null structs through as "null" instead of empty seed_structs * Revert one of the 64-bit type safety commits from 2.29.5.2 until someone can take a closer look at it; it broke enum typing on Linux * Fix potential segfault in various modules (missing null sentinels) == Seed 2.29.5.2, "Third Stage" (2010.01.07) == * Move tests to automake-style 'make check', away from the previous, Python-based 'make test' tool; all tests are now assertion-based, instead of the previous output-based style * Fix various segfaults on Mac OS X (and possibly *BSD) related to 64-bit type safety problems * Fix functionality of out arguments * Interpreter now returns non-zero status code if it exits with an exception == Seed 2.29.5.1, "Achtung Baby" (2010.01.01) == * Fix "duplicate symbol" errors on non-Linux platforms == Seed 2.29.5, "Icky Thump" (2009.01.01) == * Fix build on non-GNU platforms (primarily Mac OS X) * Distribute the REPL snippet with Seed again; the built-in REPL will work now * Fix segfault when accidentally protecting already-garbage-collected values * Fix segfault when accidentally unreffing nonexistant GIBaseInfos == Seed 2.29.4, "( )" (2009.12.17) == * Improve type conversion portability; add seed_value_(to|from)_(s)size functions. * Small random cleanup of unused arguments. == Seed 2.29.3 (2009.11.30) == No changes. == Seed 2.29.2, "Never Mind the Bollocks" (2009.11.16) == * Change semantics of seed_value_from_string and _from_filename; they now return JavaScript null if passed a null input value. * Seed interpreter adds --version argument * libseed adds --seed-version argument * Clutter extension wrapper for animate_with_alpha == Seed 2.28.0, "The Rise and Fall of Ziggy Stardust and the Spiders from Mars" (2009.09.21) == * First official stable release! == Seed 2.27.92, "Metal Machine Music" (2009.09.07) == * Fix a bug in module building; modules are now versionless * The instanceof operator now works for GTypes * Add global support for G_TYPE_STRV == Seed 2.27.91, "Yellow Submarine" (2009.08.21) == * Added seed_context_collect, to provide an interface for forcing garbage collection manually == Seed 2.27.90, "London Calling" (2009.08.10) == * Expanded and updated documentation; also available at: http://library.gnome.org/devel/seed/unstable/ * All JavaScript contexts now have a __script_path__ property, which exposes the absolute, canonical path to the evaluated script * Add __init__.js functionality; if an imported folder contains __init__.js, it will be evaluated with the imported context as the 'this' object * Fix bug which caused inheritance from a GType created in Seed to fail * Add "pretty" property installation, see: tests/javascript/gtypes/gtype-property-nice.js * New FFI module, provides an interface for calling non-introspected native C functions from JavaScript == Seed 0.8.5, "Self Portrait" (2009.07.10) == * Significant reorganization and expansion of the reference documentation * New native modules: * gettext * MPFR (partially complete) * Same Seed has moved to the gsoc-seed-games branch of Gnome Games (and will eventually move to master) * Add seed-module.h, which includes a handful of macros to make writing modules slightly more attractive. Look at gettext or the reference docs for examples. * Prefix native modules with seed_ (libseed_readline.so, etc.); this fixes the need to incessantly 'make clean' seed and cuts down on ambiguity in naming. * Add 'seed_value_is_string', 'seed_value_is_number', and 'seed_value_is_object_of_class' to libseed * Update examples to latest (now frozen) Clutter API changes. * Fixes a bug with the importer search path which resulted in the search path being overwritten each time something was imported * The importer now also searches the directory in which the script being executed is located by default. == Seed 0.8, "Bringing It All Back Home" (2009.05.27) == * Importer now supports constructing directory objects, to avoid manipulation of search path. Importer directory objects now support property enumeration. * Fix small leak in GObject wrapper initialization. (and also simplify the process). * GtkBuilder module to handle GtkBuilder automatic signal connection. * *_init methods now take normal arrays (by value) in addition to the special Seed.argv array. * GObject constructors (init methods) now take "self" as a parameter. * Passing non gobject-properties to a GObject constructor will set the properties on the GObject wrapper. * Module documentation rewritten in docbook, and builds one nice manual. * New Cairo module, supports most of the cairo API, with automatic memory management and everything you would expect. * Fix a reference count leak introduced in the last few releases. in some cases with non INITIALLY_UNOWNED objects. * Some work on ClutterPad examples, and writing examples which live inside of it (lots of fun to play with!, cairo example...fun spring example...ClutterBox2D) * Working around a WebKit bug (which is actually fixed in SVN now), should prevent a crash that happened sometimes with C modules. * Clutter animatev wrapper looks up property type wrapper now, so as to avoid having to pass [GObject.TYPE_FOO, bar] * Implement some varargs functions which can be implemented on top of non-vararg variants in JavaScript extensions. * JSON stuff (stringify,parse) is now in gnome-js-common. * Add seed_value_to_format to API, for converting an Array of SeedValue based on a format string. * Install seed-debug.h so modules can make use of it. * Search path now works in nonstandard prefix, default search path includes gnome-js-common moduledir (from pkgconfig). * Support to/from Date objects to time_t. == Seed 0.7, "Another Side of Bob Dylan" (2009.05.13) == * Support for library init methods. * The REPL now supports multi-line entry. * Signal disconnection. * Significant Gtk-Doc reorganization. * New C modules: * sandbox - provides sandboxed JavaScriptCore contexts. * DBus - Client side DBus bindings. * libxml - XML parsing, XPath, etc. * Examples: * New: ClutterPad (initially by Johan Euphrosine). * New: dbus-banshee, dbus-consolekit, dbus-networkmanager * New: xml-dom.js xml-tree.js, xml-xpath.js. * Pango examples have returned. * Same Seed performance is increased significantly. * Many examples now use "recent" style; some were completely rewritten * Improvements to test system, and quite a few more tests. * Improvements to error checking/handling in signal code. * Reorganization of API related to GClosure handling, much cleaner and easier. * Several new API methods. * GC related crash fixes. * Improvements to seed_value_to_string (mostly formatting improvements). * Void methods now properly return undefined instead of null. * seed_make_exception takes format strings now. == Seed 0.6, "Beatles for Sale" (2009.04.29) == * Significant build fixes and cleanups. Should build on more distros with weird libffis now. * Depend on GObject-introspection from GIT. * Some API additions. * Reimplement Seed.import_namespace in terms of the new imports system, will be entirely deprecated for 0.6. * Improve memory management in signals and closures. * Rewrite the GType subclassing to avoid using FFI, saves memory and improves performance. * GType "init" now means "constructor" and not "instance init". * Signal installation, is now handled by an array on the type definition rather than in class_init (which was clunky and C-like). * Lots of new documentation, including a documentation index, a description of the mapping from C to JavaScript, an example index, and updates to the rest of the documentation. * Significant cleanup of all of the examples, a lot of them had bit rotted a bit, being written months ago. == Seed 0.5, "Transformer" (2009.04.16) == * Many, many crash fixes. * Significantly better base memory usage (on the order of MB) for some apps. * Enums use Gtk.WindowType.NORMAL instead of Gtk.WindowType.Normal. This may break existing code in subtle ways (as Gtk.WindowType.Normal will now be JavaScript null). * instance_init is now just init when creating new GTypes. This will require changes in any code using subclassing. * Enum types are validated when passed in to functions now. * Complete rewrite of import system, spanning GObject Introspection namespaces, native modules, and JavaScript files, which is compatible with Gjs. * Along with above, deprecate Seed.import_namespace. * New 'os' module, similar to that of Python. Provides access to a significant quantity of low-level system features unavailable from GLib. * Significant updates to Canvas module - most features are compatible with the Mozilla/WebKit implementations at this point. * Clutter 0.9 animation API wrappers. * Add seed_repl_expose; gives the ability to drop to a JavaScript REPL from within C, and magically expose JSValueRefs to JS in a simple way. * Seed.readline history persists between sessions (stored in ~/.seed_history) * Support for several more array types. * Added Seed.breakpoint(), which inserts a breakpoint instruction. * API additions: Lots of API additions. Including a significant amount of API documentation. * New examples: * opengl-glib examples (teapot, gears, triangle) * Gtk Twitter client (from the Ars Technica article) * Same Seed (Clutter 0.9 rewrite of Same Gnome) * Clutter-COGL example * Reddit client (Gio and JSON) * Library of Clutter "slide transitions" * Rewrote clutter example for 0.9 * The Lights Off example now lives in Gnome Games. == Seed 0.3, "Wednesday Morning 3AM" (2008.12.31) == * Lots of memory changes. Memory usage isn't bad anymore, reference counting actually works (no big leaks or anything anymore ...there are still a few very small ones you can trigger). Memory usage of most of the examples after they've loaded, has about halved (or more in cases like the browser) since 0.1, and now compares very favorably to other dynamic languages. Lots of g_slice_alloc, which comes off quite nicely when creating bunches of small structs like ClutterColor. * Innumerable bug fixes. * Structs work now! Things like GdkRectangle: you can allocate them, get at their members, etc. * Including struct "literals, i.e." stage.set_color({red: 255, alpha: 220}). * GObject subclassing, which was rushed in to a 0.1 point release, is reliable now! signal installation too. * Multiple context support, rather than the silly global context. * Support for string array argument conversion. * C extension Modules * readline * Multiprocessing -- Simple IPC pipes. Just an example, really. * sqlite * canvas -- A little, toy, mostly functional but incomplete HTML Canvas implementation. May be useful until we have cairo bindings. Supports SVG/PDF output. * Signals use userdata now. The 'this' argument was removed, as it really just lead to organizational issues. * object.signal.connect is defined for connecting by strings (allows for connecting to detailed signals, like property notifications) * 'out' arguments of methods work, granted in a rather poor fashion, not sure of the best way to do this yet. * Enums use Gtk.WindowType.Normal instead of Gtk.WindowType.normal, may break existing code in subtle ways (as Gtk.WindowType.normal will now be JavaScript null). * Licensing update - libseed is LGPL. The trivial examples are BSD, the more complete ones are GPL. * Lots of leaks fixed, and also some reference bugs that lead to crashing. * External API is pretty usable now. * External API example (Turtle Graphics) * Threading sort of works now. It's rather unpredictable, but async callbacks and stuff are fine. * Many more Seed examples. Ranging from Gnio Server, to threading. The browser example is pretty neat now, and has sqlite bookmarks, WebInspector, and a few other tidbits. lightsoff and browser are the two highlight examples to play with. * Skeleton GTK-Doc for API * New builtins: Seed.spawn, Seed.repl/glib_repl/thread_repl. Kind of useful for debugging. * Removed builtins: Seed.prototype: Now use Gtk.Window.prototype Seed.closure, Automatically handled now. Seed.closure_native, automagic. Seed.readline, moved in to module. seed-webkit2-4.0.0+20161014+6c77960+dfsg1/README000066400000000000000000000023121303774616400175040ustar00rootroot00000000000000=== Seed README === Seed is a library and interpreter, dynamically bridging (through gobject-introspection) the WebKit JavaScriptCore engine with the GObject type system. In a more concrete sense, Seed enables you to immediately write applications around a significant portion of the GNOME platform, and easily embed JavaScript as a scripting language in your GObject library. Seed recommends WebKitGtk+ 3.0 (built against gtk+-3.0). If you want to use WebKitGtk+ 1.0, append "--with-webkit=1.0" to your configuration arguments. Website: http://live.gnome.org/Seed SVN: git://git.gnome.org/seed Dependencies (Ubuntu package name): * gobject-introspection (gobject-introspection) * gobject-introspection-glib (gobject-introspection-glib) * gir-repository (gobject-introspection-repository) * webkit (libwebkit-dev) * readline (libreadline-dev) * ffi (libffi-dev) * gnome-js-common (gnome-js-common) Recommended Dependencies (Ubuntu package name): * gobject-introspection-freedesktop * sqlite3 (libsqlite3-dev) * soup (libsoup2.4-dev) * clutter (libclutter-1.0-dev) * clutter-gtk (libclutter-gtk-0.10-dev) * cairo (libcairo-dev) * gtk-doc (gtk-doc-tools) * dbus (libdbus-1-dev) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/autogen.sh000077500000000000000000000010501303774616400206230ustar00rootroot00000000000000#!/bin/sh # Run this to generate all the initial makefiles, etc. srcdir=`dirname $0` test -z "$srcdir" && srcdir=. PKG_NAME="seed" (test -f $srcdir/src/main.c) || { echo -n "**Error**: Directory "\`$srcdir\'" does not look like the" echo " top-level $PKG_NAME directory" exit 1 } which gnome-autogen.sh || { echo "You need to install gnome-common from GNOME SVN and make" echo "sure the gnome-autogen.sh script is in your \$PATH." exit 1 } REQUIRED_AUTOMAKE_VERSION=1.9 REQUIRED_INTLTOOL_VERSION=0.40.4 . gnome-autogen.sh seed-webkit2-4.0.0+20161014+6c77960+dfsg1/configure.ac000066400000000000000000000404731303774616400211240ustar00rootroot00000000000000AC_PREREQ(2.59) AC_INIT(seed, 4.0.0) AM_INIT_AUTOMAKE([1.7 -Wno-portability]) AM_MAINTAINER_MODE([enable]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_MACRO_DIR([m4]) AC_CANONICAL_HOST AC_PROG_CC AM_PROG_CC_C_O AC_PROG_LIBTOOL PKG_PROG_PKG_CONFIG # Use AM_SILENT_RULES if present m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) changequote(,)dnl ensureflag() { flag="$1"; shift result="$@" case " ${result} " in *[\ \ ]${flag}[\ \ ]*) ;; *) result="${flag} ${result}" ;; esac echo ${result} } changequote([,])dnl dnl =====================Internationalization================================== GETTEXT_PACKAGE=seed AC_SUBST(GETTEXT_PACKAGE) AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE", [GETTEXT package name]) AM_GLIB_GNU_GETTEXT IT_PROG_INTLTOOL([0.35.0]) dnl ============================libffi========================================= PKG_CHECK_MODULES(FFI, libffi, have_ffi_pkgconfig=yes, have_ffi_pkgconfig=no) if test x"$have_ffi_pkgconfig" = xno ; then AC_MSG_CHECKING(for ffi.h) AC_TRY_CPP([#include ], have_ffi_h=yes, have_ffi_h=no) if test x"$have_ffi_h" = x"yes"; then save_LIBS=$LIBS if test x"$with_ffi" = x"yes" || test x"$with_ffi" = x"auto"; then other_LIBS= else other_LIBS=$with_ffi fi AC_SEARCH_LIBS(ffi_call,ffi,,AC_MSG_ERROR([libffi not found]),$other_LIBS) if test x"$ac_cv_search_ffi_call" = x"none required" ; then FFI_LDFLAGS=$other_LIBS else FFI_LDFLAGS="$ac_cv_search_ffi_call $other_LIBS" fi LIBS=$save_LIBS fi if test x"$have_ffi_h" != x"yes" ; then AC_MSG_ERROR([ffi.h not found]) fi FFI_CFLAGS= AC_MSG_RESULT([$have_ffi_h]) fi AC_SUBST(FFI_LDFLAGS) AC_SUBST(FFI_CFLAGS) dnl ==============================WebKit======================================= m4_define([webkit_default], [4.0]) AC_ARG_WITH([webkit], [AC_HELP_STRING([--with-webkit=@<:@4.0/3.0/1.0@:>@], [Select the Webkit backend, default=4.0])], [], [with_webkit=webkit_default]) dnl=== support all 1.0, 3.0 and 4.0 (default 3.0) == AS_CASE([$with_webkit], [3.0], [ WEBKIT_PC=webkitgtk-3.0 SEED_GTK_VERSION=-gtk3 AC_CHECK_LIB(webkitgtk-3.0, JSContextGroupCreate,, AC_CHECK_LIB(javascriptcoregtk-3.0, JSContextGroupCreate,WEBKIT_PC=javascriptcoregtk-3.0)) ], [4.0], [ WEBKIT_PC=webkitgtk-4.0 SEED_GTK_VERSION=-gtk4 AC_CHECK_LIB(webkitgtk-4.0, JSContextGroupCreate,, AC_CHECK_LIB(javascriptcoregtk-4.0, JSContextGroupCreate,WEBKIT_PC=javascriptcoregtk-4.0)) ], [1.0], [ AC_CHECK_LIB(webkitgtk-1.0, JSContextGroupCreate,WEBKIT_PC=webkitgtk-1.0, AC_CHECK_LIB(javascriptcoregtk-1.0, JSContextGroupCreate,WEBKIT_PC=javascriptcoregtk-1.0, AC_CHECK_LIB(webkit-1.0, JSContextGroupCreate,WEBKIT_PC=webkit-1.0, AC_MSG_ERROR([The installed version of WebKit is too old. Seed requires WebKit SVN revision 35442 or greater.])))) ], [AC_MSG_ERROR([Invalid argument for --with-webkit])] ) PKG_CHECK_MODULES(WEBKIT, $WEBKIT_PC) AC_SUBST(WEBKIT_PC) AC_SUBST(WEBKIT_CFLAGS) AC_SUBST(WEBKIT_LDFLAGS) AC_SUBST(SEED_GTK_VERSION) dnl =========================Introspection===================================== GOBJECT_INTROSPECTION_CHECK([1.41.4]) PKG_CHECK_MODULES(GOBJECT_INTROSPECTION, gobject-introspection-1.0 >= 0.6.3) AC_SUBST(GOBJECT_INTROSPECTION_CFLAGS) AC_SUBST(GOBJECT_INTROSPECTION_LDFLAGS) GOBJECT_INTROSPECTION_VERSION=`$PKG_CONFIG --modversion gobject-introspection-1.0 | $AWK '{ split($1, a , ".") ; printf "0x%02d%02d%02d", a[[1]], a[[2]], a[[3]] }'` AC_SUBST(GOBJECT_INTROSPECTION_VERSION) dnl ========================GNOME-js common==================================== PKG_CHECK_MODULES(GNOME_JS, gnome-js-common) GNOME_JS_DIR=`pkg-config --variable=moduledir gnome-js-common` AC_SUBST(GNOME_JS_DIR) dnl ========================GThread============================================ PKG_CHECK_MODULES(GTHREAD, gthread-2.0) dnl ========================GIO================================================ PKG_CHECK_MODULES(GIO, gio-2.0) dnl ========================GModule================================================ PKG_CHECK_MODULES(GMODULE, gmodule-no-export-2.0) dnl =============================Modules======================================= dnl ==== canvas ==== AC_ARG_ENABLE(canvas-module, AC_HELP_STRING([--enable-canvas-module], [enable the canvas Seed module. [default=yes]]), [want_canvas_module=$enableval],[want_canvas_module="yes"]) if test x"$want_canvas_module" = x"yes" ; then PKG_CHECK_MODULES(CAIRO, cairo) AC_SUBST(CAIRO_CFLAGS) AC_SUBST(CAIRO_LDFLAGS) if test x"$with_webkit" = x"3.0" ; then PKG_CHECK_MODULES(GDK, gdk-3.0) else PKG_CHECK_MODULES(GDK, gdk-2.0) fi AC_SUBST(GDK_CFLAGS) AC_SUBST(GDK_LDFLAGS) fi AM_CONDITIONAL(BUILD_CANVAS_MODULE, test "x$want_canvas_module" = "xyes") AC_SUBST(BUILD_CANVAS_MODULE) dnl ==== readline ==== AC_ARG_ENABLE(readline-module, AC_HELP_STRING([--enable-readline-module], [enable the readline Seed module. [default=yes]]), [want_readline_module=$enableval],[want_readline_module="yes"]) if test x"$want_readline_module" = x"yes" ; then AC_CHECK_HEADER([readline/readline.h],,AC_MSG_ERROR([the readline library is not installed.])) fi AM_CONDITIONAL(BUILD_READLINE_MODULE, test "x$want_readline_module" = "xyes") AC_SUBST(BUILD_READLINE_MODULE) dnl ==== multiprocessing ==== AC_ARG_ENABLE(multiprocessing-module, AC_HELP_STRING([--enable-multiprocessing-module], [enable the multiprocessing Seed module. [default=yes]]), [want_multiprocessing_module=$enableval], [want_multiprocessing_module="yes"]) AM_CONDITIONAL(BUILD_MULTIPROCESSING_MODULE, test "x$want_multiprocessing_module" = "xyes") AC_SUBST(BUILD_MULTIPROCESSING_MODULE) dnl ==== sqlite ==== AC_ARG_ENABLE(sqlite-module, AC_HELP_STRING([--enable-sqlite-module], [enable the sqlite Seed module. [default=yes]]), [want_sqlite_module=$enableval],[want_sqlite_module="yes"]) if test x"$want_sqlite_module" = x"yes" ; then PKG_CHECK_MODULES(SQLITE, sqlite3) AC_SUBST(SQLITE_CFLAGS) AC_SUBST(SQLITE_LDFLAGS) fi AM_CONDITIONAL(BUILD_SQLITE_MODULE, test "x$want_sqlite_module" = "xyes") AC_SUBST(BUILD_SQLITE_MODULE) dnl ==== xorg ==== AC_ARG_ENABLE(xorg-module, AC_HELP_STRING([--enable-xorg-module], [enable the xorg Seed module. [default=no]]), [want_xorg_module=$enableval],[want_xorg_module="no"]) if test x"$want_xorg_module" = x"yes" ; then PKG_CHECK_MODULES(LIBXSS, [xscrnsaver], [ AC_DEFINE(USE_LIBXSS, 1, [Use XScreenSaver for idleness]) AC_SUBST(LIBXSS_CFLAGS) AC_SUBST(LIBXSS_LIBS) ] , [ echo "" echo "configure: error: " echo "XScreenSaver development headers not found." echo "Use --enable-xorg-module=no if you do not need it." echo "If you're using debian or ubuntu, install it by" echo "\"sudo apt-get install libxss-dev\"" echo "" exit -1 ]) fi AM_CONDITIONAL(BUILD_XORG_MODULE, test "x$want_xorg_module" = "xyes") AC_SUBST(BUILD_XORG_MODULE) dnl ==== Example ==== AC_ARG_ENABLE(example-module, AC_HELP_STRING([--enable-example-module], [enable the example Seed module. [default=yes]]), [want_example_module=$enableval],[want_example_module="yes"]) AM_CONDITIONAL(BUILD_EXAMPLE_MODULE, test "x$want_example_module" = "xyes") AC_SUBST(BUILD_EXAMPLE_MODULE) dnl ==== dbus ==== AC_ARG_ENABLE(dbus-module, AC_HELP_STRING([--enable-dbus-module], [enable the dbus Seed module. [default=yes]]), [want_dbus_module=$enableval],[want_dbus_module="yes"]) AM_CONDITIONAL(BUILD_DBUS_MODULE, test "x$want_dbus_module" = "xyes") AC_SUBST(BUILD_DBUS_MODULE) if test x"$want_dbus_module" = x"yes" ; then PKG_CHECK_MODULES(DBUS, dbus-1) AC_SUBST(DBUS_CFLAGS) AC_SUBST(DBUS_LDFLAGS) PKG_CHECK_MODULES(DBUSGLIB, dbus-glib-1) AC_SUBST(DBUSGLIB_CFLAGS) AC_SUBST(DBUSGLIB_LDFLAGS) fi dnl ==== os ==== AC_ARG_ENABLE(os-module, AC_HELP_STRING([--enable-os-module], [enable the os Seed module. [default=yes]]), [want_os_module=$enableval],[want_os_module="yes"]) AM_CONDITIONAL(BUILD_OS_MODULE, test "x$want_os_module" = "xyes") AC_SUBST(BUILD_OS_MODULE) dnl ==== ffi ==== AC_ARG_ENABLE(ffi-module, AC_HELP_STRING([--enable-ffi-module], [enable the ffi Seed module. [default=yes]]), [want_ffi_module=$enableval],[want_ffi_module="yes"]) AM_CONDITIONAL(BUILD_FFI_MODULE, test "x$want_ffi_module" = "xyes") AC_SUBST(BUILD_FFI_MODULE) dnl ==== libdl ==== AC_CHECK_LIB([c], [dlsym], [LIBDL=""], [AC_CHECK_LIB([dl], [dlsym], [LIBDL="-ldl"])]) AC_SUBST(LIBDL) dnl ==== libxml ==== AC_ARG_ENABLE(libxml-module, AC_HELP_STRING([--enable-libxml-module], [enable the libxml Seed module. [default=yes]]), [want_libxml_module=$enableval],[want_libxml_module="yes"]) if test x"$want_libxml_module" = x"yes" ; then PKG_CHECK_MODULES(LIBXML, libxml-2.0) AC_SUBST(LIBXML_CFLAGS) AC_SUBST(LIBXML_LDFLAGS) fi AM_CONDITIONAL(BUILD_LIBXML_MODULE, test "x$want_libxml_module" = "xyes") AC_SUBST(BUILD_LIBXML_MODULE) dnl ==== os ==== AC_ARG_ENABLE(os-module, AC_HELP_STRING([--enable-os-module], [enable the os Seed module. [default=yes]]), [want_os_module=$enableval],[want_os_module="yes"]) AM_CONDITIONAL(BUILD_OS_MODULE, test "x$want_os_module" = "xyes") AC_SUBST(BUILD_OS_MODULE) dnl ==== DynamicObject ==== AC_ARG_ENABLE(dynamicobject-module, AC_HELP_STRING([--enable-dynamicobject-module], [enable the DynamicObject Seed module. [default=yes]]), [want_dynamicobject_module=$enableval],[want_dynamicobject_module="yes"]) AM_CONDITIONAL(BUILD_DYNAMICOBJECT_MODULE, test "x$want_dynamicobject_module" = "xyes") AC_SUBST(BUILD_DYNAMICOBJECT_MODULE) dnl ==== gtkbuilder ==== AC_ARG_ENABLE(gtkbuilder-module, AC_HELP_STRING([--enable-gtkbuilder-module], [enable the gtkbuilder Seed module. [default=yes]]), [want_gtkbuilder_module=$enableval],[want_gtkbuilder_module="yes"]) if test x"$want_gtkbuilder_module" = x"yes" ; then if test x"$with_webkit" = x"3.0" || test x"$with_webkit" = x"4.0" ; then PKG_CHECK_MODULES(GTK, gtk+-3.0) else PKG_CHECK_MODULES(GTK, gtk+-2.0) fi AC_SUBST(GTK_CFLAGS) AC_SUBST(GTK_LDFLAGS) fi AM_CONDITIONAL(BUILD_GTKBUILDER_MODULE, test "x$want_gtkbuilder_module" = "xyes") AC_SUBST(BUILD_GTKBUILDER_MODULE) dnl ==== cairo ==== AC_ARG_ENABLE(cairo-module, AC_HELP_STRING([--enable-cairo-module], [enable the cairo Seed module. [default=yes]]), [want_cairo_module=$enableval],[want_cairo_module="yes"]) if test x"$want_cairo_module" = x"yes" ; then PKG_CHECK_MODULES(CAIRO, cairo) AC_SUBST(CAIRO_CFLAGS) AC_SUBST(CAIRO_LDFLAGS) fi AM_CONDITIONAL(BUILD_CAIRO_MODULE, test "x$want_cairo_module" = "xyes") AC_SUBST(BUILD_CAIRO_MODULE) dnl ==== gettext ==== AC_ARG_ENABLE(gettext-module, AC_HELP_STRING([--enable-gettext-module], [enable the gettext Seed module. [default=yes]]), [want_gettext_module=$enableval],[want_gettext_module="yes"]) AM_CONDITIONAL(BUILD_GETTEXT_MODULE, test "x$want_gettext_module" = "xyes") AC_SUBST(BUILD_GETTEXT_MODULE) dnl ==== mpfr ==== AC_ARG_ENABLE(mpfr-module, AC_HELP_STRING([--enable-mpfr-module], [enable the mpfr Seed module. [default=yes]]), [want_mpfr_module=$enableval],[want_mpfr_module="yes"]) if test x"$want_mpfr_module" = x"yes" ; then AC_TRY_CPP([#include ], have_mpfr_h=yes, have_mpfr_h=no) if test x"$have_mpfr_h" = x"yes"; then save_LIBS=$LIBS if test x"$with_mpfr" = x"yes" || test x"$with_mpfr" = x"auto"; then other_LIBS= else other_LIBS=$with_mpfr fi AC_SEARCH_LIBS(mpfr_init2,mpfr,,AC_MSG_ERROR([mpfr not found]),$other_LIBS) if test x"$ac_cv_search_mpfr_call" = x"none required" ; then MPFR_LDFLAGS=$other_LIBS else MPFR_LDFLAGS="$other_LIBS" fi LIBS=$save_LIBS fi if test x"$have_mpfr_h" != x"yes" ; then AC_MSG_ERROR([mpfr.h not found]) fi MPFR_CFLAGS= fi AM_CONDITIONAL(BUILD_MPFR_MODULE, test "x$want_mpfr_module" = "xyes") AC_SUBST(BUILD_MPFR_MODULE) dnl ==== glib-compile-resources ==== AC_PATH_PROG([GLIB_COMPILE_RESOURCES],[glib-compile-resources]) AS_IF([test "$GLIB_COMPILE_RESOURCES" == ""],[ AC_MSG_ERROR([glib-compile-resources not found]) ]) dnl ===========================Profiling======================================= AC_ARG_ENABLE(profile, AC_HELP_STRING([--enable-profile], [turn on profiling [default=no]]), [enable_profile="yes"],[enable_profile="no"]) AC_ARG_ENABLE(profile-modules, AC_HELP_STRING([--enable-profile-modules], [turn on profiling for modules [default=no]]), [enable_profile_modules="yes"],[enable_profile_modules="no"]) if test "x$enable_profile" = "xyes"; then SEED_PROFILE_CFLAGS="-fprofile-arcs -ftest-coverage" SEED_PROFILE_LIBS="-lgcov" [need_debug="yes"] fi if test "x$enable_profile" = "xno"; then [enable_profile_modules="no"] fi AC_SUBST(SEED_PROFILE_CFLAGS) AC_SUBST(SEED_PROFILE_LIBS) AM_CONDITIONAL(PROFILE_MODULES, test "x$enable_profile_modules" = "xyes") dnl =============================Debug========================================= AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug], [enable verbose debugging. [default=no]]), [enable_debug="yes"],[enable_debug="no"]) if test "x$enable_debug" = "xyes"; then SEED_DEBUG_CFLAGS="-DSEED_ENABLE_DEBUG -g" CFLAGS="$CFLAGS -O0 -Wall" else SEED_DEBUG_CFLAGS="-DG_DISABLE_ASSERT -DG_DISABLE_CHECKS -DG_DISABLE_CAST_CHECKS" CFLAGS="$CFLAGS -Wall" if test "x$need_debug" = "xyes"; then AC_MSG_ERROR([debug must be enabled in order to enable profiling.]) fi fi AC_SUBST(SEED_DEBUG_CFLAGS) AC_CHECK_HEADERS(pty.h) dnl =============================gtk-doc======================================= GTK_DOC_CHECK(1.9) dnl =============================Output======================================== AC_CONFIG_FILES([ seed.pc Makefile doc/index.html doc/conventions.html doc/runtime.html doc/tutorial-standalone/tutorial.html doc/modules/canvas/canvas.html doc/modules/multiprocessing/multiprocessing.html doc/modules/canvas/Makefile doc/modules/multiprocessing/Makefile doc/modules/readline/Makefile doc/modules/gtkbuilder/Makefile doc/modules/sqlite/Makefile doc/modules/sandbox/Makefile doc/mapping/mapping.html libseed/Makefile libgjs-private/Makefile po/Makefile.in src/Makefile jsextensions/Makefile tests/Makefile tests/javascript/Makefile tests/javascript/included.js tests/javascript/syntax-test-noasserts.js tests/javascript/modules-noasserts.js tests/javascript/gtypes/Makefile tests/javascript/signals/Makefile tests/javascript/structs/Makefile tests/c/Makefile doc/Makefile doc/modules/Makefile doc/modules/version.xml doc/tutorial-standalone/Makefile doc/reference/Makefile doc/reference/version.xml doc/mapping/Makefile modules/Makefile modules/example/Makefile modules/sqlite/Makefile modules/xorg/Makefile modules/canvas/Makefile modules/readline/Makefile modules/multiprocessing/Makefile modules/sandbox/Makefile modules/os/Makefile modules/dbus/Makefile modules/dbus/util/Makefile modules/libxml/Makefile modules/cairo/Makefile modules/gtkbuilder/Makefile modules/gettext/Makefile modules/mpfr/Makefile modules/ffi/Makefile modules/DynamicObject/Makefile modules/gjs/system/Makefile modules/gjs/_gi/Makefile modules/gjs/Makefile libseed/seed-path.h ]) AC_OUTPUT echo " Build Configuration: Debug......................$enable_debug Profiling/Coverage.........$enable_profile Profiling for Modules......$enable_profile_modules gtk-doc....................$enable_gtk_doc Installation: Prefix.....................$prefix Modules: Canvas.....................$want_canvas_module example....................$want_example_module multiprocessing............$want_multiprocessing_module readline...................$want_readline_module SQLite.....................$want_sqlite_module XOrg.......................$want_xorg_module DBus.......................$want_dbus_module libxml.....................$want_libxml_module cairo......................$want_cairo_module gtkbuilder.................$want_gtkbuilder_module gettext....................$want_gettext_module mpfr.......................$want_mpfr_module ffi........................$want_ffi_module Dynamic Object.............$want_dynamicobject_module " if test "x$want_readline_module" != "xyes"; then echo "WARNING: The readline module is not enabled. Without this, the Seed REPL will not work; however, most Seed applications will still run. " fi seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/000077500000000000000000000000001303774616400173735ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/Makefile.am000066400000000000000000000005261303774616400214320ustar00rootroot00000000000000SUBDIRS = tutorial-standalone modules mapping reference EXTRA_DIST = \ index.html.in \ runtime.html.in \ style.css \ conventions.html.in \ sh.css \ sh.js \ sh_js.js \ seed.1 doc_DATA = index.html runtime.html conventions.html style.css sh.css sh.js sh_js.js ## File created by the gnome-build tools -include $(top_srcdir)/git.mk seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/conventions.html.in000066400000000000000000000024021303774616400232310ustar00rootroot00000000000000 Seed Coding Conventions
v.@VERSION@
Naming and Capitalization

  • Always use UpperCamelCase for the names of classes.
  • Always use underscore_case for the names of variables and functions.

Encapsulation

  • Prefer functions to properties, for performance's sake.
  • Place all code for a class within its init function. Look at the tutorial Web Browser for an example.

seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/index.html.in000066400000000000000000000217721303774616400220060ustar00rootroot00000000000000 Seed Documentation
v.@VERSION@
Tutorial

There is a (very) introductory tutorial to Seed, covering the creation of a small GTK+ WebKit browser, here.

Mapping

There is a document covering at a broad level, how things in a namespace are mapped to Seed when importing, here.

Reference Manual

The C API, some of the modules, and a small (but expanding) portion of the runtime API is documented here.

Runtime

Documentation on the Seed builtins and runtime is here.

Examples

Seed has a wide variety of examples in git. A partial index of some of the more useful examples is below:

Large Examples

  • browser - An expanded version of the simple WebKit browser outlined in the tutorial
  • clutter-pad - An example to prototype Clutter scripts using a GtkSourceView widget and a GtkClutter stage. Demonstrates usage of sandbox module and GtkBuilder
  • clutter-shader - Demonstrates the use of Clutter Shaders and GtkSourceView
  • pango - Demonstrates a bit more complicated Pango usage, and Clutter usage, to create a sort of font playground
  • turtle - a simple example of the C embedding API to create a logo like turtle
  • twitter - A moderately simple Gtk twitter client, demonstrates GIO, Gtk, GdkPixbuf.

Small Examples

  • accelgroup.js - Demonstrates proper use of Gtk key accelerators
  • actions.js - Gtk actions, for menus, toolbars, and accelerators
  • async-quine.js - A Quine which loads itself asynchronously
  • broken - Several old examples, or old versions of examples which have not been updated
  • calculator.js - A simple GTK calculator
  • clutter-1.0.js - A silly demo of Clutter 1.0
  • clutter-cairo-1.0.js - Simple use of Clutter 1.0's Cairo component
  • clutter-cogl-1.0.js - Demonstrates usage of COGL for drawing in Clutter
  • dbus-banshee - Demonstrates the use of DBus to control Banshee
  • dbus-consolekit - Demonstrates the use of DBus to query ConsoleKit
  • dbus-networkmanager - Demonstrates the use of DBus to query NetworkManager
  • gconf.js - Simple GConf usage (reading keys)
  • gdkpixbufloader.js - Demonstrates reading an image with GIO and loading it in to a GdkPixbuf
  • glib - Several examples of using GLib, including timers, timeouts and threading
  • Gnio.js - Basic client usage of GIO
  • Gnio-server.js -Implementing a server using GIO
  • gtkplug.js - Demonstrates GtkPlug usage
  • gtktextview.js - A very simple use of GtkTextView
  • gtktreeview.js - Demonstrates the use of GtkTreeView
  • json-reddit.js - Uses GIO and JSON to parse the reddit homepage
  • ls.js - Enumerating a directory with GIO
  • n-oscillator.js - Demonstrates basic Gtk and GStreamer usage
  • notify-test.js - Usage of libnotify
  • opengl - Reimplementations of classic opengl examples in Seed (including glxgears!)
  • pango-fontset - Demonstrates basic Pango usage (for querying font information)
  • poppler.js - A simple PDF viewer, demonstrates poppler and GTK
  • quine.js - Reads itself with GIO
  • repl.js - The Seed REPL
  • soup.js - Basic client usage of soup
  • threaded-repl.js - An example of a REPL which runs async while a GTK program continues to run
  • video.js - Runs the GStreamer video test
  • vte-test.js - A simple terminal using VTE
  • xml-dom - Demonstrates the use of the libxml module for basic document access using DOM methods
  • xml-tree - Demonstrates the use of the libxml module for basic document access using the document tree
  • xml-xpath - Demonstrates the use of the libxml module for basic document access using XPath
  • weather - Demonstrates the use of XPath and Soup to check the weather using the Yahoo API
Native Modules

Seed has several C extension modules, to bind libraries not available from GObject-introspection.

readline, sqlite, GtkBuilder, and sandbox

Documented in the main manual (html pdf)

canvas

A reimplementation of HTML5 canvas, with some Cairo integration. Documented here

os

A module similar (nearly identical) to python's os module. Not yet documented, python os module documentation is useful.

dbus

A module which allows usage of DBus. Not yet documented, but see the dbus-banshee or dbus-consolekit examples.

libxml

A module which allows basic usage of libxml. Not yet documented, or complete, however very similar to the libxml2 python module.

seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/mapping/000077500000000000000000000000001303774616400210265ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/mapping/Makefile.am000066400000000000000000000003741303774616400230660ustar00rootroot00000000000000tutorialdir=$(docdir)/mapping tutorial_DATA = \ mapping.html \ enum-mapping.png EXTRA_DIST = \ mapping.html.in \ enum-mapping.png uninstall-local: rm -rf $(docdir)/mapping ## File created by the gnome-build tools -include $(top_srcdir)/git.mk seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/mapping/enum-mapping.png000066400000000000000000000246341303774616400241420ustar00rootroot00000000000000‰PNG  IHDR$x[ÂÔsBIT|dˆ pHYs 4 4TíÞ´tEXtSoftwarewww.inkscape.org›î< IDATxœíyœÅÙÇ¿5» ¢K<Ú[2lË Í«1Áë}£Æ#‰èà¯&^L‹&€FEÓƒ‰F&ʠѨä0Ñ7¢‘d e QZQ†CäØzÿ¨êÝÞÙ9ö˜eGRßϧ?½[]]]}ýú©§žªRJ ƒ¡ˆôv ƒ!À’Á`¨Œ  †ªÁ’Á`¨Œ  †ªÁ’Á`¨Œ  †ªÁ’Á`¨Œ  †ªÁ’Á`¨Œ  †ªÁ’Á`¨j‹mÈF£‡GCxx­>“i å98°ƒÇòë3™³Ñh $pe}&³¶À±NfÖg2Ó:z2aÏÚøðªkû–É»p1p¯kû tÚÀ%v»Íµý·CeüÜåÚ~c‘ãÜô×ö¥ãYÃsCYrÀ àCàQ×ö?-Sïê:l < <íÚþGyùNö~êÚ~»ë—÷R Ùµý[Kå+±ÿÀW;˜}±kûw:žup°Èµý_—(ûr`Gà:×ö?u<ë›À‰yÙ$ððð˜kû畱=ðÓŽTεýK:xI¤ÒC€›’ñØG¶÷n>KÆc×ؾ30ˆ>ð4ðB2[Ÿ—¯póv—Ààcà‰d<¶8oŸ€ À“ñØ %Îá»ÀÉxì'%ò\žŒÇn*¶]çù°%0%-+–¯ e£Ñ€_¢t€õÀ÷É@&Ž®Ïd‚›|/U‘‹QVÙÅÀêúLæÒÇ?xX\ÖÁ² ñ9p0h#HŽgäÚþ+¡¤tî¥l]¢ü?o‡þÿ6p 08²È>ÿ ¬qm?¡ÿ„°¿r<ëN”xåò7:žµ p0:”| Ï:ǵý{CéÃh=¿¹¡2b(Qø"\4ð÷"uêßë`Þg€;EÀéÀÖŽgý͵ýwò3:ž5˜¼êý(~ýns<ëû®í?JTfŸ0Ý$Ô;t008»Àö>º./m)‘J¸Uß–d`i"•>8}J¯¥ô9¹‰TúÚd<61”¶­Þç°D*="µ›ö#‘JÔu¨ R"•þpu"•¾=­)Q‡qú˜‰yÚ6Ù²ÑhøêBÞº˜€(JÉ£À³Ùht[½ËŨ/VxY¥—üôCJUDà1”²]ŸÉ|Xf—¢¸¶/Q" §k«$ßê¢×-_×öë]Û®í à]`]ð¿^f9ôŽgS¢j…æ{¹e vE ©\ <ŸÙñ¬:”54¸hv.@ ùÝŽg}'´KF¯‡åu3ðÍP¹ýP÷j1]çû´½ï{êôE´&~àÚþjàç¨ëê"å:z]èK|'êÃ3e þ˜ŠzáÿìxÖÑöù=êe/µTŠx"•Ž•ØÞæ™H¤ÒG3PïçÀö(+ø7À`àéD*]_ œÅ´^‡‘Àq(kp%pM"•žR`8©H½.¶)QoPÜZ ˜RÈd<Ö\*C¾…tðu œUŸÉª¸\7·NAYËë3™@|ZÈF£9@Ôg2EͲBd£ÑQ&éV(1ò:³2À~ŽgmëÚþrv°ãY»¸¶ÿNüÛµýR ß\dzþϵý¦òYhrmþ{-pãYÏèúq<ëA×öåšE®kûa+òNdzÞþ<ìxÖÞ®í¿º$dzú¢>꺃²ØJ<º„kû+Âÿ;ž5Pÿ¹ÑµýRÏį€ñÀϺÁµý·BeìŠzð¡>Xù,sm?ú.ðˆãY PÏò…À_óöÙàÚ~¶§T "(,k9&RéÀ¥±ø¯d<|L>fk«e ð[”ø‡ù"…¯Cx<‘Jÿ x ¸ ‘J_•ŒÇòŸËI‰TúÉx¬ÅׂWÒšI¤ÒôG Ü["{‡h±²ÑèV¨&U#pNHŒÂ\\ŸÉ¼]`[—ÉF£QÌîÀyõ™Ì3*ºÝ‹ˆ¤ð” uù%ÌãI`T“¯Ë¸¶ÿ­ÖÂåAºãYý‰¨Áõö{u·Ž×É‹P_á°µx°În^ åߤ¸¶ÿ9Êb«¡½•t1êãy³¶|;ÊýÀgÀÁŽgõ—nžF'RéãËæ„¢,Þé!1 s.Êb?6‘JoÙ‘ƒ'ã±¹(Aˆ² ìE½§ä¥;(ã`e‰¢¿²ÌßI¤Ò{u¤>¥7Ù†£œNÔg2ͪúL¦¹>“YÚ݃†ÉF£uÀQŽ»ŸÕg2ÝVÙ EôC4Qò_ÄJ½„“Q7q¢ãY…ÌêÎp+ÊOs“)æ?è*ùÒ¨¯ÄB”¯Gh‘ÚÊ Òr”å² pMw rm¿ev@5§ ­O¦ Q–ÁA¡´ 0Ôñ¬àÅ<x#ô7(AZj>nR´s} ÊJ ®Ý8Ô=û…kû:SžãY_E5m_+×»ØÃ,~ ìü¨LÞ¡(köÍy‚^±¯—ÈÓB"•î‡ú7¡šèaV£zèöBYg ,ò¾ÀU%ʬE5OÆcC}8ÏÔ͸.SH:åûéÙhôÔEx›Â½Ýe êË4UŽ@½¬¢…6ª™XCe›)·K;žµg™¼åø—^7èõP½.úåÒÍš!jD5{ör”e7¶Ì~% R`·9Él4z@6Íæ-ã(Çõ(Çk¸7Zeòw…F`dzvB5Ùf¢^ÂU¨oêP´„.àÚþÃÀlàdz¾Õ¢èup>ÓëÊìÜÛ ù¤#€ué9`gdz†¡š…½*Hšßï£Äh*.®Kçõòp psm¿Øᯨ&O¡¥ ÿ¦–ó‰Tzïüº—+‹ ‰(E^ç[Qkh½Ï£>: š½ßJÆc«(Nà¿Û˜šŒÇübuðà±d<¶N×})ðàøD*Ýå‰pÏCÐfÝ‘¶í×,­*¸ êaîÛÕ†XSŸÉ\FoAu1NËF£Çéáë*Á‹xªK{–kûÍŽgýÕ »Ø¿5õešêxV~ïFG¡×A0ê½\f¿A¨p‚ —$ìàEk,Ö³À•¨¦sª@\Ûß ƒBo@E[}94¿wm¿]¤s>É Žíq’ñØúD*ýT ”Kûž-Pî‹ý©tßüˆìAgI~$ÿ¿’ñØ Á?‰Tú(«¨o®þüº}¡ã”®¤}Ôw>G£zà>H¤ÒÿJoDùªN¥‹¢¶jHXŸÉ¼UŸÉŒ©ÏdÆÐM'ma¸åÛù6*f¤’]§ç³C¦ÿ³¨ðôÐKèÚþKÀPAjgv±˜}õ:hRíú= äÀñ¬­P¾±Àÿ„kûŸ¡‚-G£˜AçÅK(+$0µ{]4Á×¼TSíKG2{e9 ^ ËÛ¨çàÅÏÄ¿JäDº¸2‘Jç÷®âNÔ0‘r×<ÒËQþ©`ù_Þåf[X‚ñÂl4* eî)ê3™õ¨/ôFàæl4jW°øÀ2°hÛƒø¬^ï@Ͼ„W š[×ÓÉ®gT¸ðžkûstrÐ%R‰ØšÃQþ«§óÒQ×az‰öw½ˆºÙü±_†!8,Ôœ ƒBÖS@`•ð.²}ê];­A íhcò×g2³³Ñè$T·äËÙhôA`*Šû$ÔEZKëƒ]Qê3™æl4z0øq6}º>“ÉÿÊw…F ãÚþƼôçPçÕ&MÇé\JÔ:ž5)”ö”kû³é®í¯p<ë:ÔƒVˆo8žÕŒ²w@}…£üj'èfU¸¼%ŽgýÕUû”ãYÿDÅ%…²œÒÀI:°2LðEͤ9(ŸÍ’ }Óñ¬‡JlßàÚþ=uðd<öv"•¾5€:Ÿ)¨f÷aÀâD*=åÈ>õŒLHÆc3:q¸›P>ÔK©ô­Éxly¹ ¡ã§Ž^*4 ¨HòD*=e!K[áÚÑ^Œ\;D}&sm6ý;ªp,­¦×JÔT“ê3™rq]¦>“y3N@kÝ›F÷­ÏdÊõ²”#ƒzϳÀ»"“·¦­ „ãGV²¸:ÀÀQ_·|ާuÜÙ:”0\ Ü¢ÇxµÃµý¤ãYsP&ò·ôò)jxÅ„"…Qþ¨6CCt¯ã,þ³i0¥ÇëQ#í{’ë(0Ü"­J¤Ò‡ ¦$¹Õk°¸/%;sd<öQ"•¾ Õãv­3't–ß?”É7Víh#H”ž&%'¤,ÞÛFëQ½nÿ®ÏdJ:»Bûô…Gu—ÐNõPñA«ë3™f!ÄOèx¸Á?¤”As,èuÚ˜7ïO°m‡üQèÚSîX X %ÑþšÀâÑM³°£»©3„Ëݳ3¯\ϲ u£k«pmØÓ¢•š¤.Ì?]Û/8ìHOk’ëìÐjAq(Ÿã©YJY.¨°ݬÉx¬àµÑãËP“¸½ßÑr;pÜào* '‘:d¡ÕªÚž ƒÇ다RÈ’‚TM!V£ÿv„륔EÇá:†ãY+hy)ÇM®í_Ñ“õé-„W“7Z 6J){s ï—šÞœ’¡³Œ¢ãs€w©lhÇ×h .GÉév¿äÜrÖv„/ǾJùÒXHƒaóÇüêˆÁ`¨Œ  †ªÁ’Á`¨Œ  †ªÁ’Á`¨Œ  _„; !6ëw¶b''„¨ÄÀ=ƒÁPœQ£m¶TRm¨`Y†M€"Z>—Á°éجÍ?CY*9¨ÁÐmŒ  †ªÁ’Á`¨Œ  †ªÁ’Á`¨Œ  †ªÁ’Á`¨Œ  †ªÁ’Á`¨Œ  †ªÁ’Á`¨Œ  †ªÁ’Á`¨Œ  †ªÁ’Á`¨Œ  †ªÁ’Á`¨Œ  †ªÁ’Á`¨Œ  †ªÁ’Á`¨Œ  †ªÁ’Á`¨Œ  †ªÁ’Á`¨Œ  †ªÁ’Á`¨Œ  †ªÁ’Á`¨Œ  †ªÁ’Á`¨Œ  †ª¡[‚$„ض3郡s!ŽB|¥@úw…¢7êÔ“t×Bš,„Ø%œ „88¾›å ÅÇÀ+aQB\œ*¥”½W­ž¡»‚ô6°@±´ˆÑ#ÀsÝ­˜¡gBÄ…ýòÒú!Îê­:Š#¥œÔÏ}€×éÅjõݤ?9`°p'ðž”ò_Ý­˜¡Ç¨^DIÑõ°ìÍJJ2hŽÆŸOôjzˆn ’”r)ð)0ذ€×º]+COò°0%NÏ îÝfùÅÝL¸Ø ŸJ)Wôn•z†Ú ”ñ*ðU]ÖçÀ´ ”iè!¤” !Þ¾H½¼§?.†êä)”UøkÿÞ‹uéQ*Ñí°JÿýÊü7T7/¢¬£>@_`NïVÇP )eX®ÿ]ü®«Ó£TBþdõßˤ”ë+P¦¡g¹Ö{ö9꽪:ÈL½^ÌëÍŠô$Ý$-@êÿÔÝò ›„—Q6z=«ëbè üHK7Çîþ€JEjÿhFuùª)eð¾þ÷#cÕ~)˜¯×›õ;V)Aú°NJùN…Ê3ô<¡ÚèíŠÊ£­¢—€Çz».=‰¨”õ'„'¥¼»"…z!ÄŽ¨¦ö7öå@±§”rIo×£'©¤ E¤”¹ŠfØ$!fI)¿ÙÛõ0*&H†/Bˆ¥”ÿîíz F CÕ`æC2 Uƒ$ƒÁP5ôŠ ­lh8,.[>ÔÇï,ŽgíãxÖ¯Ï:¸Žýdz²Žg ÝÔÇ6üç19õ|¿ò¹zŽÂƒkG®Í.[v1Bœì ¼…3Gë.ìvØzNʾ,!åÚî–U dz^¹¶_r®dzvA‚¿ÁµýBg×ßFÃ+^ÑÒ ¶Fͪ°Iq<ë9 Ýl…E¸ßµýdOÖ§7ILO¿€¤¯ØÐ|´;nÔòüí—Ý÷ú¾¹\ä>Ï$ÏŒ]–¿Ý™>œ”œ ²AB£@<-šs¹g|7œoüôùÃ…”„ÓH‰X'¤|ä wìÈ6±c‰Túhà†ˆŒŒÿùØ}‹ÎEæLK?,k“ñØØBÛ/»Á’úó ÅÊøñ}¯nÓ7×çYàó­Þ}câD*Ú³ÞÎBúløðáYߟ‡.pB¼ìŒ”× åìlCÃqÅ [ÑÐpH6}-þ¦’•ì[Gç':žua^ÒW´ŽïÊç1ÔÀá?V´vÕO_ _h„ºN{ä¥÷£23GT/’}dŸšI…67! ®Í€pú¥©t}bzúq)å] •à ø:È)²F¼|i*=8œ?"e]N5­Ï` CA$'K!f$¦§ï˜<¹õÝBÝ—œ×«þøÔëÿ#'£æ-+H®)7F"~8yòóEïeÿœ¨ γÒbù‚4ztm$—{hRþô‹þý¿R¿páaõ™ÌàˆkÈåf¬lh8¬`i¹œ ì/„h÷é%Ëñ¬–¯¼ãY»®ãYágˆ^/*TˆkûÓ]Û߯µýkz®ªÕ‡kû»¶¿O°§èMO„ÓõrSoÖu“!8ïÒû_ÖÑì5ˆ‘ ü¥nCóvSã±ëÖoò`G»hÚ¼íò÷“ˆ‡’ñX½^¶š·y4à#9åîó ˆ<ȹoÞ· V[D®+nò;¬Üý+Ëh“UEùWœ6‚´bÙ²ËbB\;¨±ñÆçÌiiRmµpál¤<XÙ¸qA‘Jn “òƒž¨lÈèuø:5íF8 p°–Öñ]C!6"©4GÜŽd¾ìž y.ðêÔxìÄ)ãF­¸õ´W%ã#¯Cð;{Õ‰ÈåÊrÇZîž1ò)rò¿UŠü^¡|RŠkóÓÆOKdÿRå;ÓæEAØBæ 6é6­¦ÙèѵBˆ«%õ N,”¹¾±qûï sæl Ò>>|x$—;@F" ×4bÅðáÿäiâÑíÞxcYG+•6ì›D"C#B¼±Õo¼ÚùÓj¡Q¯‡¡æ%HÁú¯úï!Àb×ö[Tßñ¬½€ÃóÊ›ëÚ~Á1Ïêœ ¬vmÿŽgE€ÿŽEMññ¤kû¯«¨ãY{cP³9¾<ëÚþËåNÐñ¬À¡€ ¼ <—팷§]Û_Z¢¬à‡Àû®í?[îØEʨNÐÿ>âÚ~;?¡ãYÛ'Ÿ¸¶ÿGvêÜgKQ>»]Pó5ÍpmM‰ãZÀwPçÙX¤JíÓi$K¼=~úü£¦ž9âo¥²çjrW5y½,`Q¬Yß|Þ–}jŽùÉ“‰t¤ ”¤EškjöRvÊ"©©«›F$2’Hd¤òiçiD"#7ÔÖµ ¬>ü<¡æ}i¬«©ùÆ 7Þx¯3u)À[(ÕšlûÛO Žgí Ó‡ÐÞô¸ÞoP¾ýÝJÔdZ+ÿAÍ3>Y×#åxÖ®áÌŽgüÕ\åÚþWô>—£^ȯ9Î_P/루ž¿ÀQ¨/á%@¸Y1W¯÷w[”`^ÊÔ-Cqm¿YŸY$[ÐÑðûPZð²Ü ¾…ê”°Q÷k(ðdz¶ äxÖ·PÏÌ»ºÜQ®ƒ“Q–ÒãÚ"«Sã¶b’†]×|õœRy% EÊ²Ž„/H!:Ô{{Ù´‡»!Iß~A´ )?Bþ1~ú¼ïNžLDää$¯ßùp±2Çß;o${ É#Ô=!àS ½Òlki²‰\n È\îãΰåüù£~;Šl4ªæÕ‘2]ÿÆéΔ³2½\¯P[{ô€ º=‰¹kûÏZB« zpp<ëq`òɵýUè©yÏò;qX 5MÄÉ®í7é´IŽg A5‡b´õUý5—Ô÷\ÛÏècÜìxÖp”åÐdzNA‰ÏSÀwCMÍg´À½ œïxÖ4×ö碬¨f`T¨˜o ¾¢ß®Òi»éu—Is08Ûñ¬ë\ÛoiŠ8žU‡ºKŠ4×ǹ¶¿Zÿÿ†ãY'³Q–ÞA}Ϫ~…ê=ÖµýCåÌÐ͸ÛPâtg7Ï©…\mÓÕ‘¦š1yíEÌþý­§¸*?Ïe÷/Ø¢ä”<ñ)@ÑF4…ƒ.M¥c-ÿÙUÛÁ@‚(ØÁRWW;uÃ†æ ‘bòÊÝÒ[ Á08J‚L©CDDÆH!›rÍ}þ4ñ¤è†D*ý€9Ó_åž¹ßÜ"»õ-RNˆ¡‘Hä‹69öß¿.ÛÐ /Ÿî½÷ÎEÊë „hwƒJ±"½IÂ`溺º#¶®€…hvÓ½jG ¬—Y¨ôHÊô°u7$F¿!ßJ‰ÿˆQ—)ÿ'z}YØïàÚþg(+#œ®ÓÖ¢Î/Ü|9T¯÷u<+¢Š’kû¡,·]ü›ÿ¶BY5a‚óø¿å5¡„Ú†qÄPÖá_òÄ( ¼=±S'P†[Nõ‘òf`ûº} 7«eÓ’Òï‚TþE@ÌÛplæ‹ ÷0 @HÆ%ÇŽ(ø3H7žj¯~ ‚;„`¦=SìøD."€3§žýL§M2²É­¤AŠHù @N+œá³-r¹yᥦ¶öŠü‚4ÖG"«‹lo‹5+†¿KÀ¤üxÍêÕÇYóçÞµS)J#Êœ¿3µõ3%PCP/Û:^õ5Ï'pîîJkÐëbÇþÚ::ÏꋲøV¹¶¿°È~ÿÔë}Bis½Ï üCúïcôzW`…kûÝõݲüÆå¥Ÿ†ºÞÓ‹ìWln¦ gwoí „VŸØ¶ŽgMÊ_€ Þl§ÎU½<Ÿ¯Ï¹À‡ .¹ìþ{äooÞØïÜ­ÝÎa„Ü 'ó„K0¸¸TÂMÀêæ¦Ú!îØØoKY·¡ùÔÔÄ[@®Ø» À¥©‡É.R¶ÎDéÆc¯¡>J§^tÛ’¾%ë_aZIê—BÀŽá a…â|)ÄùRÊ¢NL×»ý IDATVM€¦~ý:j!Rž‹”#Äö,Ø»×MÇöY(ŸDÐ{ô,êA=xϵý/ ìÛVh?J>v„Îþ‚Qغ©³2/yoTS»”ím½þj(mê~tùÖj·¹kܨµRŠ«€¾¹æ\»,mm¬ TÏ­M5¡›nRŠÆd<ö‹d<ö‹©ñØÏ‘ò>``MmSÙ¡)ãF­È›‘Ü_®É%Dî½>0‘š7%X¬Õnõy©ŽœŠÓâCб8'%Hù_¨^ ´Åòk€ÏFŒØElÜxC‰òúwòø5qvssóË555¯ ¸|ÅðáÞ … óÍùîÒ©ÀíŸõÂüÕ+ó ¯3–H»/,´ô ÈKþL¯-г•^‡òàÁ¥ËüÕø$pŽãYýQRE~èÓµ}éxÖ]@8Õ1p"ê)õÛ};JÔau¨‰îƒÀÛàÃw¡kû›ü÷·~oÄôU»§/NŠ4‹Wyo±Ý‘Ù2ß ¥ê´H¯Ô±¤¬½^DšÏ@2qòŒÌƒOŠn(•ßœR®þ“'?_Ëîõß±ŽÖP }@u6B2–M8w«©OŸÅ¨›}ú' ŠÐ`àÊ•ù/Q1~_¿pá´m/^„rÞʈ”¿]ÕÐP°{·‹,B}}· õ§d@Å%­×é•ôu† Ô`ï"Û·G_Ó×ö?@‰ÒvÚUˆ )¶vÂŽíCç]Û߈ŠÅê‡j¾VÒBõóJëPÎíª¹¶†ÂCp iÇÛ@õ²õG9à 4¨k%Ÿ—3q"9)¥€héhEŠùHjûõßP°7î¼»çÖ¡ÂP>NÆc%oêXûm% ^µvùݮ<°z·A‡ÛIÉõÉxl‡¼Å±äQãï›_Ìg\qZ©~Þ¼¬Tΰ¾µ¹Ü%],o @Smm´\F¤l‰iªÏd~&¡_.—ûóòh´ØƒÙ)\ÛÿœÖæÍÌPú:Toôž ½ƒ—CÏY`{¼È~ƒ¼˜Ó;J ‚AÃŽí@Gçó(ki j m1¿T§ÑöGP~³3P¢÷ˆ¾'Å(h-ß×ëWBisÀñááA›’©cGÎD‰úÖùÛdsóTý.þÑ™-ó·oÙ'2ò‰R¡-åÉÚë4!¹rüŒ—·ènÝ¥c"¢©`ì¡r‰äd±ðŠÓfèHs.÷3à#Nvذ‰Ѳ}UCÞ5MM?*Sžš @ˆ+—î±G?F®ÍF£'f£ÑÇW54”}`ê'¢š;×ÀŸÙk¯¢5!ÄyBˆ„eÃîQͶ ´ošþ¤ü ÈM‚î=ºåt¿'ÔÛ…ãY‡ëm…üP½39žÕæaq<ë”_l>¡¦·f.ʯtZ´ïìï´CVÒB‚Öîö_¡üg©"ù‚òdz.op<ëT,×z €kûÿFÅ[íüN¤†÷‹:žõH(Þ¬BˆÿB¼#„xD„ž÷Î ¤¼ e}¶aêÙû-‘p0x‹þ^˜0}îP€Ëî_0 ‘š?ÄxKĆ\±KÛòZ­¤#k·È Þ)´³úD ãÆGü 7×4ß4çŠ+N›Q½Û.Z´zÕðá'æ¤|!&e‡ G4:å[ºŒß$—+8ê]ærw‰HäTàÈú-¶ø$»lÙZ„ØhnÎå¢u¨Fa¤”rèÐÓDß¾¯ 80[Www}ñຫPAp„7J)K9Ò- cxø,$dzơáÐꯉ;ž =™äÚþÓ%ϧc܃o Ïze% Eãé(çmËËâÚþûŽgE NJ‹P#*ðs8ê×DÆp®ÏAY*º¶ßJÿ+ª;}•~É+†kû¯8ž•FuÑ/qmÿ…2»<ÜäxÖ¥À«Àž¨¨ùfÀqm?ß™ÞþmàmdzCù˜Pã—£,´b=‡— ®÷ÀTÚZ`Â;2“HÍû-ˆóò·5Õ­¿¦nCßݤàÄfY³$‘J¿b'ý,—M¹o' LgRŒÀ—$%—_ôÀì_Šê}®ù¶„­…¿,–ç–ÓG}”˜ž~JHŽuîˆ{Öˆ ÷ {'R鱆rQ2>rLgëÕî‹°ÕÂ…³××ÕBL>êFï(à))Äùõ–5¼¾±ñùB… Z´èE)ÄwPM!‰>pO.ÙwP&Ó"F2—ËJ˜h46èí·Wæ"‘„‹€‘+†/Ö«p;ª‰xo1õ">Z$}®Ž›É§ åÿX‡ ¦œ, ¥å¿ìM:O±z¹ÞÞ¦‹_ûqCYCN¼œíÚþõ(ÑœE^‡kû3P/ù#¨èóStž»ÛµýBóV½ˆ IÈw?©ÓËýòðj¯³?Å“Òëb]ýaf¢š”(Ko_T½wmÿŽüÌ®íáÚþ(ÇùÔózjª”»€®í øÕö<­ŽÿvHÕ^Ôá©©¹xQʶa ·žvàªäØØwQáÿ,\„äúææÈ!SÏÞ/ïZ6¯f ))€²’Ä€×gCŸ£È‰åfˈ,Ô,™-¥j’ç¤h0rE#¸Õ.â6`‘ÜH€¦æ$Ì–°@ºâK¤¤Ó½å'ùBP¥¿°9þô’ãY"?رƒûõ/4µp<ëa”h°kûgTp<먮ú³‚3=Ø7¢E»3ÇëÔ5ÜŸ£/+å'ÕªR1Ø¢®ˆ‘Þ¯*ÄH‡*líÚ~VÿjèÆŒbbT Ýä,ÓUn¿N]ÃÍñ9ú²²yÏògè NÆ:ž•D5½.@õ4• ª­ÚŸaÓaÉPiöBÍcÌ*ê£oÖ?m¨ æ‡" GO6>敉; öÙ úžŽ_2übÉ`0T æ‡" CÕ`É`0T F CÕ`É`0T F CÕðÿ1Â#Ø®ÖpIEND®B`‚seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/mapping/mapping.html.in000066400000000000000000000207231303774616400237600ustar00rootroot00000000000000 Seed C Mapping Conventions
v.@VERSION@
Enums and Flags

The mapping of enum types to JavaScript is straightforward.

In this example, Gtk is the namespace, WindowType is the enum class, and NORMAL is the enum member. Note that the enum member is always UPPERCASE, and the enum class is CasedLikeTypes. It is worth noting that this is the same convention as Vala. When passing enums in to functions, the enum will be checked (to ensure it is in fact a value of the required enum class). This is not true for fields.

Toplevel Functions

Toplevel library functions are mapped exactly as you would expect, with gtk_main mapping to Gtk.main.

Constants
Constants are placed directly on the namespace, with the same casing as present in the C library.
Clutter.COGL_FIXED_0_5
Clutter.Alt_L
Objects

Objects are given a constructor on the namespace. ClutterTexture having a constructor at Clutter.Texture

Constructors

Object constructors, accept as their only argument, a JavaScript object pairing GObject properties, with values. As an example,

w = new Gtk.Window({title: "Hello"});
c = new Clutter.Texture({width: 300, height:300});
All other properties are left to their default values. Note, Gtk.Window.prototype is the prototype of all Gtk.Window instances. It is also possible for objects to have "named" constructors which take specific arguments, i.e. for clutter_texture_new_from_file we have
t = new Clutter.Texture.from_file("/tmp/cat.png");
In addition gtk_window_new maps to Gtk.Window.c_new (because new is a JavaScript keyword). This however is rarely used.

Methods & Static Methods

Non static methods (or "instance" methods) are accessible from the object, as you would expect.

w = new Gtk.Window();
w.resize(300, 300);
Static methods are accessible from the constructor, so for clutter_stage_get_default.
c = Clutter.Stage.get_default();
The type conversion, is fairly sophisticated, so where C methods expect non-basic types, like function pointers, GLists, or C arrays, you are able to just pass in JavaScript functions and arrays.
w = new Gtk.Window();
w.add (new Gtk.VBox());
w.foreach(function (widget) {
              print(widget);
         });

children = w.get_children();
for (i in children) {
    print(children[i]);
}

Properties

When attempting to set a property on an object, the following things happen in order.

  • If the property name corresponds to a GObject property name, then the JavaScript value is converted to a GValue and set as the property.
  • If the property name corresponds to a member of the objects struct (i.e. the GtkWindow struct), the JavaScript value is set inside the struct.
  • The property name is set on the JavaScript object.
and vice versa for reading properties. One thing which may be surprising to developers used to other scripting languages (say, python) is that an attempt to access an unset property will just return null, instead of throwing an exception. So, accessing for example actor.witdh will return null and it is up to you to catch your typo.

Signals

Interaction with an objects signals, takes place through the object.signals property. For example

w.signal.map.connect(function(window) {print ("Hello world");});
foo.signal.bar.emit(3, 7, "Baz");
In addition you can use user_data, similar to C
w.signal.map.connect(function(window, user_data) {print(user_data)},  "Hello world");
In many cases this is made useless by JavaScript's support for closures. Note, in many cases, it is useful to access signals with details, for example notify::x however as this is not a valid JavaScript identifier, you have to use the array syntax for accessing properties,
w.signal["notify::x"].connect(function(){print("x changed")});
Sometimes, it may be desirable to check that the functions you are connecting to signals, have the correct arity (accept the proper number of argmuents), and if you compile Seed with debugging enabled, and pass --seed-debug=signal or --seed-debug=all, Seed will give warnings when connections of improper arity are made (however clearly this is only sometimes a bug).

Structs and Unions

Structs and Union's are given a constructor on the namespace. GdkEventKey simply having a constructor at Gdk.EventKey.

Constructors

Struct and Union constructors, accept as their only argument, a pair of initialization parameters, in a similar fashion to object constructors. As an example,

c = new Clutter.Color({red: 0xff, alpha: 0xff});
All other fields are "zeroed" in the C sense that the memory is allocated with g_slice_alloc0. Like objects Clutter.Color.prototype is the prototype of all ClutterColor instances. Again like objects, structs can have "named" constructors which take specific arguments, i.e. for soup_date_new_from_now
d = new Soup.Date.from_now(0)
Once again soup_date_new would map to Soup.Date.c_new.

Methods & Static Methods

Non static methods are directly accessible from the object, i.e.

c = new Clutter.Color({red: 0xff, alpha: 0xff});
c.from_string("purple");

TODO: Static methods
Implicit creation

Anywhere where a struct is expected, (property assignment, or a method call), a JavaScript object describing the struct can be used.

stage.color = {red: 0xff, blue: 0xcc, alpha: 0xff};
The semantics are identical to constructors, in that uninitialized fields will be zeroed.

seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/modules/000077500000000000000000000000001303774616400210435ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/modules/Makefile.am000066400000000000000000000014211303774616400230750ustar00rootroot00000000000000SUBDIRS=canvas multiprocessing readline sandbox sqlite gtkbuilder EXTRA_DIST=make-functions.js book.xml version.xml.in if ENABLE_GTK_DOC html/index.html: version.xml book.xml sqlite/sqlite.xml sqlite/sqlite-funcs.xml readline/readline.xml readline/readline-funcs.xml make-functions.js gtkbuilder/gtkbuilder-funcs.xml gtkbuilder/gtkbuilder.xml sandbox/sandbox.xml sandbox/sandbox-funcs.xml mkdir -p html; cd html && gtkdoc-mkhtml --path="$(abs_top_builddir)/doc/modules" "Seed" $(abs_top_srcdir)/doc/modules/book.xml; bookdir = $(docdir)/modules/html book_DATA = html/index.html install-data-local: cp -r html $(DESTDIR)$(docdir)/modules CLEANFILES = \ html/* \ html.stamp \ $(NULL) endif uninstall-local: rm -rf $(DESTDIR)$(docdir)/modules -include $(top_srcdir)/git.mk seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/modules/book.xml000066400000000000000000000014651303774616400225250ustar00rootroot00000000000000 ]> Seed Modules Reference Manual Documentation for Seed &version; modules. The latest version of this documentation can be found on-line at http://library.gnome.org/devel/seed/unstable/. seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/modules/canvas/000077500000000000000000000000001303774616400223165ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/modules/canvas/Makefile.am000066400000000000000000000001731303774616400243530ustar00rootroot00000000000000modulesdir = $(docdir)/modules modules_DATA = \ canvas.html EXTRA_DIST = \ canvas.html.in -include $(top_srcdir)/git.mk seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/modules/canvas/canvas.html.in000066400000000000000000000037211303774616400250670ustar00rootroot00000000000000 Seed canvas Module Documentation
v.@VERSION@
Usage

In order to use functions from the canvas module, you must first import it:

canvas = imports.canvas;
External Documentation

The canvas module is actually an implementation of a subset of the HTML Canvas element. Many of the functions from Canvas directly translate into Seed, and you can use any Canvas documentation to help develop Seed canvas code. The drawing functions will not be redocumented here.

new CairoCanvas(cairo)
new PDFCanvas(filename, width, height)
new SVGCanvas(filename, width, height)
new ImageCanvas(filename, width, height)

Construct a Canvas with a particular output format. CairoCanvases are constructed given a cairo to draw to, while the others output to a file, and need to be given a size for the canvas.

seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/modules/gtkbuilder/000077500000000000000000000000001303774616400231775ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/modules/gtkbuilder/Makefile.am000066400000000000000000000011521303774616400252320ustar00rootroot00000000000000EXTRA_DIST = \ gtkbuilder.js \ example.ui \ example.js \ gtkbuilder.xml gtkbuilder-funcs.xml: $(top_builddir)/src/seed $(top_srcdir)/doc/modules/gtkbuilder/gtkbuilder.js $(top_srcdir)/doc/modules/gtkbuilder/example.ui $(top_srcdir)/doc/modules/gtkbuilder/example.js $(top_builddir)/src/seed $(top_srcdir)/doc/modules/make-functions.js $(top_srcdir)/doc/modules/gtkbuilder/gtkbuilder.js > $(top_builddir)/doc/modules/gtkbuilder/gtkbuilder-funcs.xml CLEANFILES=gtkbuilder-funcs.xml gtkbuilderdocsdir = \ $(docdir)/modules/gtkbuilder/html gtkbuilderdocs_DATA = gtkbuilder-funcs.xml -include $(top_srcdir)/git.mk seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/modules/gtkbuilder/example.js000077500000000000000000000005651303774616400252010ustar00rootroot00000000000000 #!/usr/local/bin/seed Gtk = imports.gi.Gtk; GtkBuilder = imports.gtkbuilder; handlers = { ok_button_clicked: function(button){ Seed.quit(); } }; Gtk.init(Seed.argv); b = new Gtk.Builder(); b.add_from_file("test.ui"); b.connect_signals(handlers); d = b.get_object("dialog1"); d.show_all(); Gtk.main(); seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/modules/gtkbuilder/example.ui000066400000000000000000000016611303774616400251750ustar00rootroot00000000000000 <interface> <object class="GtkDialog" id="dialog1"> <child internal-child="vbox"> <object class="GtkVBox" id="vbox1"> <property name="border-width">10</property> <child internal-child="action_area"> <object class="GtkHButtonBox" id="hbuttonbox1"> <property name="border-width">20</property> <child> <object class="GtkButton" id="ok_button"> <property name="label">gtk-ok</property> <property name="use-stock">TRUE</property> <signal name="clicked" handler="ok_button_clicked"/> </object> </child> </object> </child> </object> </child> </object> </interface> seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/modules/gtkbuilder/gtkbuilder.js000066400000000000000000000010551303774616400256720ustar00rootroot00000000000000funcs = [{id: "gtkbuilder-connect-signals", title: "builder.connect_signals (object, user_data)", description: "Connects the signals present in the GtkBuilder to the functions present in object. That is to say, a signal with handler name, 'ok_button_clicked' will be connected to the 'ok_button_clicked' property of object.", params: [ {name: "object", description: "The object containing the signal handlers"}, {name: "user_data", description: "The user_data to use in connecting the signals"} ] }] seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/modules/gtkbuilder/gtkbuilder.xml000066400000000000000000000022611303774616400260560ustar00rootroot00000000000000 Robert Carr
racarr@gnome.org
GtkBuilder API Reference The GtkBuilder extends Gtk.GtkBuilder.prototype to implement a custom automatic signal connection function, which is useful in Seed. It does not provide any methods or types, so there is no need to save it's namespace, as of such it can be imported as follows. imports.gtkbuilder; Examples Below are several examples of using the Seed GtkBuilder module. For additional resources, consult the examples/ folder of the Seed source
seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/modules/make-functions.js000077500000000000000000000020611303774616400243260ustar00rootroot00000000000000#!/usr/bin/env seed Seed.include(Seed.argv[2]); function output_param (param){ print("" + param.name + "" + "" + param.descripton + ""); } function output_function (func){ var start = print("" + "" + func.title + "" + "" + func.description + ""); if (func.params || func.returns) print(""); if (func.params != null){ for (var i = 0; i < func.params.length; i++){ output_param (func.params[i]); } } if (func.returns != null){ print("Returns" + "" + func.returns + ""); } if (func.params || func.returns) print(""); print(""); } print(""); for (var i = 0; i < funcs.length; i++) { output_function (funcs[i]); } print(""); seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/modules/multiprocessing/000077500000000000000000000000001303774616400242725ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/modules/multiprocessing/Makefile.am000066400000000000000000000002151303774616400263240ustar00rootroot00000000000000modulesdir = $(docdir)/modules modules_DATA = \ multiprocessing.html EXTRA_DIST = \ multiprocessing.html.in -include $(top_srcdir)/git.mk seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/modules/multiprocessing/multiprocessing.html.in000066400000000000000000000016671303774616400310260ustar00rootroot00000000000000 Seed multiprocessing Module Documentation
v.@VERSION@
Usage

In order to use functions from the multiprocessing module, you must first import it:

multiprocessing = imports.multiprocessing;
seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/modules/readline/000077500000000000000000000000001303774616400226265ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/modules/readline/Makefile.am000066400000000000000000000011231303774616400246570ustar00rootroot00000000000000EXTRA_DIST = \ readline.js readline.xml readline-funcs.xml: $(top_builddir)/src/seed $(top_srcdir)/doc/modules/readline/readline.js $(top_builddir)/src/seed $(top_srcdir)/doc/modules/make-functions.js $(top_srcdir)/doc/modules/readline/readline.js > $(top_builddir)/doc/modules/readline/readline-funcs.xml CLEANFILES=readline-funcs.xml readlinedocsdir = \ $(docdir)/modules/readline/html readlinedocs_DATA = readline-funcs.xml #index.html: readline-funcs.xml # gtkdoc-mkhtml "readline" readline.xml; # mv *.html *.css *.png html #readlinedocs_DATA = html/* -include $(top_srcdir)/git.mk seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/modules/readline/readline.js000066400000000000000000000026321303774616400247520ustar00rootroot00000000000000funcs = [{id: "readline-readline", title: "readline.readline (prompt)", description: "Prompts for one line of input on standard input using prompt as the prompt.", params: [ {name: "prompt", description: "A string to use as the readline prompt"} ], returns: "A string entered on standard input."}, {id: "readline-bind", title: "readline.bind (key, function)", description: "Binds key to function causing the function to be invokved whenever key is pressed", params: [ {name: "key", description: "A string specifying the key to bind"}, {name: "function", description: "The function to invoke when key is pressed"} ]}, {id: "readline-done", title: "readline.done ()", description: "Indicates that readline should finish the current line, and return from readline.readline. Can be used in callbacks to implement features like multiline editing"}, {id: "readline-buffer", title: "readline.buffer()", description: "Retrieve the current readline buffer", returns: "The current readline buffer"}, {id: "readline-insert", title: "readline.insert (string)", description: "Inserts string in to the current readline buffer", params: [ {name: "string", description: "The string to insert"} ]}]; seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/modules/readline/readline.xml000066400000000000000000000024561303774616400251420ustar00rootroot00000000000000 Robert Carr
racarr@gnome.org
readline API Reference The readline module allows for basic usage of the GNU readline library, in Seed. More advanced features may be added a a later time. In order to use the readline module it must be first imported. readline = imports.readline; Examples Below are several examples of using the Seed readline module. For additional resources, consult the examples/ folder of the Seed source This demonstrates a simple REPL using the readline module readline = imports.readline; while (1){ try{ eval(readline.readline("> ")); } catch(e) { print(e.name + " " + e.message); } }
seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/modules/sandbox/000077500000000000000000000000001303774616400225015ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/modules/sandbox/Makefile.am000066400000000000000000000007021303774616400245340ustar00rootroot00000000000000EXTRA_DIST = \ sandbox.js sandbox.xml sandbox-funcs.xml: $(top_builddir)/src/seed $(top_srcdir)/doc/modules/sandbox/sandbox.js $(top_builddir)/src/seed $(top_srcdir)/doc/modules/make-functions.js $(top_srcdir)/doc/modules/sandbox/sandbox.js > $(top_builddir)/doc/modules/sandbox/sandbox-funcs.xml CLEANFILES=sandbox-funcs.xml sandboxdocsdir = \ $(docdir)/modules/sandbox/html sandboxdocs_DATA = sandbox-funcs.xml -include $(top_srcdir)/git.mk seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/modules/sandbox/sandbox.js000066400000000000000000000022741303774616400245020ustar00rootroot00000000000000funcs = [{id: "sandbox-context", title: "new sandbox.Context()", description: "Creates a new sandbox context object, which wraps a Seed JavaScript context with it's own global object. By default this global object contains only default JSCore globals (Array, Object, etc...) and has no ability to interact with the outside system. Note the context must be manually destroyed with the destroy method."}, {id: "sandbox-eval", title: "context.eval(source)", description: "Evaluates a string source with context, returns the result.", params: [ {name: "source", description: "The code to evaluate"} ]}, {id: "sandbox-addglobals", title: "context.add_globals()", description: "Adds the default Seed globals to the context, including the 'Seed' global object, and the imports object."}, {id: "sandbox-destroy", title: "context.destroy()", description: "Destroys the internal context object, and any further usage of the wrapper is an exception"}, {id: "sandbox-global", title: "context.global", description: "A project, representing the literal global object of the context, may be freely read from and assigned to"}] seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/modules/sandbox/sandbox.xml000066400000000000000000000023721303774616400246650ustar00rootroot00000000000000 Robert Carr
racarr@gnome.org
Sandbox API Reference The sandbox module allows the creation of isolated JSCore contexts with individual global objects. It is useful as a literal "sandbox" or in a variety of other contexts. sandbox = imports.sandbox; Examples Below are several examples of using the Seed Sandbox module. For additional resources, consult the examples/ folder of the Seed source sandbox = imports.sandbox; ctx = new sandbox.Context(); ctx.eval("b = 2+2"); print(ctx.global.b); //4 ctx.global.b = new Gtk.Window(); // Possible to expose objects to the context. ctx.eval("b.show()");
seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/modules/sqlite/000077500000000000000000000000001303774616400223445ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/modules/sqlite/Makefile.am000066400000000000000000000010571303774616400244030ustar00rootroot00000000000000EXTRA_DIST = \ sqlite.js sqlite.xml sqlite-funcs.xml: $(top_builddir)/src/seed $(top_srcdir)/doc/modules/sqlite/sqlite.js $(top_builddir)/src/seed $(top_srcdir)/doc/modules/make-functions.js $(top_srcdir)/doc/modules/sqlite/sqlite.js > $(top_builddir)/doc/modules/sqlite/sqlite-funcs.xml CLEANFILES=sqlite-funcs.xml sqlitedocsdir = \ $(docdir)/modules/sqlite/html sqlitedocs_DATA = sqlite-funcs.xml #index.html: sqlite-funcs.xml # gtkdoc-mkhtml "sqlite" sqlite.xml; # mv *.html *.css *.png html #sqlitedocs_DATA = html/* -include $(top_srcdir)/git.mk seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/modules/sqlite/sqlite.js000066400000000000000000000024561303774616400242120ustar00rootroot00000000000000funcs = [{id: "sqlite-database", title: "new sqlite.Database(filename)", description: "Constructs a new sqlite.Database", params: [ {name: "filename", description: "The SQLite database to be opened (or constructed if it does not exist"} ], returns: "A new sqlite.Database object, the status property will be one of the SQLite status enums" }, {id: "sqlite-exec", title:"database.exec(command, callback)", description: "Executes the SQLite command on the given database. If callback is defined, it is called with each table entry from the given command, with a single argument. The argument has properties for each value in the returned table entry.Keep in mind that, just like in C, it is necessary to sanitize user input in your SQL before passing it to the database.", params: [ {name: "command", description: "The SQLite command to evaluate"}, {name: "callback", description: "The callback to invoke, should expect one argument and return nothing. optional"} ], returns: "An SQLite status enum representing the result of the operation"}, {id: "sqlite-close", title: "database.close()", description: "Closes an SQLite database and syncs"}]; seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/modules/sqlite/sqlite.xml000066400000000000000000000037051303774616400243740ustar00rootroot00000000000000 Robert Carr
racarr@gnome.org
SQLite API Reference The sqlite module allows for manipulation and querying of sqlite databases. sqlite = imports.sqlite; The SQLite module provides a selection of status enums, to be used as the return values of functions. For meanings, consult the SQLite C documentation. sqlite.[OK, ERROR, INTERNAL, PERM ABORT, BUSY, LOCKED, NOMEM, READONLY, INTERRUPT, CORRUPT, NOTFOUND, FULL, CANTOPEN, PROTOCOL, EMPTY, SCHEMA, TOOBIG, CONSTRAINT, MISMATCH, MISUSE, NOLFS, AUTH, FORMAT, RANGE, NOTADB, ROW, DONE] Examples Below are several examples of using the Seed sqlite module. For additional resources, consult the examples/ folder of the Seed source This demonstrates creating a new table, populating it, and querying it for results sqlite = imports.sqlite; var db = new sqlite.Database("people.db"); db.exec("create table people (key INTEGER PRIMARY KEY, name TEXT," + "age INTEGER, phone TEXT);"); db.exec("insert into people(name, age, phone) " + "values('John Smith', 24, '555-123-4567');"); function cb_print_phone(results) { print(results.phone); } db.exec("select * from people where name='John Smith';", cb_print_phone); db.close();
seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/modules/version.xml.in000066400000000000000000000000121303774616400236500ustar00rootroot00000000000000@VERSION@ seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/reference/000077500000000000000000000000001303774616400213315ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/reference/Makefile.am000066400000000000000000000073631303774616400233760ustar00rootroot00000000000000## Process this file with automake to produce Makefile.in # We require automake 1.6 at least. AUTOMAKE_OPTIONS = 1.6 # This is a blank Makefile.am for using gtk-doc. # Copy this to your project's API docs directory and modify the variables to # suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples # of using the various options. # The name of the module, e.g. 'glib'. DOC_MODULE=seed # The top-level SGML file. You can change this if you want to. DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.sgml # The directory containing the source code. Relative to $(srcdir). # gtk-doc will search all .c & .h files beneath here for inline comments # documenting the functions and macros. # e.g. DOC_SOURCE_DIR=../../../gtk DOC_SOURCE_DIR=../../libseed # Extra options to pass to gtkdoc-scangobj. Not normally needed. SCANGOBJ_OPTIONS= # Extra options to supply to gtkdoc-scan. # e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED" SCAN_OPTIONS= # Extra options to supply to gtkdoc-mkdb. # e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml MKDB_OPTIONS=--sgml-mode --output-format=xml --name-space=seed # Extra options to supply to gtkdoc-mktmpl # e.g. MKTMPL_OPTIONS=--only-section-tmpl MKTMPL_OPTIONS= # Extra options to supply to gtkdoc-fixref. Not normally needed. # e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html FIXXREF_OPTIONS= extra_paths = \ $(abs_builddir) \ $(abs_top_srcdir)/doc/modules/readline \ $(abs_top_builddir)/doc/modules/readline \ $(abs_top_srcdir)/doc/modules/sqlite \ $(abs_top_builddir)/doc/modules/sqlite \ $(abs_top_srcdir)/doc/modules/gtkbuilder \ $(abs_top_builddir)/doc/modules/gtkbuilder \ $(abs_top_srcdir)/doc/modules/sandbox \ $(abs_top_builddir)/doc/modules/sandbox \ $(NULL) space = $(NULL) $(NULL) # Add the builddirs to the HTML path so that built files are found MKHTML_OPTIONS=--path=$(subst $(space),:,$(extra_paths)) # Used for dependencies. The docs will be rebuilt if any of these change. # e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h # e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c HFILE_GLOB=$(top_srcdir)/libseed/*.h CFILE_GLOB=$(top_srcdir)/libseed/*.c # Header files to ignore when scanning. # e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h IGNORE_HFILES=seed-builtins.h seed-closure.h seed-engine.h seed-exceptions.h seed-gtype.h seed-private.h seed-signals.h seed-structs.h seed-types.h seed-importer.h seed-debug.h seed-path.h # Images to copy into HTML directory. # e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png HTML_IMAGES= # Extra SGML files that are included by $(DOC_MAIN_SGML_FILE). # e.g. content_files=running.sgml building.sgml changes-2.0.sgml content_files=seed-docs.sgml seed-sections.txt building.sgml introduction.sgml contact.sgml imports.sgml version.xml # SGML files where gtk-doc abbrevations (#GtkWidget) are expanded # These files must be listed here *and* in content_files # e.g. expand_content_files=running.sgml expand_content_files= # CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library. # Only needed if you are using gtkdoc-scangobj to dynamically query widget # signals and properties. # e.g. INCLUDES=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS) # e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib) INCLUDES= GTKDOC_LIBS= # This includes the standard gtk-doc make rules, copied by gtkdocize. include $(top_srcdir)/gtk-doc.make # Other files to distribute # e.g. EXTRA_DIST += version.xml.in EXTRA_DIST += version.xml.in # Files not to distribute # for --rebuild-types in $(SCAN_OPTIONS), e.g. $(DOC_MODULE).types # for --rebuild-sections in $(SCAN_OPTIONS) e.g. $(DOC_MODULE)-sections.txt #DISTCLEANFILES += # Comment this out if you want your docs-status tested during 'make check' #TESTS = $(GTKDOC_CHECK) -include $(top_srcdir)/git.mk seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/reference/building.sgml000066400000000000000000000276171303774616400240270ustar00rootroot00000000000000 Compiling Seed 3 SEED Library Compiling Seed How to compile Seed itself Building the Library on UNIX On UNIX, Seed uses the standard GNU build system, using autoconf for package configuration and resolving portability issues, automake for building makefiles that comply with the GNU Coding Standards, and libtool for building shared libraries on multiple platforms. The normal sequence for compiling and installing Seed is thus: ./configure make make install The standard options provided by GNU autoconf may be passed to the configure script. Please see the autoconf documentation or run ./configure --help for information about the standard options. Dependencies Before you can compile Seed, you need to have various external libraries installed on your system. The gobject-introspection library is necessary to build Seed. It provides the bridge between Seed and many GObject-based libraries. WebKit provides the JavaScriptCore interpreter, which is fundamental to Seed's ability to execute JavaScript. Seed requires a WebKit SVN revision newer than 35442. Keep in mind that some builds between this and HEAD still won't work with Seed, and performance has only improved, so try to keep an up-to-date version of WebKit if you're planning on working with Seed. readline is used by the Seed REPL in order to communicate with the user. libffi provides Seed with an interface to call into C libraries at runtime. gnome-js-common includes a battery of tests against both Seed and GJS, and also provides numerous libraries of JavaScript functions, including JSON manipulation and various language extensions. Module Dependencies Seed ships with a number of native modules which provide access to libraries which help with development but are not able to be introspected. Some of these modules depend on external libraries, and Seed's configuration will fail if they are not installed; if you wish to build Seed without a module for which you do not have the underlying library installed, check the Extra Configuration Options section of this document. Cairo provides access to fast 2D graphics and numerous different types of output, including drawing to the screen, to an image, to a PDF, etc. DBus enables Seed to manipulate the various message busses, and provides communication between applications. gettext is a common library used for internationalization support. libxml2 provides a powerful XML parsing interface. mpfr provides multiple-precision arithmetic. sqlite3 provides straightforward read-write access to on-disk SQL databases. Optional Dependencies Seed's library of examples utilizes many other GObject projects which Seed does not strictly depend on, and will not be enumerated here. Introspection data for these projects may either be found within the projects themselves, or in the gir-repository. Extra Configuration Options In addition to the normal options, the configure script in the Seed library supports these additional arguments: <systemitem>--disable-canvas-module</systemitem> and <systemitem>--enable-canvas-module</systemitem> By default, and with --enable-canvas-module as well, Seed attempts to build the Canvas native module. <systemitem>--disable-readline-module</systemitem> and <systemitem>--enable-readline-module</systemitem> By default, and with --enable-readline-module as well, Seed attempts to build the readline native module. <systemitem>--disable-multiprocessing-module</systemitem> and <systemitem>--enable-multiprocessing-module</systemitem> By default, and with --enable-multiprocessing-module as well, Seed attempts to build the multiprocessing native module. <systemitem>--disable-sqlite-module</systemitem> and <systemitem>--enable-sqlite-module</systemitem> By default, and with --enable-sqlite-module as well, Seed attempts to build the SQLite native module. <systemitem>--disable-example-module</systemitem> and <systemitem>--enable-example-module</systemitem> By default, and with --enable-example-module as well, Seed attempts to build the example native module. <systemitem>--disable-dbus-module</systemitem> and <systemitem>--enable-dbus-module</systemitem> By default, and with --enable-dbus-module as well, Seed attempts to build the DBus native module. <systemitem>--disable-os-module</systemitem> and <systemitem>--enable-os-module</systemitem> By default, and with --enable-os-module as well, Seed attempts to build the os native module. <systemitem>--disable-libxml-module</systemitem> and <systemitem>--enable-libxml-module</systemitem> By default, and with --enable-libxml-module as well, Seed attempts to build the libxml2 native module. <systemitem>--disable-gtkbuilder-module</systemitem> and <systemitem>--enable-gtkbuilder-module</systemitem> By default, and with --enable-gtkbuilder-module as well, Seed attempts to build the GtkBuilder native module. <systemitem>--disable-cairo-module</systemitem> and <systemitem>--enable-cairo-module</systemitem> By default, and with --enable-cairo-module as well, Seed attempts to build the Cairo native module. <systemitem>--disable-gettext-module</systemitem> and <systemitem>--enable-gettext-module</systemitem> By default, and with --enable-gettext-module as well, Seed attempts to build the gettext native module. <systemitem>--disable-mpfr-module</systemitem> and <systemitem>--enable-mpfr-module</systemitem> By default, and with --enable-mpfr-module as well, Seed attempts to build the mpfr native module. <systemitem>--disable-turtle-example</systemitem> and <systemitem>--enable-turtle-example</systemitem> By default, and with --enable-turtle-example as well, Seed attempts to build the Turtle example. <systemitem>--disable-examples</systemitem> and <systemitem>--enable-examples</systemitem> By default, and with --enable-examples as well, a library of JavaScript examples are installed alongside Seed. <systemitem>--disable-profile</systemitem> and <systemitem>--enable-profile</systemitem> With --enable-profile, Seed is built with profiling and coverage instructions. One can use make profile or make profile-gui to profile the library. <systemitem>--disable-profile-modules</systemitem> and <systemitem>--enable-profile-modules</systemitem> With --enable-profile-modules, all Seed modules are built with profiling and coverage instructions. One can use make profile or make profile-gui to profile the modules. <systemitem>--disable-debug</systemitem> and <systemitem>--enable-debug</systemitem> With --enable-debug, Seed is built without optimizations and with extra debugging information included, and extra debug arguments to the seed interpreter are enabled; you can learn about these by calling seed --help. <systemitem>--disable-shave</systemitem> and <systemitem>--enable-shave</systemitem> By default, and with --enable-shave as well, Seed is built with pretty-printed build output. Disable this to see the actual compiler and linker commands being executed. seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/reference/contact.sgml000066400000000000000000000025021303774616400236470ustar00rootroot00000000000000 Contact Information 3 SEED Library Contact Information Where to find help, ask questions, or bring patches Authors Robert Carr <racarr@svn.gnome.org> Tim Horton <hortont@svn.gnome.org> Source Repository The Seed source code is kept in the GNOME-wide version control at git.gnome.org. You can check out the code on your own machine if you have git installed: git clone git://git.gnome.org/seed Bugs Bugs and feature requests can be reported on the seed product in GNOME Bugzilla. seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/reference/imports.sgml000066400000000000000000000146021303774616400237150ustar00rootroot00000000000000 Importer 3 SEED Library Importer Importing gobject-introspection namespaces, native modules, and JavaScript modules Overview The Seed importer provides a way for applications written in JavaScript to reference functions outside of the current file. This is the heart of Seed's ability to work with other parts of the GNOME stack, as well as a way to write reasonably structured and sensible complex applications from JavaScript. The importer allows access to four types of external objects: GObject-Introspection namespaces, which provide access to functiosn and data which were scanned using gobject-introspection from other C libraries; this is how one accesses most of the libraries of the GNOME stack from JavaScript Native modules, which provide a way to load arbitrary shared libraries tailored explicitly to the Seed API, which often offer much higher performance for critical code, or provide an easy way to bind code (by hand) which the introspection scanner cannot parse. JavaScript modules, which provide a way to access (in a namespaced manner) the global object of another script, offering a simple way to modularize code written against Seed. Directories, which simply contain, as properties on the object the importer returns, the contents of the directory. (expand, fix. this is confusing and misplaced) The global 'imports' object represents the runtime-side portion of the importer; all of your interactions with the importer will take place through this object. The Imports Search Path The path which the importer searches for native modules and JavaScript modules is defined by the searchPath property on the 'imports' global. This should be a JavaScript array of strings representing the order and locations to search for these modules; the default set of paths includes various Seed system directories, the directory in which the currently running script is located, and the current directory, in that order. You can change the path at any time; if an invalid value is assigned, the importer will throw an exception the next time something is imported, not when the property is set. Adding a directory to the search path imports.searchPath.unshift("/usr/local/share/random-seed-program-scripts/"); Importing GObject-Introspection namespaces GObject-Introspection provides the metadata required in order to call functions, connect to signals, and interact with properties within any library which has been scanned. The hows and whys of introspection are outside of the scope of this article, but how to utilize this data is central to the very tenents of Seed (the minimal platform possible to interact with GObject-based libraries from a pleasant language). Namespaces are loaded as requested, and are loaded only once throughout the lifetime of a Seed program (subsequent requests for the same namespace will return the same object provided previously). The special property 'gi' on the imports global represents the interface for loading these namespaces. A request to import Gtk might look like the following: Using 'imports.gi' to import the Gtk namespace Gtk = imports.gi.Gtk; This will import the Gtk namespace from GObject-Introspection, and assign it to the global "Gtk" object. Afterwards, Gtk-related functions can be accessed as properties of said object. Imports will never add values to the global object or affect anything outside of their namespace. By default, 'imports.gi.NameSpace' will return the most recent installed version of the imported namespace; in order to request a different version, or to mark your program as requiring a particular version, the "imports.gi.versions.NameSpace" property can be set. Keep in mind that versioning for GObject-Introspection namespaces is slightly different from the actual library version numbers; for example, the version for Gtk is still "2.0", even though we're many versions past that. The import will raise an exception if the requested version could not be loaded: Using 'imports.gi.versions' to require Clutter 0.8 imports.gi.versions.Clutter = "0.8"; try { Clutter = imports.gi.Clutter; } catch(e) { print("Clutter 0.8 is not installed!"); } Importing Native Modules Seed ships with a number of (link!) native modules, which provide access to various parts of the system which GObject-Introspection cannot provide proper metadata for. An application developer could also decide to write performance-critical parts of their code as a native Seed module, as well, as one of the numerous ways to interface C with Seed. Native modules are loaded just like GObject-Introspection namespaces, except as toplevel objects on "imports", instead of "imports.gi". For example, to load the readline module that ships with Seed, one could: Loading the native module "readline" readline = imports.readline; Seed searches the imports search path for native modules; if it finds a file with the given name, the prefix "seed_" and the same suffix as is used for shared libraries on your system (.so on Linux, .dylib on Mac OS X, etc.), it will assume this is a native module and load and initialize it as such. For example, the readline module loaded above is named seed_readline.so on a recent Linux machine. seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/reference/introduction.sgml000066400000000000000000000016241303774616400247410ustar00rootroot00000000000000 Introduction 3 SEED Library Introduction What Seed is all about Seed is a library and interpreter, dynamically bridging (through gobject-introspection) the WebKit JavaScriptCore engine with the GObject type system. In a more concrete sense, Seed enables you to immediately write applications around a significant portion of the GNOME platform, and easily embed JavaScript as a scripting language in your GObject library. Seed is built around the idea of "minimal-platform", in that it seems a theoretically ideal GNOME development language provides no platform of its own, but instead seamlessly integrates with the already quite large GNOME platform. seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/reference/seed-docs.sgml000066400000000000000000000043761303774616400240750ustar00rootroot00000000000000 ]> Seed Reference Manual Documentation for Seed &version;. The latest version of this documentation can be found on-line at http://library.gnome.org/devel/seed/unstable/. Seed Overview Seed JavaScript Reference This is the documentation for the JavaScript runtime side of Seed. Seed API Reference This is the documentation for the C API of Seed, used for embedding, and creating native C modules. Values and Type Conversion Seed Module Reference This is the documentation for the various modules included with Seed. Index seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/reference/seed-overrides.txt000066400000000000000000000011501303774616400250070ustar00rootroot00000000000000# These are manually-edited to override or add declarations to those scanned # from the Seed header files. SeedEngine struct SeedEngine { JSGlobalContextRef context; JSObjectRef global; gchar **search_path; JSContextGroupRef group; }; SeedScript struct SeedScript { JSStringRef script; JSValueRef exception; JSStringRef source_url; gint line_number; }; SeedClosure struct SeedClosure { GClosure closure; JSObjectRef function; JSValueRef user_data; GType return_type; gchar *description; }; seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/reference/seed-sections.txt000066400000000000000000000073271303774616400246500ustar00rootroot00000000000000seed/seed.h
Initialization seed-main SeedEngine seed_init seed_init_with_context_group seed_engine_set_search_path seed_engine_get_search_path
Contexts seed-context SeedContext SeedGlobalContext SeedContextGroup seed_context_create seed_context_ref seed_context_unref seed_context_collect seed_context_get_global_object seed_prepare_global_context seed_importer_add_global seed_importer_set_search_path
Evaluation seed-eval SeedScript seed_make_script seed_evaluate seed_simple_evaluate seed_script_new_from_file seed_script_exception seed_script_destroy
Exceptions seed-exception SeedException seed_make_exception seed_exception_get_name seed_exception_get_message seed_exception_get_line seed_exception_get_file seed_exception_to_string
Signals seed-signals seed_signal_connect seed_signal_connect_value
Native Type Conversion seed-typeconversion SeedValue SeedType seed_make_undefined seed_make_null seed_value_to_boolean seed_value_from_boolean seed_value_to_uint seed_value_from_uint seed_value_to_int seed_value_from_int seed_value_to_char seed_value_from_char seed_value_to_uchar seed_value_from_uchar seed_value_to_long seed_value_from_long seed_value_to_ulong seed_value_from_ulong seed_value_to_int64 seed_value_from_int64 seed_value_to_uint64 seed_value_from_uint64 seed_value_to_float seed_value_from_float seed_value_to_double seed_value_from_double seed_value_to_string seed_value_from_string seed_value_from_binary_string seed_value_to_object seed_value_from_object seed_value_to_filename seed_value_from_filename seed_value_to_format seed_pointer_get_pointer seed_make_pointer SeedString seed_string_ref seed_string_unref seed_string_get_maximum_size seed_string_to_utf8_buffer seed_string_is_equal seed_string_is_equal_utf8
Operating on Native Types seed-nativetypes seed_value_unprotect seed_value_protect seed_value_is_undefined seed_value_is_null seed_value_is_function seed_value_is_number seed_value_is_string seed_value_is_object_of_class seed_value_is_object seed_value_get_type
JS Objects seed-object SeedObject seed_make_object seed_make_array seed_object_call seed_object_set_property_at_index seed_object_get_property_at_index seed_object_is_of_class seed_object_get_private seed_object_set_private seed_object_get_property seed_object_set_property seed_object_get_prototype seed_object_copy_property_names SeedObjectInitializeCallback SeedObjectFinalizeCallback SeedObjectHasPropertyCallback SeedObjectGetPropertyCallback SeedObjectSetPropertyCallback SeedObjectDeletePropertyCallback SeedObjectGetPropertyNamesCallback SeedObjectCallAsFunctionCallback SeedObjectHasInstanceCallback SeedObjectConvertToTypeCallback SeedObjectCallAsConstructorCallback
Native Functions seed-nativefuncs SeedFunctionCallback seed_make_function seed_create_function
JavaScript Classes seed-jsclass SeedPropertyAttributes SeedClassAttributes SeedClass seed_empty_class seed_create_class seed_make_constructor
SeedClosure seed-closure SeedClosure seed_closure_new seed_closure_get_callable seed_closure_invoke seed_closure_invoke_with_context seed_closure_warn_exception
Modules seed-modules CHECK_ARG_COUNT DEFINE_ENUM_MEMBER DEFINE_ENUM_MEMBER_EXT SeedModuleInitCallback
seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/reference/seed.types000066400000000000000000000000001303774616400233250ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/reference/tmpl/000077500000000000000000000000001303774616400223055ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/reference/tmpl/seed-closure.sgml000066400000000000000000000021151303774616400255620ustar00rootroot00000000000000 Using JavaScript closures Creating and invoking closures over JavaScript functions using GClosure Long description @closure: @function: @user_data: @return_type: @description: @ctx: @function: @user_data: @description: @Returns: @c: @Returns: @closure: @args: @argc: @exception: @Returns: @ctx: @closure: @args: @argc: @exception: @Returns: @c: @ctx: @exception: seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/reference/tmpl/seed-context.sgml000066400000000000000000000041651303774616400256010ustar00rootroot00000000000000 Working with Contexts Self-contained JavaScript execution environments A #SeedContext provides a complete "universe" for the execution of JavaScript. You can use seed_context_create() to create a sandboxed context that lacks the import system, so it can be used to execute somewhat untrusted JavaScript (as it has no way to access the rest of your system). You can also expose the default set of globals (including "print", "imports", and "Seed") to create more powerful but still self-contained environments within which to execute code. Using a Seed context as a form of sandboxing ... ctx = seed_context_create(NULL, NULL); script = seed_make_script(ctx, "print(imports)", NULL, 0); // nothing is printed, because imports is undefined, because we're in a sandbox ... The sandbox module provides access to this system from the JavaScript side of Seed. @group: @global_class: @Returns: @ctx: @Returns: @ctx: @ctx: @ctx: @Returns: @ctx: @ctx: @name: @ctx: @search_path: seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/reference/tmpl/seed-eval.sgml000066400000000000000000000046471303774616400250510ustar00rootroot00000000000000 Evaluating JavaScript Creating and interpreting scripts Seed relies on WebKit's JavaScriptCore interpreter to actually evaluate snippets of JavaScript; however, it provides a handful of useful wrapper functions to quickly create and evaluate scripts. seed_make_script() and seed_evaluate() are the workhorse functions; these allow you to control every detail of the created script and its evaluation environment (including customizing the "this" object during evaluation, and setting a starting line number and filename from which the script originates). seed_simple_evaluate() provides an interface to execute a string of JavaScript without previously creating a #SeedScript, and, while requiring less supporting code, is less flexible. Create and evaluate a string of JavaScript with seed_make_script() SeedEngine * eng;   ...   SeedScript * script; /* Create a simple #SeedScript */ script = seed_make_script(eng->context, "print('Hello, world!')", NULL, 0);   /* Evaluate the #SeedScript in the default context */ seed_evaluate(eng->context, script, 0);   ... Create and evaluate a string of JavaScript with seed_simple_evaluate() SeedEngine * eng;   ...   /* Evaluate a simple JavaScript snippet in the default context */ seed_simple_evaluate(eng->context, "print('Hello, world!')", NULL);   ... @script: @exception: @source_url: @line_number: @ctx: @js: @source_url: @line_number: @Returns: @ctx: @s: @this_object: @Returns: @ctx: @source: @exception: @Returns: @ctx: @file: @Returns: @s: @Returns: @s: seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/reference/tmpl/seed-exception.sgml000066400000000000000000000077361303774616400261220ustar00rootroot00000000000000 Exception Handling Throwing and catching exceptions Seed uses exceptions as a method of handling runtime errors within scripts. An exception consists of a name (a list of commonly-used exception names is below), a message, detailing the error, and the line number and filename from which the exception was raised. If Seed cannot determine from where the exception was raised, the line number and filename will be undefined. seed_exception_to_string() provides a simple way to convert all of these into a consistent representation to display to users. All Seed callbacks take an exception argument; calling seed_make_exception() with this argument and the details you wish to fill it with will propogate that exception up the chain. Exceptions can be caught either by a try/catch block in the calling JavaScript, or by observing the exception property, dealing with it, and then clearing the exception. It is important to note that calling seed_make_exception() does not in fact throw the exception, but just creates an object which, when stored in the exception pointer passed to a callback, causes JSC to throw an exception once flow is returned. Throw an exception, because <function>random_callback</function> was called with the wrong number of arguments SeedValue random_callback(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException *exception) { ...   if(argument_count != 1) { seed_make_exception(ctx, exception, "ArgumentError", "wrong number of arguments; expected 1, got %zd", argument_count); return seed_make_undefined(ctx); }   ... } Predefined Exception Names InvalidPropertyValue - a property was set to a value out of range PropertyError - a warning occurred in GLib while trying to set a property ArgumentError - a function was called with the wrong number of arguments ConversionError - one of the type conversion functions threw an exception TypeError - a required argument was of the wrong type SyntaxError - a syntax error was thrown from JavaScriptCore ParseError - a parsing error was thrown from JavaScriptCore (make sure you close all of your brackets!) ReferenceError - a reference error was thrown from JavaScriptCore (most likely, you tried to access a variable which was undefined) @ctx: @exception: @name: @message: @...: @ctx: @exception: @Returns: @ctx: @exception: @Returns: @ctx: @exception: @Returns: @ctx: @exception: @Returns: @ctx: @exception: @Returns: seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/reference/tmpl/seed-jsclass.sgml000066400000000000000000000030331303774616400255500ustar00rootroot00000000000000 Creating JavaScript classes Dealing with Seed class definitions and constructors Defining new Seed classes allows for implementing more complex behavior than possible with the traditional JavaScript object system and default class. When writing Seed modules, it is often the best pattern to define many of your types through classes and static functions/value. Please note that inside the finalize callback of a class, it is not legal to call any method requiring a #SeedContext (with the exception of protect/unprotect, though it is not guaranteed this will continue to work with future versions of JSCore). @SEED_PROPERTY_ATTRIBUTE_NONE: @SEED_PROPERTY_ATTRIBUTE_READ_ONLY: @SEED_PROPERTY_ATTRIBUTE_DONT_ENUM: @SEED_PROPERTY_ATTRIBUTE_DONT_DELETE: @SEED_CLASS_ATTRIBUTE_NONE: @SEED_CLASS_ATTRIBUTE_NO_SHARED_PROTOTYPE: @def: @Returns: @ctx: @klass: @constructor: @Returns: seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/reference/tmpl/seed-main.sgml000066400000000000000000000033341303774616400250360ustar00rootroot00000000000000 Initialization Overall setup of the Seed engine Before any other Seed functions can be used, you must initialize the engine, which creates an initial JavaScript context and sets up JavaScriptCore and GLib. To do this in most cases, you will use seed_init(), which will provide you with a #SeedEngine. Only one #SeedEngine is permitted per application; use a #SeedContext to sandbox code execution. Very simple <function>main</function> function for a Seed program int main (int argc, char **argv) { SeedEngine * eng; SeedScript * script;   /* Initialize the Seed engine */ eng = seed_init(&argc, &argv);   /* Create a simple #SeedScript */ script = seed_make_script(eng->context, "print('Hello, world!')", NULL, 0);   /* Evaluate the #SeedScript in the default context */ seed_evaluate(eng->context, script, 0);   g_free(script); return 0; } @context: @global: @search_path: @group: @argc: @argv: @Returns: @argc: @argv: @group: @Returns: @eng: @path: @eng: @Returns: seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/reference/tmpl/seed-main.sgml.sgml000066400000000000000000000044321303774616400257770ustar00rootroot00000000000000 seed-main.sgml @argc: @argv: @Returns: @argc: @argv: @group: @Returns: @ctx: @name: @ctx: @search_path: @eng: @path: @eng: @Returns: @ctx: @js: @source_url: @line_number: @Returns: @ctx: @s: @this: @Returns: @ctx: @source: @exception: @Returns: @ctx: @file: @Returns: @s: @Returns: @ctx: @callback: @name: @Returns: @ctx: @name: @callback: @object: @ctx: @class: @Param3: @Returns: @ctx: @pointer: @Returns: @ctx: @function: @this_object: @argument_count: @arguments: @excecption: @Returns: @eng: @Returns: @ctx: @object: @signal: @script: @ctx: @object: @signal: @function: @user_data: seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/reference/tmpl/seed-modules.sgml000066400000000000000000000100331303774616400255540ustar00rootroot00000000000000 Seed Modules Native C modules for Seed Seed includes a simple system for creating C modules which can be loaded and manipulated from JavaScript. This is used for implementing performance-critical code closer to the silicon, as well as binding non-introspectable libraries in an attractive way. Numerous binding modules are included in the Seed repository; when writing a new native module, it would be wise to look over these before beginning, as they have many tidbits of useful knowledge for writing modules. Very simple example C module #include <glib.h> #include <seed-module.h> SeedObject seed_module_init(SeedEngine * eng) { /* Say hello! */ g_print("Hello, Seed Module World!\n");   /* Return an empty object as the module's namespace */ return seed_make_object (eng->context, NULL, NULL); } Above is a C module which does absolutely nothing useful. When a module is loaded, seed_module_init() is called, which should have the signature of SeedModuleInitCallback(). You're passed the global #SeedEngine, and the value you return is the namespace for your module. Say, for example, you place a static function on that object: C module with a function #include <glib.h> #include <seed-module.h> /* Our function, with the signature of SeedFunctionCallback(); say hello! */ SeedValue say_hello_to(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException *exception) { guchar * name;   /* Check that only one argument was passed into the function. CHECK_ARG_COUNT() is from seed-module.h, which you might find useful. */ CHECK_ARG_COUNT("hello.say_hello_to", 1);   /* Convert the first argument, a #SeedValue, to a C string */ name = seed_value_to_string(ctx, arguments[0], exception);   g_print("Hello, %s!\n", name);   g_free(name);   return seed_make_null(ctx); }   /* Define an array of #seed_static_function */ seed_static_function gettext_funcs[] = { {"say_hello_to", say_hello_to, 0} };   SeedObject seed_module_init(SeedEngine * eng) { SeedGlobalContext ctx = eng->context;   /* Create a new class definition with our array of static functions */ seed_class_definition ns_class_def = seed_empty_class; ns_class_def.static_functions = example_funcs;   /* Create a class from the class definition we just created */ SeedClass ns_class = seed_create_class(&ns_class_def);   /* Instantiate the class; this instance will be the namespace we return */ ns_ref = seed_make_object (ctx, ns_class, NULL); seed_value_protect (ctx, ns_ref);   return ns_ref; } After building and installing this module (look in the Seed build system for examples of how to get this to work, as well as a copy of seed-module.h, which will be very useful), it will be loadable with the normal Seed import system. Assuming it's installed as libseed_hello.so: Utilize our second example C module from JavaScript hello = imports.hello; hello.say_hello_to("Tim"); @name: @argnum: @holder: @member: @holder: @name: @val: @eng: @Returns: seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/reference/tmpl/seed-nativefuncs.sgml000066400000000000000000000042261303774616400264400ustar00rootroot00000000000000 Creating native functions C functions as first-class JavaScript objects Exposing native C functions to JavaScript is one of the fundamental use cases for libseed when used in an embedding environment; if your application cannot be introspected, or you only have a small number of functions to expose, this is the simplest way to do that. All native C callbacks should have the prototype of SeedFunctionCallback(). Simple C program which embeds Seed with one exposed function #include <glib.h> #include <seed.h>   /* Our function, with the signature of SeedFunctionCallback(); say hello! */ SeedValue hello_world(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException *exception) { g_print("Hello, World!\n"); return seed_make_null(ctx); }   int main(gint argc, gchar ** argv) { SeedEngine * eng;   /* Initialize the Seed engine */ eng = seed_init(&argc, &argv);   /* Expose a C function to JavaScript */ seed_create_function(eng->context, "hello_world", (SeedFunctionCallback)hello_world, eng->global);   /* Call the newly created JavaScript function */ seed_simple_evaluate(eng->context, "hello_world()", NULL);   return 0; } @ctx: @function: @this_object: @argument_count: @arguments: @exception: @Returns: @ctx: @func: @name: @Returns: @ctx: @name: @func: @obj: seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/reference/tmpl/seed-nativetypes.sgml000066400000000000000000000024661303774616400264720ustar00rootroot00000000000000 Operating on JavaScript types Determining the type of a SeedValue Long description @ctx: @value: @ctx: @value: @ctx: @value: @Returns: @ctx: @value: @Returns: @ctx: @value: @Returns: @ctx: @value: @Returns: @ctx: @value: @Returns: @ctx: @value: @klass: @Returns: @ctx: @value: @Returns: @ctx: @value: @Returns: seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/reference/tmpl/seed-object.sgml000066400000000000000000000063021303774616400253560ustar00rootroot00000000000000 Working with JavaScript objects Using properties, constructing objects, etc. Long description @ctx: @klass: @private_object: @Returns: @ctx: @elements: @num_elements: @exception: @Returns: @ctx: @object: @this_object: @argument_count: @arguments: @exception: @Returns: @ctx: @object: @index: @value: @exception: @ctx: @object: @index: @exception: @Returns: @ctx: @obj: @klass: @Returns: @object: @Returns: @object: @value: @ctx: @object: @name: @Returns: @ctx: @object: @name: @value: @Returns: @ctx: @obj: @Returns: @ctx: @object: @Returns: @ctx: @object: @object: @ctx: @object: @string: @Returns: @ctx: @object: @property_name: @e: @Returns: @ctx: @object: @property_name: @value: @e: @Returns: @ctx: @object: @property_name: @e: @Returns: @void: @ctx: @function: @this_object: @argument_count: @arguments: @exception: @Returns: @ctx: @constructor: @instance_p: @exception: @Returns: @ctx: @object: @type: @exception: @Returns: @ctx: @constructor: @argument_count: @arguments: @exception: @Returns: seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/reference/tmpl/seed-signals.sgml000066400000000000000000000011221303774616400255430ustar00rootroot00000000000000 GObject Signals Connecting JavaScript functions to signals Long description @ctx: @object: @signal: @script: @ctx: @object: @signal: @function: @user_data: seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/reference/tmpl/seed-string.sgml000066400000000000000000000003201303774616400254100ustar00rootroot00000000000000 SeedString This one should go away eventually Long description seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/reference/tmpl/seed-typeconversion.sgml000066400000000000000000000114251303774616400272010ustar00rootroot00000000000000 Type Conversion Moving between JavaScript and C intrinsic types Long description @SEED_TYPE_UNDEFINED: @SEED_TYPE_NULL: @SEED_TYPE_BOOLEAN: @SEED_TYPE_NUMBER: @SEED_TYPE_STRING: @SEED_TYPE_OBJECT: @ctx: @Returns: @ctx: @Returns: @ctx: @val: @exception: @Returns: @ctx: @val: @exception: @Returns: @ctx: @val: @exception: @Returns: @ctx: @val: @exception: @Returns: @ctx: @val: @exception: @Returns: @ctx: @val: @exception: @Returns: @ctx: @val: @exception: @Returns: @ctx: @val: @exception: @Returns: @ctx: @val: @exception: @Returns: @ctx: @val: @exception: @Returns: @ctx: @val: @exception: @Returns: @ctx: @val: @exception: @Returns: @ctx: @val: @exception: @Returns: @ctx: @val: @exception: @Returns: @ctx: @val: @exception: @Returns: @ctx: @val: @exception: @Returns: @ctx: @val: @exception: @Returns: @ctx: @val: @exception: @Returns: @ctx: @val: @exception: @Returns: @ctx: @val: @exception: @Returns: @ctx: @val: @exception: @Returns: @ctx: @val: @exception: @Returns: @ctx: @val: @exception: @Returns: @ctx: @val: @exception: @Returns: @ctx: @bytes: @n_bytes: @exception: @Returns: @ctx: @val: @exception: @Returns: @ctx: @val: @exception: @Returns: @ctx: @val: @exception: @Returns: @ctx: @val: @exception: @Returns: @ctx: @format: @values: @exception: @...: @Returns: @ctx: @pointer: @Returns: @ctx: @pointer: @Returns: @string: @Returns: @string: @string: @Returns: @string: @buffer: @buffer_size: @Returns: @a: @b: @Returns: @a: @b: @Returns: seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/reference/tmpl/seed.sgml000066400000000000000000000031771303774616400241210ustar00rootroot00000000000000 seed @argc: @argv: @Returns: @eng: @path: @eng: @Returns: @ctx: @js: @source_url: @line_number: @Returns: @ctx: @s: @this: @Returns: @ctx: @source: @exception: @Returns: @ctx: @file: @Returns: @s: @Returns: @ctx: @name: @callback: @object: @ctx: @class: @Param3: @Returns: @ctx: @pointer: @Returns: @ctx: @function: @this_object: @argument_count: @arguments: @exception: @eng: @Returns: seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/reference/version.xml.in000066400000000000000000000000121303774616400241360ustar00rootroot00000000000000@VERSION@ seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/runtime.html.in000066400000000000000000000312361303774616400223560ustar00rootroot00000000000000 Seed Runtime Documentation
v.@VERSION@
imports

An imports object is defined globally in every Seed context. This provides access to GObject Introspection namespaces, C extension modules, and other JavaScript files, as explained in the next three sections.

The default path to search for native modules and JavaScript files to be imported can be set as an array of strings on imports.searchPath:

imports.searchPath.push("/opt/javascript");

This will add /opt/javascript as the last location to search when looking for native Seed modules and JavaScript files. The default search path includes the current directory and the directory into which Seed's default native modules are installed.

imports.gi

Provides access to all installed gobject-introspection namespaces. imports.gi.namespace will import functions and constructors from the given namespace and return an object providing them.

Importing is done once per process, and any subsequent accesses to the same namespace return the same object, and are very cheap as a result.

Gtk = imports.gi.Gtk;
Gtk.init(null, null);

A particular version of a namespace can be loaded by setting before it is first requested, by setting the imports.gi.versions.namespace object to a string representing the version number to load:

imports.gi.versions.Clutter = "0.8";
Clutter = imports.gi.Clutter; // The returned object represents clutter-0.8
Importing modules and JavaScript files

Native C modules and JavaScript files can be imported in a similar fashion, by accessing imports.file. Notice that the suffix (most likely .so or .js, respectively) is not included in the file name when requesting it, and keep this in mind when naming files.

First, if the file name is actually a directory, an object is returned that represents the contents of that directory, which behaves exactly as imports does in regards to importing native modules and JavaScript files. For example, say you have the directory js, which contains score.js:

score = imports.js.score;

This will import score.js, just as described below.

If the file is not a directory, but happens to have your system's shared library suffix, the native module is loaded, and the module object is returned, similar to GObject Introspection namespace imports:

readline = imports.readline;
readline.readline(">");

Otherwise, Seed assumes that the file is a JavaScript file. If the file is found in the current path, it is evaluated (in a separate Seed context, so any state in the file it is imported from is not accessible), and the global object is returned. Keep in mind that it is possible to accidentally import a non-JavaScript file, as the extension is not taken into account.

Imagine we have the file test_file.js:

test_string = "Hello, world!";

And another file, which we evaluate with seed:

test_file = imports.test_file;
print(test_file.test_string);

This will print "Hello, world!", as expected. Notice how, unlike in versions of Seed prior to 0.5, the file is not actually evaluated in the context of the importing file, so its toplevel objects are not globally available.

print(value)

Prints, to standard output, a representation of value. Number types are printed as floating-point values (with 6 decimal places); strings are printed as-is; objects are printed as [object type].

print(5);
print("This is a test!".replace(" is ", " was "));

var win = new Gtk.Window();
print(win);
printf(format, ...)
Seed.sprintf(format, ...)

printf prints, to standard output, a string formatted as specified by format. Following format should be values to substitute, as in C's printf. Most standard printf format strings should work.

sprintf returns the string, instead of printing it.

printf("A number: %d\n", 5);
printf("One third is approximately %.3f\n", 1/3);
printf("%d %s %d\n", 2, " is not ", 5);

var my_string = Seed.sprintf("%d + %d = %d", 2, 3, 2+3);
var my_name = printf("[%s] is %d characters long!\n",
                          my_string, my_string.length);
Seed.check_syntax(code)

Examines a segment of Javascript, looking for syntax errors. If errors are found, an exception is thrown, which can be caught with a try/catch block. You can examine the location of the syntax error with the line property of the returned exception.

try{
    Seed.check_syntax("234[asdf");
}
catch(e){
    print("Something horrible happened on line " + e.line);
}
Seed.stringify(object)

Returns a string representing the entire contents of object in a pretty-printed fashion, like that of JSON.

proto = Seed.prototype(Gtk.Window);
method = Seed.introspect(proto.translate_coordinates);
print(Seed.stringify(method));
Seed.argv

An array representing the arguments passed to the seed interpreter.

Seed.quit(exitcode)

Terminates the execution of the Seed interpreter, returning exitcode as the exit value of the program.

object.signal.signame.connect(function, user_data)
object.connect(signame, function, user_data)

Connects function to the signal, signame, on object. Any GObject signal will work. If present, user_data is passed as the last argument to the callback.

function button_clicked(){
    print("You pushed me!!");
}

var button = new Gtk.Button();
button.signal.clicked.connect(button_clicked);

The second form is useful if you want to connect to detailed signals; for example, notify:: signals on an object's properties:

function handle_opacity_change(obj, gobject, user_data){
    print("Window " + obj + "'s opacity was changed!");
}

win = new Gtk.Window();
win.signal.connect("notify::opacity", handle_opacity_change);
Exceptions

Seed throws Javascript exceptions for errors in the GObject layer; our custom exception types are as follows:

  • InvalidPropertyValue - a property was set to a value out of range
  • PropertyError - a warning occurred in GLib while trying to set a property
  • ArgumentError - a function was called with the wrong number of arguments
  • ConversionError - one of the type conversion functions threw an exception
  • TypeError - a required argument was of the wrong type
  • SyntaxError - a syntax error was thrown from JavaScriptCore
  • ParseError - a parsing error was thrown from JavaScriptCore (make sure you close all of your brackets!)

Exceptions are caught with the try/catch construct:

try{
    var window = new Gtk.Window();
    window.opacity = "hello!";
}
catch(e){
    print("An exception occurred!");
}

e is the name we've given the Exception object in this examle. The Exception object has a handful of properties which provide more information about the exception:

  • name - the exception type
  • message - the detailed message describing the exception
  • line - the line on which the exception took place
  • sourceURL - the source file, if any, in which the exception took place

Just as in Javascript, you can throw an exception manually with the throw function, passing it an object - either a new object, with the properties listed above (for consistency), or an arbitrary object:

try{
    if(!http.connect("http://google.com"))
        throw { name: "HTTPConnectionError", message: "404 File Not Found" }
}
catch(e){
    // e.message = "404 File Not Found"
}
Inheritance

JavaScript, being a prototypal language, rather than a class based language, has no strict inheritance model. A plethora of documentation can be found on the internet for implementing various inheritance models inside your program. However, a clear and common use case is to subclass GObjects, and Seed provides an interface to define and implement new GTypes.

Type Objects

To implement a new GType, an object describing the type is required.

NewType = {
    parent: ParentTypeConstructor,
    name: "NewTypeName",
    class_init: function(klass, prototype){
    },
    instance_init: function(){
    }
}

Indicates that the new type derives from ParentType, i.e. Gtk.Window, with name "NewTypeName". The class_init function is called when the class comes in to existence, and allows you to add to the prototype of objects constructed by the type. The instance_init function is called on the creation of each instance, with the "this" variable set to the new instance. An example type:

HelloLabel = new GType({
    parent: Gtk.Label,
    name: "HelloLabel",
    class_init: function(klass, prototype){
        prototype.say_goodbye = 
                             function(){
                                 this.label = "Goodbye";
                             }
    },
    instance_init: function(){
        this.label = "Hello"; // Hello Labels Always Say Hello.
    }
});

Now to create an instance of the object:

label = new HelloLabel();
box.pack_start(label);
label.show();
label.say_goodbye();

The label inherits all the methods, signals, and properties of the Gtk.Label class and its parents, and internally has its own GType.

signal.emit(...)

emit provides the ability to arbitrarily emit any GObject signal, thus calling all of the functions which are connected to it. Any arguments passed to emit are passed on to the callback function.

win = new Gtk.Window();
win.signal.close.connect(Gtk.main_quit);
win.signal.close.emit();
class.install_signal(signal_descriptor)

When creating a new GObject type within Seed, install_signal provides the ability to install new signals, which you can later emit with emit and can be connected to in any of the usual ways.

signal_descriptor is a Javascript object describing the signal. Important properties of signal_descriptor are:

  • name — the name of the signal
  • parameters — the types of any arguments the signal takes, as a Javascript array (optional)
  • return_type — the expected return type of the signal handler (optional)

For example:

HelloWindow = new GType({       
    parent: Gtk.Window.type,
    name: "HelloWindow",
    signals: [{name: "hello",
               parameters: [GObject.TYPE_INT,
                            GObject.TYPE_STRING],
               return_type: Gtk.Window.type}];
});

w = new HelloWindow();

w.signal.hello.connect(function(object, number, string){
                           print(number + " " + string);
                           return new Gtk.Window()
                       });

print(w.signal.hello.emit(2, "Test"));

seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/seed.1000066400000000000000000000020771303774616400204030ustar00rootroot00000000000000.TH "seed" 1 .SH NAME seed \- libseed JavaScript REPL/Interpreter. .SH SYNOPSIS .B seed [OPTION...] [SCRIPT] .SH DESCRIPTION seed acts as a simple read-eval-print loop for libseed's GObject JavaScriptCore bindings, unless the path to a script to interpret is specified. .SH OPTIONS .TP .B \--help Show these help options. .TP .B \--version Print interpreter version. .TP .B \-e "expression" Takes the JavaScript expression, checks its syntax, and evaluates it, printing the return value. .TP .B \--seed-debug=DEBUGFLAGS Show debug messages, filtered by the specified debug flags. If one wishes to see all possible debug messages, specify the flag "all" (keep in mind that this will produce a significant amount of output). Otherwise, specify a comma-separated list of: misc, finalization, initialization, signal, invocation, structs, construction, gtype, importer, module. .TP .SH BUGS Report bugs at http://bugzilla.gnome.org/ in the seed product. .SH HOMEPAGE and CONTACT http://live.gnome.org/Seed .SH AUTHORS Robert Carr .PP Tim Horton seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/sh.css000066400000000000000000000027361303774616400205270ustar00rootroot00000000000000pre.sh_sourceCode{color:#000;font-style:normal;}pre.sh_sourceCode .sh_keyword{color:#9c20ee;font-weight:bold;font-style:normal;}pre.sh_sourceCode .sh_type{color:#208920;font-style:normal;}pre.sh_sourceCode .sh_string{color:#bd8d8b;font-style:normal;}pre.sh_sourceCode .sh_regexp{color:#bd8d8b;font-style:normal;}pre.sh_sourceCode .sh_specialchar{color:#bd8d8b;font-style:normal;}pre.sh_sourceCode .sh_comment{color:#ac2020;font-style:italic;}pre.sh_sourceCode .sh_number{color:#000;font-style:normal;}pre.sh_sourceCode .sh_preproc{color:#000;font-style:normal;}pre.sh_sourceCode .sh_function{color:#000;font-style:normal;}pre.sh_sourceCode .sh_url{color:#bd8d8b;font-style:normal;}pre.sh_sourceCode .sh_date{color:#9c20ee;font-weight:bold;font-style:normal;}pre.sh_sourceCode .sh_time{color:#9c20ee;font-weight:bold;font-style:normal;}pre.sh_sourceCode .sh_file{color:#9c20ee;font-weight:bold;font-style:normal;}pre.sh_sourceCode .sh_ip{color:#bd8d8b;font-style:normal;}pre.sh_sourceCode .sh_name{color:#bd8d8b;font-style:normal;}pre.sh_sourceCode .sh_variable{color:#00f;font-style:normal;}pre.sh_sourceCode .sh_oldfile{color:#bd8d8b;font-style:normal;}pre.sh_sourceCode .sh_newfile{color:#bd8d8b;font-style:normal;}pre.sh_sourceCode .sh_difflines{color:#9c20ee;font-weight:bold;font-style:normal;}pre.sh_sourceCode .sh_selector{color:#00f;font-style:normal;}pre.sh_sourceCode .sh_property{color:#9c20ee;font-weight:bold;font-style:normal;}pre.sh_sourceCode .sh_value{color:#bd8d8b;font-style:normal;}seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/sh.js000066400000000000000000000122711303774616400203460ustar00rootroot00000000000000/* Copyright (C) 2007, 2008 gnombat@users.sourceforge.net */ /* License: http://shjs.sourceforge.net/doc/gplv3.html */ if(!this.sh_languages){this.sh_languages={}}var sh_requests={};function sh_isEmailAddress(a){if(/^mailto:/.test(a)){return false}return a.indexOf("@")!==-1}function sh_setHref(b,c,d){var a=d.substring(b[c-2].pos,b[c-1].pos);if(a.length>=2&&a.charAt(0)==="<"&&a.charAt(a.length-1)===">"){a=a.substr(1,a.length-2)}if(sh_isEmailAddress(a)){a="mailto:"+a}b[c-2].node.href=a}function sh_konquerorExec(b){var a=[""];a.index=b.length;a.input=b;return a}function sh_highlightString(B,o){if(/Konqueror/.test(navigator.userAgent)){if(!o.konquered){for(var F=0;FI){x(g.substring(I,E.index),null)}var e=O[u];var J=e[1];var b;if(J instanceof Array){for(var L=0;L0){var e=b.split(" ");for(var c=0;c0){a.push(e[c])}}}return a}function sh_addClass(c,a){var d=sh_getClasses(c);for(var b=0;b element with class="'+h+'", but no such language exists'}}break}}}};seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/sh_js.js000066400000000000000000000130001303774616400210310ustar00rootroot00000000000000if (! this.sh_languages) { this.sh_languages = {}; } sh_languages['javascript'] = [ [ [ /\/\/\//g, 'sh_comment', 1 ], [ /\/\//g, 'sh_comment', 7 ], [ /\/\*\*/g, 'sh_comment', 8 ], [ /\/\*/g, 'sh_comment', 9 ], [ /\b(?:abstract|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|final|finally|for|function|goto|if|implements|in|instanceof|interface|native|new|null|private|protected|prototype|public|return|static|super|switch|synchronized|throw|throws|this|transient|true|try|typeof|var|volatile|while|with)\b/g, 'sh_keyword', -1 ], [ /(\+\+|--|\)|\])(\s*)(\/=?(?![*\/]))/g, ['sh_symbol', 'sh_normal', 'sh_symbol'], -1 ], [ /(0x[A-Fa-f0-9]+|(?:[\d]*\.)?[\d]+(?:[eE][+-]?[\d]+)?)(\s*)(\/(?![*\/]))/g, ['sh_number', 'sh_normal', 'sh_symbol'], -1 ], [ /([A-Za-z$_][A-Za-z0-9$_]*\s*)(\/=?(?![*\/]))/g, ['sh_normal', 'sh_symbol'], -1 ], [ /\/(?:\\.|[^*\\\/])(?:\\.|[^\\\/])*\/[gim]*/g, 'sh_regexp', -1 ], [ /\b[+-]?(?:(?:0x[A-Fa-f0-9]+)|(?:(?:[\d]*\.)?[\d]+(?:[eE][+-]?[\d]+)?))u?(?:(?:int(?:8|16|32|64))|L)?\b/g, 'sh_number', -1 ], [ /"/g, 'sh_string', 10 ], [ /'/g, 'sh_string', 11 ], [ /~|!|%|\^|\*|\(|\)|-|\+|=|\[|\]|\\|:|;|,|\.|\/|\?|&|<|>|\|/g, 'sh_symbol', -1 ], [ /\{|\}/g, 'sh_cbracket', -1 ], [ /\b(?:Math|Infinity|NaN|undefined|arguments|Seed|signal|argv|argc|Gtk|GObject|GLib|WebKit)\b/g, 'sh_predef_var', -1 ], [ /\b(?:printf|sprintf|connect|Array|Boolean|Date|Error|EvalError|Function|Number|Object|RangeError|ReferenceError|RegExp|String|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt)\b/g, 'sh_predef_func', -1 ], [ /(?:[A-Za-z]|_)[A-Za-z0-9_]*(?=[ \t]*\()/g, 'sh_function', -1 ] ], [ [ /$/g, null, -2 ], [ /(?:?)|(?:?)/g, 'sh_url', -1 ], [ /<\?xml/g, 'sh_preproc', 2, 1 ], [ //g, 'sh_keyword', -1 ], [ /<(?:\/)?[A-Za-z](?:[A-Za-z0-9_:.-]*)/g, 'sh_keyword', 6, 1 ], [ /&(?:[A-Za-z0-9]+);/g, 'sh_preproc', -1 ], [ /<(?:\/)?[A-Za-z][A-Za-z0-9]*(?:\/)?>/g, 'sh_keyword', -1 ], [ /<(?:\/)?[A-Za-z][A-Za-z0-9]*/g, 'sh_keyword', 6, 1 ], [ /@[A-Za-z]+/g, 'sh_type', -1 ], [ /(?:TODO|FIXME|BUG)(?:[:]?)/g, 'sh_todo', -1 ] ], [ [ /\?>/g, 'sh_preproc', -2 ], [ /([^=" \t>]+)([ \t]*)(=?)/g, ['sh_type', 'sh_normal', 'sh_symbol'], -1 ], [ /"/g, 'sh_string', 3 ] ], [ [ /\\(?:\\|")/g, null, -1 ], [ /"/g, 'sh_string', -2 ] ], [ [ />/g, 'sh_preproc', -2 ], [ /([^=" \t>]+)([ \t]*)(=?)/g, ['sh_type', 'sh_normal', 'sh_symbol'], -1 ], [ /"/g, 'sh_string', 3 ] ], [ [ /-->/g, 'sh_comment', -2 ], [ / image/svg+xml VBox HBox WebView Entry seed-webkit2-4.0.0+20161014+6c77960+dfsg1/doc/tutorial-standalone/tutorial.html.in000066400000000000000000000601661303774616400265330ustar00rootroot00000000000000 Seed Tutorial : Standalone
v.@VERSION@
Introduction

Seed, first and foremost, provides an easily embeddable JavaScript engine to developers looking for a straightforward way to create extensible applications. It also provides bindings between GObject and the WebKit JavaScript engine, giving new developers access to the power of the GNOME stack from a familiar and simple language, and allowing rapid prototyping of applications for hardened GNOME developers.

This tutorial begins with a few brief examples, and then dives right in, following the development of a simple Seed program, from beginning to end. By the end of the tutorial, you'll have your very own tiny WebKit-based web browser, as well as a summary knowledge of the use of Seed to build GTK+ applications.

Beginning Seed

It makes sense to start our exploration with a program you're probably quite familiar with:

#!/usr/bin/env seed

print("Hello, world!");

If you were to make this script executable (chmod +x hello.js), and run it, you'd hopefully see the following, just as expected (if you don't, for some reason, make sure you have the latest version of Seed installed, then email us):

Hello, world!

In order to make the file executable, include (#!/usr/bin/env seed) at the top of every Seed program you write. This is known as the shebang line, and tells your shell where to find the seed interpreter; I'm only going to include it when listing a whole file, from now on.

Variables in JavaScript are not given any type, and conversion between different kinds of values is automatic and painless. For example, you can:

  • Add two strings ("Hello, " + "World!") turns into "Hello, World!"
  • Add a number to a string ("Example" + (2 * 2)) turns into "Example4"

There is one exception: in order to convert a string of digits into a 'number', JavaScript needs to be explicitly instructed to do so: parseFloat("42.5").

Seed also provides a very simple interface to the GNU Readline library, which allows programs to ask the user for input. This interface is in the readline module, which must be imported before it can be used. The only argument readline.readline() requires is the prompt for the user. Also, the current version of Seed ensures that everything typed is automatically saved in the prompt's history; if you press the up key while at a prompt, you can access and edit lines you've previously entered. Future versions of Seed will provide more control over the history and other parts of readline.

readline = imports.readline;
var my_name = readline.readline("Your name? ");
var my_age = readline.readline("Your age? ");
var old = 25;
var old_age = old + parseFloat(my_age);
print(my_name + " will be " + old_age + " in " + old + " years!");

You've probably noticed that the word 'var' precedes the first use of every variable in JavaScript. This is important, because it ensures that the memory consumed by the variable is freed to be used elsewhere at the end of the current block of code, when the variable goes out of scope. If, instead, you want to create a variable which is global (available forever, after it is created), you can omit the 'var'. Keep in mind that making many global variables is generally considered bad practice, and can be expensive in terms of memory use.

A JavaScript Shell

JavaScript, being a scripting language, includes a construct, eval() which allows you to evaluate a string of JavaScript. This allows, for example, a user to input JavaScript with readline, and it to be executed as if it had been part of your source file. In addition, eval()'s return value is the return value of the snippet of code. For example:

var output = eval("2+2");
print(output);

Will output:

4.000000

When something goes wrong in a piece of JavaScript code, the program will exit, most likely leaving the user in a confused state. For example, if you try to access a variable that doesn't exist: print(asdf); Seed will exit with the message: ReferenceError Can't find variable: asdf. It is possible to catch this sort of error, or exception, inside of your JavaScript program, ensuring that it doesn't terminate your program - or that if it does, it prints a useful error message. The try/catch construct provides a way to try to execute a segment of JavaScript, and, if it fails, run a second segment, without exiting the program. The second segment could print a user-friendly error message, ignore the exception entirely, or try to work around the problem. A quick example of try/catch:

try{
    print(asdf);
}
catch(e){
    print("Something went wrong!");
}

It's also possible to determine what, exactly, went wrong. The 'e' in the catch statement (which, by the way, you cannot omit) is actually an object containing information about the exception! We can access some of the basic properties of this object:

try{
    print(asdf);
}
catch(e){
    print("Something went wrong!");
    print(e.name);
    print(e.message);
}

This will print a message similar to what would be printed if you hadn't caught the exception, but without exiting the program!

Combining readline, eval, exceptions, and print, we can write a simple shell, allowing interactive use of Seed. This shell is included in the Seed distribution, in examples/repl.js. Looking at the source, you'll note that it takes very little code to implement a shell:

examples/repl.js
#!/usr/bin/env seed

readline = imports.readline;

while(1){
    try{
        print(eval(readline.readline("> ")));
    }
    catch(e){
        print(e.name + " " + e.message);
    }
}

You can (and should!) use this shell in order to experiment with and learn to use Seed.

Getting GTK Going

Thus far in this tutorial, we've been completely ignoring the most useful part of Seed: the ability to use external libraries from within JavaScript. The single most useful of these libraries is GTK, the widget and windowing toolkit used by all GNOME applications, which will provide the ability to create and manipulate graphical windows, as well as just about any sort of widget you should require.

In order to use GTK (or any other external library) in a Seed program, you first have to import the functions from said library. Gtk = imports.gi.Gtk, does this for us. The imports.gi object is a special object which handles importing libraries from introspection data.

Once the library has been imported, all of the imported functions are available on the Gtk object: GTK.init(), etc.

Let's start off the development of our browser by getting GTK working. It takes very little to get a window displayed with Seed:

#!/usr/bin/env seed

Gtk = imports.gi.Gtk;
Gtk.init(null, null);

var window = new Gtk.Window();
window.show_all();

Gtk.main();

If you've ever used GTK from C, you'll notice some similarities here. All of the GTK functions have been mapped into JavaScript in a reasonable way, but it will certainly take a bit to get used to, for example, new Gtk.Window() instead of gtk_window_new().

Executing the above script should give you a window that looks entirely empty and boring, something like the following:

Blank GTK Window
JSON Constructors

Notice that the title of the window is 'seed'. We'll fix that, using another Seed feature: you can use JSON notation to set properties while constructing objects, like so:

var window = new Gtk.Window({title: "Browser"});

This saves a lot of typing from the alternative, conventional method:

var window = new Gtk.Window();
window.set_title("Browser");

You can set any number of properties this way, by separating them by commas ({"title": "Browser", "default-height": 500}, etc.). This method should work for any GObject constructor.

Signals

You'll notice that our program, as it stands, fails to quit when you click the 'Close' button. You can, of course, quit it with Ctrl-C, but this is certainly unacceptable behaviour. To fix it, we'll connect a C function to the signal that gets emitted when the 'Close' button is clicked:

window.signal.hide.connect(Gtk.main_quit);

The signal names are the same as in the GTK documentation, except using underscores instead of dashes between words.

GObject Subclassing

Inheritance is a useful feature of many object-oriented languages which provides a way to create your own classes, extending any existing class, while 'inheriting' those behaviors and properties of your parent class which you do not choose to override. Seed provides an incredibly simple interface in order to subclass GObject classes. In order to make our browser, we'll need a number of subclasses. We'll start with our toolbar; since it's a horizontal collection of elements, let's make it a subclass of Gtk.HBox:

BrowserToolbar = new GType({
    parent: Gtk.HBox.type,
    name: "BrowserToolbar",
    init: function (){
    }
});

You'll notice that the GType takes a JavaScript object. The three most important properties which we'll be using are parent, the type of the 'parent' class, from which our subclass should inherit its default behavior; name, the UpperCamelCase name of our new class; and init, a JavaScript function which is called each time a new instance of the class is made.

Working with Widgets

We'll start by making the BrowserToolbar's buttons. GTK provides a ToolButton widget, which is generally used for making such toolbars, as well as various different stock icons (to ensure consistency within all GTK applications). Browsing through the GTK Stock Item documentation, we find that we're looking for "gtk-go-back", "gtk-go-forward", and "gtk-refresh". A glance at the GtkToolButton documentation shows us that we can choose a stock icon by setting the stock-id property - we'll use JSON constructors to keep things tidy. Do note that we use underscores instead of dashes, because the property name isn't quoted (thus, a dash would indicate subtraction, which isn't what we're looking for!):

BrowserToolbar = new GType({
    parent: Gtk.HBox.type,
    name: "BrowserToolbar",
    init: function (){
        // Private
        var url_bar = new Gtk.Entry();

        var back_button = new Gtk.ToolButton({stock_id:"gtk-go-back"});
        var forward_button = new Gtk.ToolButton({stock_id:"gtk-go-forward"});
        var refresh_button = new Gtk.ToolButton({stock_id:"gtk-refresh"});

        // Implementation
        this.pack_start(back_button);
        this.pack_start(forward_button);
        this.pack_start(refresh_button);
        this.pack_start(url_bar, true, true);
    }
});

There are a few things in the snippet above which you probably haven't seen before (unless you've used GTK in another language). Firstly, the Gtk.Entry widget is a simple text entry field, like you would expect in a browser's URL bar. Secondly, you'll notice the use of the Gtk.HBox widget's pack_start() function. This serves as the foundation of GUI layout in GTK: a window is subdivided into boxes, which 'pack' widgets in a particular direction (HBoxes pack horizontally, VBoxes pack vertically, as expected). We use a HBox, since we want our toolbar arranged horizontally. pack_start() adds a widget to a Box; widgets are packed in the order they're added. There are optional arguments, which are addressed in more depth in the GtkBox documentation, which allow you to force widgets to expand into the usable space (the second and third arguments used when packing url_bar above serve this purpose).

To try and get a more visual feel of packing, let's take a look at the Box layout for our browser:

Packing Layout
Callbacks Galore

We also need a bunch of callbacks (for all three buttons, and for when you're done entering text in the URL bar). We'll make them just print the function they're supposed to perform, for now, since we don't have a WebKit view to operate on yet. Let's make them private members of the BrowserToolbar class, and connect them to the appropriate signals:

BrowserToolbar = new GType({
    parent: Gtk.HBox.type,
    name: "BrowserToolbar",
    init: function (){
        // Private
        var url_bar = new Gtk.Entry();

        var back_button = new Gtk.ToolButton({stock_id:"gtk-go-back"});
        var forward_button = new Gtk.ToolButton({stock_id:"gtk-go-forward"});
        var refresh_button = new Gtk.ToolButton({stock_id:"gtk-refresh"});

        var back = function (){
            print("Go Back");
        };

        var forward = function (){
            print("Go Forward");
        };

        var refresh = function (){
            print("Refresh");
        };

        var browse = function (url){
            print("Navigate to: " + url.text);
        };

        // Implementation
        back_button.signal.clicked.connect(back);
        forward_button.signal.clicked.connect(forward);
        refresh_button.signal.clicked.connect(refresh);
        url_bar.signal.activate.connect(browse);

        this.pack_start(back_button);
        this.pack_start(forward_button);
        this.pack_start(refresh_button);
        this.pack_start(url_bar, true, true);
    }
});

You'll notice that right now, nothing's creating a BrowserToolbar, so if you execute your application, you won't see the toolbar drawn. To remedy this, before window.show_all(), add lines to create and pack the toolbar:

toolbar = new BrowserToolbar();
window.add(toolbar);

Your code should be in a runnable state now; take a minute to try it out, stand back, and admire what you've learned:

GTK Window with buttons and text entry field

If, for some reason, something doesn't work, compare your code to the tutorial version.

Adding WebKit

It's finally time to start displaying some web pages with our little browser! Let's create and pack a WebKit.WebView below our toolbar, first. We should make a WebView subclass to use, to initialize some settings and provide an encapsulated interface to our browser view.

A quick note about WebKit: if you omit the protocol part of a URL (e.g., http://), WebKit won't even bother to try to figure it out - so make sure you specify it! We'll add a browse function to our subclass, as well as a callback when the WebView's URL changes, so we can update the URL bar. To get around this shortcoming, we'll use JavaScript's string search function to see if a protocol has been specified, and, if it hasn't, we'll assume it's "http://".

Poking around in the WebKit documentation (the WebKit team is a bit behind on documentation, so all we have to work with is header files), we find that the open() function on a WebView allows you to navigate to a particular page. We'll use this in our implementation of the WebView.browse() function below.

Here's an early version of our new BrowserView subclass:

BrowserView = new GType({
    parent: WebKit.WebView.type,
    name: "BrowserView",
    init: function (){
        // Private
        var update_url = function (web_view, web_frame){
            var toolbar = browser.get_toolbar();

            toolbar.set_url(web_frame.get_uri());
            toolbar.set_can_go_back(web_view.can_go_back());
            toolbar.set_can_go_forward(web_view.can_go_forward());
        };

        // Public
        this.browse = function (url){
            if(url.search("://") < 0)
                url = "http://" + url;

            this.open(url);
        };

        // Implementation
        this.set_scroll_adjustments(null, null);
        this.signal.load_committed.connect(update_url);
    }
});

You'll notice that we also turned off WebKit's automatic scrollbars, with the set_scroll_adjustments function. We do this in order to get smooth scrolling, by wrapping the WebView in a Gtk.ScrolledWindow, as you'll see shortly.

Also, remember that we need to import a namespace before its functions are available to us! So, go back to the top of the file and import "WebKit", just after you import "Gtk". One final thing, before you again try to run your browser: we haven't yet specified a 'recommended' size for our window - let's go ahead and do that (if we didn't do so, the WebKit view would have no space to fill!). Just after you create the Gtk.Window(), add:

window.resize(600,600);
Pulling it all together...

As you can see in the last bit of code, we have a few more functions to add to our BrowserToolbar class. Functions to allow toggling the 'clickable' state of the back and forward buttons, and a function to update the URL bar when a link is clicked. We will also update the button callbacks with what we find while again browsing webkitwebview.h: reload(), go_forward(), and go_back().

BrowserToolbar = new GType({
    parent: Gtk.HBox.type,
    name: "BrowserToolbar",
    init: function (){
        // Private
        var url_bar = new Gtk.Entry();

        var back_button = new Gtk.ToolButton({stock_id:"gtk-go-back"});
        var forward_button = new Gtk.ToolButton({stock_id:"gtk-go-forward"});
        var refresh_button = new Gtk.ToolButton({stock_id:"gtk-refresh"});

        var back = function (){
            browser.get_web_view().go_back();
        };

        var forward = function (){
            browser.get_web_view().go_forward();
        };

        var refresh = function (){
            browser.get_web_view().reload();
        };

        var browse = function (url){
            browser.get_web_view().browse(url.text);
        };

        // Public
        this.set_url = function (url){
            url_bar.text = url;
        };

        this.set_can_go_back = function (can_go_back){
            back_button.sensitive = can_go_back;
        };

        this.set_can_go_forward = function (can_go_forward){
            forward_button.sensitive = can_go_forward;
        };

        // Implementation
        back_button.signal.clicked.connect(back);
        forward_button.signal.clicked.connect(forward);
        refresh_button.signal.clicked.connect(refresh);
        url_bar.signal.activate.connect(browse);

        this.pack_start(back_button);
        this.pack_start(forward_button);
        this.pack_start(refresh_button);
        this.pack_start(url_bar, true, true);
    }
});

One last thing! We need a Browser class, a subclass of Gtk.VBox, to contain a BrowserToolbar and BrowserView, and to provide functions from which to access these widgets. We'll also set up the Gtk.ScrolledWindow which we discussed earlier:

Browser = new GType({
    parent: Gtk.VBox.type,
    name: "Browser",
    init: function (){
        // Private
        var toolbar = new BrowserToolbar();
        var web_view = new BrowserView();
        var scroll_view = new Gtk.ScrolledWindow();

        // Public
        this.get_toolbar = function (){
            return toolbar;
        };

        this.get_web_view = function (){
            return web_view;
        };

        // Implementation
        scroll_view.smooth_scroll = true;
        scroll_view.add(web_view);
        scroll_view.set_policy(Gtk.PolicyType.AUTOMATIC,
                               Gtk.PolicyType.AUTOMATIC);

        this.pack_start(toolbar);
        this.pack_start(scroll_view, true, true);
        this.show_all();
    }
});

One final thing: we need to create a Browser object, and add it to the window, now, instead of a BrowserToolbar. The Browser object will contain a BrowserToolbar and a BrowserView. So, change the section near the bottom of the file from:

toolbar = new BrowserToolbar();
window.add(toolbar);

into:

browser = new Browser();
browser.get_web_view().browse(home_page);
window.add(browser);

You'll notice we navigate to home_page. Assign home_page to your favorite web site at the top of the file; perhaps even make a section at the top of the file of browser settings (I'm sure you can think of other things to implement as settings!)

If all goes well, your browser should now be in a working state. Start it up - it ought to look much like the following:

GTK Window with toolbar and browser view at GNOME.org

The final version of the tutorial's source code is available if you're having trouble; if, however, you made easy work of the tutorial, you should consider making some improvements to your browser: change the window title when the web page title changes (look at the title_changed signal!); add tabs (GtkNotebook is probably what you're looking for); bookmarks are often useful!; perhaps a status menu? Or, go ahead and write your own application in Seed!

seed-webkit2-4.0.0+20161014+6c77960+dfsg1/examples000066400000000000000000000002321303774616400203640ustar00rootroot00000000000000Seed's examples now live in the seed-examples repository at GNOME Git: git://git.gnome.org/seed-examples ssh://USERNAME@git.gnome.org/git/seed-examples seed-webkit2-4.0.0+20161014+6c77960+dfsg1/git.mk000066400000000000000000000265551303774616400177570ustar00rootroot00000000000000# git.mk, a small Makefile to autogenerate .gitignore files # for autotools-based projects. # # Copyright 2009, Red Hat, Inc. # Copyright 2010,2011,2012,2013 Behdad Esfahbod # Written by Behdad Esfahbod # # Copying and distribution of this file, with or without modification, # is permitted in any medium without royalty provided the copyright # notice and this notice are preserved. # # The latest version of this file can be downloaded from: GIT_MK_URL = https://raw.githubusercontent.com/behdad/git.mk/master/git.mk # # Bugs, etc, should be reported upstream at: # https://github.com/behdad/git.mk # # To use in your project, import this file in your git repo's toplevel, # then do "make -f git.mk". This modifies all Makefile.am files in # your project to -include git.mk. Remember to add that line to new # Makefile.am files you create in your project, or just rerun the # "make -f git.mk". # # This enables automatic .gitignore generation. If you need to ignore # more files, add them to the GITIGNOREFILES variable in your Makefile.am. # But think twice before doing that. If a file has to be in .gitignore, # chances are very high that it's a generated file and should be in one # of MOSTLYCLEANFILES, CLEANFILES, DISTCLEANFILES, or MAINTAINERCLEANFILES. # # The only case that you need to manually add a file to GITIGNOREFILES is # when remove files in one of mostlyclean-local, clean-local, distclean-local, # or maintainer-clean-local make targets. # # Note that for files like editor backup, etc, there are better places to # ignore them. See "man gitignore". # # If "make maintainer-clean" removes the files but they are not recognized # by this script (that is, if "git status" shows untracked files still), send # me the output of "git status" as well as your Makefile.am and Makefile for # the directories involved and I'll diagnose. # # For a list of toplevel files that should be in MAINTAINERCLEANFILES, see # Makefile.am.sample in the git.mk git repo. # # Don't EXTRA_DIST this file. It is supposed to only live in git clones, # not tarballs. It serves no useful purpose in tarballs and clutters the # build dir. # # This file knows how to handle autoconf, automake, libtool, gtk-doc, # gnome-doc-utils, yelp.m4, mallard, intltool, gsettings, dejagnu, appdata, # appstream, hotdoc. # # This makefile provides the following targets: # # - all: "make all" will build all gitignore files. # - gitignore: makes all gitignore files in the current dir and subdirs. # - .gitignore: make gitignore file for the current dir. # - gitignore-recurse: makes all gitignore files in the subdirs. # # KNOWN ISSUES: # # - Recursive configure doesn't work as $(top_srcdir)/git.mk inside the # submodule doesn't find us. If you have configure.{in,ac} files in # subdirs, add a proxy git.mk file in those dirs that simply does: # "include $(top_srcdir)/../git.mk". Add more ..'s to your taste. # And add those files to git. See vte/gnome-pty-helper/git.mk for # example. # ############################################################################### # Variables user modules may want to add to toplevel MAINTAINERCLEANFILES: ############################################################################### # # Most autotools-using modules should be fine including this variable in their # toplevel MAINTAINERCLEANFILES: GITIGNORE_MAINTAINERCLEANFILES_TOPLEVEL = \ $(srcdir)/aclocal.m4 \ $(srcdir)/autoscan.log \ $(srcdir)/configure.scan \ `AUX_DIR=$(srcdir)/$$(cd $(top_srcdir); $(AUTOCONF) --trace 'AC_CONFIG_AUX_DIR:$$1' ./configure.ac); \ test "x$$AUX_DIR" = "x$(srcdir)/" && AUX_DIR=$(srcdir); \ for x in \ ar-lib \ compile \ config.guess \ config.rpath \ config.sub \ depcomp \ install-sh \ ltmain.sh \ missing \ mkinstalldirs \ test-driver \ ylwrap \ ; do echo "$$AUX_DIR/$$x"; done` \ `cd $(top_srcdir); $(AUTOCONF) --trace 'AC_CONFIG_HEADERS:$$1' ./configure.ac | \ head -n 1 | while read f; do echo "$(srcdir)/$$f.in"; done` # # All modules should also be fine including the following variable, which # removes automake-generated Makefile.in files: GITIGNORE_MAINTAINERCLEANFILES_MAKEFILE_IN = \ `cd $(top_srcdir); $(AUTOCONF) --trace 'AC_CONFIG_FILES:$$1' ./configure.ac | \ while read f; do \ case $$f in Makefile|*/Makefile) \ test -f "$(srcdir)/$$f.am" && echo "$(srcdir)/$$f.in";; esac; \ done` # # Modules that use libtool and use AC_CONFIG_MACRO_DIR() may also include this, # though it's harmless to include regardless. GITIGNORE_MAINTAINERCLEANFILES_M4_LIBTOOL = \ `MACRO_DIR=$(srcdir)/$$(cd $(top_srcdir); $(AUTOCONF) --trace 'AC_CONFIG_MACRO_DIR:$$1' ./configure.ac); \ if test "x$$MACRO_DIR" != "x$(srcdir)/"; then \ for x in \ libtool.m4 \ ltoptions.m4 \ ltsugar.m4 \ ltversion.m4 \ lt~obsolete.m4 \ ; do echo "$$MACRO_DIR/$$x"; done; \ fi` ############################################################################### # Default rule is to install ourselves in all Makefile.am files: ############################################################################### git-all: git-mk-install git-mk-install: @echo "Installing git makefile" @any_failed=; \ find "`test -z "$(top_srcdir)" && echo . || echo "$(top_srcdir)"`" -name Makefile.am | while read x; do \ if grep 'include .*/git.mk' $$x >/dev/null; then \ echo "$$x already includes git.mk"; \ else \ failed=; \ echo "Updating $$x"; \ { cat $$x; \ echo ''; \ echo '-include $$(top_srcdir)/git.mk'; \ } > $$x.tmp || failed=1; \ if test x$$failed = x; then \ mv $$x.tmp $$x || failed=1; \ fi; \ if test x$$failed = x; then : else \ echo "Failed updating $$x"; >&2 \ any_failed=1; \ fi; \ fi; done; test -z "$$any_failed" git-mk-update: wget $(GIT_MK_URL) -O $(top_srcdir)/git.mk .PHONY: git-all git-mk-install git-mk-update ############################################################################### # Actual .gitignore generation: ############################################################################### $(srcdir)/.gitignore: Makefile.am $(top_srcdir)/git.mk @echo "git.mk: Generating $@" @{ \ if test "x$(DOC_MODULE)" = x -o "x$(DOC_MAIN_SGML_FILE)" = x; then :; else \ for x in \ $(DOC_MODULE)-decl-list.txt \ $(DOC_MODULE)-decl.txt \ tmpl/$(DOC_MODULE)-unused.sgml \ "tmpl/*.bak" \ $(REPORT_FILES) \ $(DOC_MODULE).pdf \ xml html \ ; do echo "/$$x"; done; \ FLAVOR=$$(cd $(top_srcdir); $(AUTOCONF) --trace 'GTK_DOC_CHECK:$$2' ./configure.ac); \ case $$FLAVOR in *no-tmpl*) echo /tmpl;; esac; \ if echo "$(SCAN_OPTIONS)" | grep -q "\-\-rebuild-types"; then \ echo "/$(DOC_MODULE).types"; \ fi; \ if echo "$(SCAN_OPTIONS)" | grep -q "\-\-rebuild-sections"; then \ echo "/$(DOC_MODULE)-sections.txt"; \ fi; \ if test "$(abs_srcdir)" != "$(abs_builddir)" ; then \ for x in \ $(SETUP_FILES) \ $(DOC_MODULE).types \ ; do echo "/$$x"; done; \ fi; \ fi; \ if test "x$(DOC_MODULE)$(DOC_ID)" = x -o "x$(DOC_LINGUAS)" = x; then :; else \ for lc in $(DOC_LINGUAS); do \ for x in \ $(if $(DOC_MODULE),$(DOC_MODULE).xml) \ $(DOC_PAGES) \ $(DOC_INCLUDES) \ ; do echo "/$$lc/$$x"; done; \ done; \ for x in \ $(_DOC_OMF_ALL) \ $(_DOC_DSK_ALL) \ $(_DOC_HTML_ALL) \ $(_DOC_MOFILES) \ $(DOC_H_FILE) \ "*/.xml2po.mo" \ "*/*.omf.out" \ ; do echo /$$x; done; \ fi; \ if test "x$(HOTDOC)" = x; then :; else \ $(foreach project, $(HOTDOC_PROJECTS),echo "/$(call HOTDOC_TARGET,$(project))"; \ echo "/$(shell $(call HOTDOC_PROJECT_COMMAND,$(project)) --get-conf-path output)" ; \ echo "/$(shell $(call HOTDOC_PROJECT_COMMAND,$(project)) --get-private-folder)" ; \ ) \ for x in \ .hotdoc.d \ ; do echo "/$$x"; done; \ fi; \ if test "x$(HELP_ID)" = x -o "x$(HELP_LINGUAS)" = x; then :; else \ for lc in $(HELP_LINGUAS); do \ for x in \ $(HELP_FILES) \ "$$lc.stamp" \ "$$lc.mo" \ ; do echo "/$$lc/$$x"; done; \ done; \ fi; \ if test "x$(gsettings_SCHEMAS)" = x; then :; else \ for x in \ $(gsettings_SCHEMAS:.xml=.valid) \ $(gsettings__enum_file) \ ; do echo "/$$x"; done; \ fi; \ if test "x$(appdata_XML)" = x; then :; else \ for x in \ $(appdata_XML:.xml=.valid) \ ; do echo "/$$x"; done; \ fi; \ if test "x$(appstream_XML)" = x; then :; else \ for x in \ $(appstream_XML:.xml=.valid) \ ; do echo "/$$x"; done; \ fi; \ if test -f $(srcdir)/po/Makefile.in.in; then \ for x in \ ABOUT-NLS \ po/Makefile.in.in \ po/Makefile.in.in~ \ po/Makefile.in \ po/Makefile \ po/Makevars.template \ po/POTFILES \ po/Rules-quot \ po/stamp-it \ po/stamp-po \ po/.intltool-merge-cache \ "po/*.gmo" \ "po/*.header" \ "po/*.mo" \ "po/*.sed" \ "po/*.sin" \ po/$(GETTEXT_PACKAGE).pot \ intltool-extract.in \ intltool-merge.in \ intltool-update.in \ ; do echo "/$$x"; done; \ fi; \ if test -f $(srcdir)/configure; then \ for x in \ autom4te.cache \ configure \ config.h \ stamp-h1 \ libtool \ config.lt \ ; do echo "/$$x"; done; \ fi; \ if test "x$(DEJATOOL)" = x; then :; else \ for x in \ $(DEJATOOL) \ ; do echo "/$$x.sum"; echo "/$$x.log"; done; \ echo /site.exp; \ fi; \ if test "x$(am__dirstamp)" = x; then :; else \ echo "$(am__dirstamp)"; \ fi; \ if test "x$(findstring libtool,$(LTCOMPILE))" = x -a "x$(findstring libtool,$(LTCXXCOMPILE))" = x -a "x$(GTKDOC_RUN)" = x; then :; else \ for x in \ "*.lo" \ ".libs" "_libs" \ ; do echo "$$x"; done; \ fi; \ for x in \ .gitignore \ $(GITIGNOREFILES) \ $(CLEANFILES) \ $(PROGRAMS) $(check_PROGRAMS) $(EXTRA_PROGRAMS) \ $(LIBRARIES) $(check_LIBRARIES) $(EXTRA_LIBRARIES) \ $(LTLIBRARIES) $(check_LTLIBRARIES) $(EXTRA_LTLIBRARIES) \ so_locations \ $(MOSTLYCLEANFILES) \ $(TEST_LOGS) \ $(TEST_LOGS:.log=.trs) \ $(TEST_SUITE_LOG) \ $(TESTS:=.test) \ "*.gcda" \ "*.gcno" \ $(DISTCLEANFILES) \ $(am__CONFIG_DISTCLEAN_FILES) \ $(CONFIG_CLEAN_FILES) \ TAGS ID GTAGS GRTAGS GSYMS GPATH tags \ "*.tab.c" \ $(MAINTAINERCLEANFILES) \ $(BUILT_SOURCES) \ $(patsubst %.vala,%.c,$(filter %.vala,$(SOURCES))) \ $(filter %_vala.stamp,$(DIST_COMMON)) \ $(filter %.vapi,$(DIST_COMMON)) \ $(filter $(addprefix %,$(notdir $(patsubst %.vapi,%.h,$(filter %.vapi,$(DIST_COMMON))))),$(DIST_COMMON)) \ Makefile \ Makefile.in \ "*.orig" \ "*.rej" \ "*.bak" \ "*~" \ ".*.sw[nop]" \ ".dirstamp" \ ; do echo "/$$x"; done; \ for x in \ "*.$(OBJEXT)" \ $(DEPDIR) \ ; do echo "$$x"; done; \ } | \ sed "s@^/`echo "$(srcdir)" | sed 's/\(.\)/[\1]/g'`/@/@" | \ sed 's@/[.]/@/@g' | \ LC_ALL=C sort | uniq > $@.tmp && \ mv $@.tmp $@; all: $(srcdir)/.gitignore gitignore-recurse-maybe gitignore: $(srcdir)/.gitignore gitignore-recurse gitignore-recurse-maybe: @for subdir in $(DIST_SUBDIRS); do \ case " $(SUBDIRS) " in \ *" $$subdir "*) :;; \ *) test "$$subdir" = . -o -e "$$subdir/.git" || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) gitignore || echo "Skipping $$subdir");; \ esac; \ done gitignore-recurse: @for subdir in $(DIST_SUBDIRS); do \ test "$$subdir" = . -o -e "$$subdir/.git" || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) gitignore || echo "Skipping $$subdir"); \ done maintainer-clean: gitignore-clean gitignore-clean: -rm -f $(srcdir)/.gitignore .PHONY: gitignore-clean gitignore gitignore-recurse gitignore-recurse-maybe seed-webkit2-4.0.0+20161014+6c77960+dfsg1/jsextensions/000077500000000000000000000000001303774616400213625ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/jsextensions/Clutter.js000066400000000000000000000034421303774616400233450ustar00rootroot00000000000000Clutter = imports.gi.Clutter; var animations = new Array(); Clutter.Actor.prototype.animate = function(mode, duration, json) { var properties = new Array(); var endvalues = new Array(); for (var prop in json){ properties.push(prop); endvalues.push(new Array(this.__property_type(prop), json[prop])); } var animation = this.animatev(mode, duration, properties.length, properties, endvalues); animations.push(animation); animation.timeline.signal["completed"].connect( function(timeline, obj){ animations.splice(animations.indexOf(animation),1); }, this); return animation; } Clutter.Actor.prototype.animate_with_timeline = function(mode, timeline, json) { var properties = new Array(); var endvalues = new Array(); for (var prop in json) { properties.push(prop); endvalues.push(new Array(this.__property_type(prop), json[prop])); } var animation = this.animate_with_timelinev(mode, timeline, properties.length, properties, endvalues); animations.push(animation); animation.timeline.signal["completed"].connect( function(timeline, obj){ animations.splice(animations.indexOf(animation),1); }, this); return animation; } Clutter.Actor.prototype.animate_with_alpha = function(alpha, json) { var properties = new Array(); var endvalues = new Array(); for (var prop in json) { properties.push(prop); endvalues.push(new Array(this.__property_type(prop), json[prop])); } var animation = this.animate_with_alphav(alpha, properties.length, properties, endvalues); animations.push(animation); animation.timeline.signal["completed"].connect( function(timeline, obj){ animations.splice(animations.indexOf(animation),1); }, this); return animation; } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/jsextensions/GLib.js000066400000000000000000000177201303774616400225440ustar00rootroot00000000000000GLib = imports.gi.GLib; (function() { /* Variant Sugar * Provide commodities methods to convert Variant from/to javascript object. * variant.toJS() : returns a javascript object representing the Variant # @variant * Variant.new(signature, value): returns a GVariant structure representing * the javascript object @value * * This implementation uses json-glib's json <-> variant conversion facilities * if presents and fallback to a javascript implementation otherwise. * This javascript implementation is imported from gjs with modification for * JSCore compatibility (Copyright 2011 Giovanni Campagna, * see gjs/override/GLib.js for licence) */ // Use json-glib's json <-> variant conversion if present. // Defaults to javascript code imported from gjs otherwise. GLib.Variant.prototype.to_js = function(signature) { return _toJS(signature, this); } var toVariant = _toVariant; try { JSONGLib = imports.gi.Json; } catch (e) {} if (JSONGLib && JSONGLib.gvariant_serialize_data) { GLib.Variant.prototype.to_js = function(signature) { return _toJSNative(signature, this); } toVariant = _toVariantNative; } GLib.Variant.new = function (value, sig) { var signature = Array.prototype.slice.call(sig); if (signature.length != 0) throw new TypeError('Invalid GVariant signature (more than one single complete type)'); var variant = toVariant(signature, value); return variant; } GLib.Variant.prototype.toString = function() { return '[object variant of type "' + this.get_type_string() + '"]'; }; /// End Variant Sugar /// }).apply(); function _toVariantNative(signature, object) { if (!object || object == '') return null; if (!signature || signature == '') signature = null; return JSONGLib.gvariant_deserialize_data (JSON.stringify (object), -1, signature); }; function _toJSNative(signature, variant) { if (!variant) return; var jsonStr = JSONGLib.gvariant_serialize_data (variant, signature); if (!jsonStr) return; return JSON.parse (jsonStr); }; // Code imported from gjs, modified for JSCore idoms. // Copyright 2011 Giovanni Campagna (see gjs/override/GLib.js for licence) const SIMPLE_TYPES = ['b', 'y', 'n', 'q', 'i', 'u', 'x', 't', 'h', 'd', 's', 'o', 'g']; function _read_single_type(signature, forceSimple) { var char = signature.shift(); var isSimple = false; if (SIMPLE_TYPES.indexOf(char) == -1) { if (forceSimple) throw new TypeError('Invalid GVariant signature (a simple type was expected)'); } else isSimple = true; if (char == 'm' || char == 'a') return [char].concat(_read_single_type(signature, false)); if (char == '{') { var key = _read_single_type(signature, true); var val = _read_single_type(signature, false); var close = signature.shift(); if (close != '}') throw new TypeError('Invalid GVariant signature for type DICT_ENTRY (expected "}"'); return [char].concat(key, val, close); } if (char == '(') { var res = [char]; while (true) { if (signature.length == 0) throw new TypeError('Invalid GVariant signature for type TUPLE (expected ")")'); var next = signature[0]; if (next == ')') { signature.shift(); return res.concat(next); } var el = _read_single_type(signature); res = res.concat(el); } } // Valid types are simple types, arrays, maybes, tuples, dictionary entries and variants if (!isSimple && char != 'v') throw new TypeError('Invalid GVariant signature (' + char + ' is not a valid type)'); return [char]; } function _toVariant(signature, value) { if (signature.length == 0) throw new TypeError('GVariant signature cannot be empty'); var char = signature.shift(); switch (char) { case 'b': return GLib.Variant.new_boolean(value); case 'y': return GLib.Variant.new_byte(value); case 'n': return GLib.Variant.new_int16(value); case 'q': return GLib.Variant.new_uint16(value); case 'i': return GLib.Variant.new_int32(value); case 'u': return GLib.Variant.new_uint32(value); case 'x': return GLib.Variant.new_int64(value); case 't': return GLib.Variant.new_uint64(value); case 'h': return GLib.Variant.new_handle(value); case 'd': return GLib.Variant.new_double(value); case 's': return GLib.Variant.new_string(value); case 'o': return GLib.Variant.new_object_path(value); case 'g': return GLib.Variant.new_signature(value); case 'v': return GLib.Variant.new_variant(value); case 'm': if (value != null) return GLib.Variant.new_maybe(null, _pack_variant(signature, value)) else return GLib.Variant.new_maybe(GLib.VariantType.new(_read_single_type(signature, false).join('')), null); case 'a': var arrayType = _read_single_type(signature, false); if (arrayType[0] == 's') { // special case for array of strings return GLib.Variant.new_strv(value, value.length); } if (arrayType[0] == 'y') { // special case for array of bytes return GLib.Variant.new_bytestring(value); } if (arrayType[0] == 'a' && arrayType[1] == 'y') { // special case for array of array of bytes return GLib.Variant.new_bytestring_array(value, value.length); } var arrayValue = []; if (arrayType[0] == '{') { // special case for dictionaries for (var key in value) { var copy = [].concat(arrayType); var child = _pack_variant(copy, [key, value[key]]); arrayValue.push(child); } } else { for (var i = 0; i < value.length; i++) { var copy = [].concat(arrayType); var child = _pack_variant(copy, value[i]); arrayValue.push(child); } } return GLib.Variant.new_array(GLib.VariantType.new(arrayType.join('')), arrayValue, arrayValue.length); case '(': var children = [ ]; for (var i = 0; i < value.length; i++) { var next = signature[0]; if (next == ')') break; children.push(_pack_variant(signature, value[i])); } if (signature[0] != ')') throw new TypeError('Invalid GVariant signature for type TUPLE (expected ")")'); signature.shift(); return GLib.Variant.new_tuple(children, children.length); case '{': var key = _pack_variant(signature, value[0]); var child = _pack_variant(signature, value[1]); if (signature[0] != '}') throw new TypeError('Invalid GVariant signature for type DICT_ENTRY (expected "}")'); signature.shift(); return GLib.Variant.new_dict_entry(key, child); default: throw new TypeError('Invalid GVariant signature (unexpected character ' + char + ')'); } } function _toJS(signature, variant) { switch (String.fromCharCode(variant.classify())) { case 'b': return variant.get_boolean(); case 'y': return variant.get_byte(); case 'n': return variant.get_int16(); case 'q': return variant.get_uint16(); case 'i': return variant.get_int32(); case 'u': return variant.get_uint32(); case 'x': return variant.get_int64(); case 't': return variant.get_uint64(); case 'h': return variant.get_handle(); case 'd': return variant.get_double(); case 'o': case 'g': case 's': // g_variant_get_string has length as out argument return variant.get_string(); case 'v': return variant.get_variant(); case 'm': var val = variant.get_maybe(); return _toJS(val); case 'a': if (variant.is_container()) { // special case containers var ret = { }; var nElements = variant.n_children(); for (var i = 0; i < nElements; i++) { // always unpack the dictionary entry, and always unpack // the key (or it cannot be added as a key) var val = _toJS(variant.get_child_value(i)); var key = val[0].classify ? _toJS(val[0]) : val[0]; ret[key] = val[1] && val[1].classify ? _toJS(val[1]) : val[1] } return ret; } // fall through case '(': case '{': var ret = [ ]; var nElements = variant.n_children(); for (var i = 0; i < nElements; i++) { var val = variant.get_child_value(i); ret.push(_toJS(val)); } return ret; } throw new Error('Assertion failure: this code should not be reached'); } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/jsextensions/GObject.js000066400000000000000000000016471303774616400232450ustar00rootroot00000000000000GObject = imports.gi.GObject; (function() { var types = [{name:"NONE", fundamental: 1}, {name:"INTERFACE", fundamental: 2}, {name:"CHAR", fundamental: 3}, {name:"UCHAR", fundamental: 4}, {name:"BOOLEAN", fundamental: 5}, {name:"INT", fundamental: 6}, {name:"UINT", fundamental: 7}, {name:"LONG", fundamental: 8}, {name:"ULONG", fundamental: 9}, {name:"INT64", fundamental: 10}, {name:"UINT64", fundamental: 11}, {name:"ENUM", fundamental: 12}, {name:"FLAGS", fundamental: 13}, {name:"FLOAT", fundamental: 14}, {name:"DOUBLE", fundamental: 15}, {name:"STRING", fundamental: 16}, {name:"POINTER", fundamental: 17}, {name:"BOXED", fundamental: 18}, {name:"PARAM", fundamental: 19}, {name:"OBJECT", fundamental: 20}]; for (var i = 0; i < types.length; i++) { GObject["TYPE_"+types[i].name] = types[i].fundamental << 2; } }).apply(); seed-webkit2-4.0.0+20161014+6c77960+dfsg1/jsextensions/Gio.js000066400000000000000000000014411303774616400224360ustar00rootroot00000000000000Gio = imports.gi.Gio; (function() { var prototype = Gio.FileInputStream.prototype; prototype.get_contents = function() { var stream = new Gio.DataInputStream.c_new(this); var line = stream.read_until("", 0); return line; } Gio.simple_write = function(file, name) { var file = Gio.file_new_for_path(file); var fstream = file.replace(); var dstream = new Gio.DataOutputStream.c_new(fstream); dstream.put_string(name); fstream.close(); } Gio.simple_read = function(name) { var file = Gio.file_new_for_path(name); var fstream = file.read(); var dstream = new Gio.DataInputStream.c_new(fstream); var line = dstream.read_until("", 0); fstream.close(); return line; } }).apply(); seed-webkit2-4.0.0+20161014+6c77960+dfsg1/jsextensions/Gst.js000066400000000000000000000003001303774616400224460ustar00rootroot00000000000000Gst = imports.gi.Gst; Gst.Element.prototype.link_many = function(){ this.link(arguments[0]); for (var i = 0; i < arguments.length-1; i++){ arguments[i].link(arguments[i+1]); } } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/jsextensions/Gtk.js000066400000000000000000000015751303774616400224550ustar00rootroot00000000000000Gtk = imports.gi.Gtk; (function() { var pack = function(packing) { for ( var i in packing ) { var entry = packing[i]; var expand = entry["expand"]; var padding = entry["padding"]; var fill = entry["fill"]; var child = entry["child"]; var position = entry["position"]; if (position == null) position = Gtk.PackType.START; this.pack_start(child); this.set_child_packing(child, expand, fill, padding, position); } } Gtk.VBox.prototype.pack = pack; Gtk.HBox.prototype.pack = pack; }).apply(); (function() { var add_from_string = function(str) { this.add_from_string_c(str, str.length); } Gtk.Builder.prototype.add_from_string_c = Gtk.Builder.prototype.add_from_string; Gtk.Builder.prototype.add_from_string = add_from_string; }).apply(); seed-webkit2-4.0.0+20161014+6c77960+dfsg1/jsextensions/Makefile.am000066400000000000000000000014661303774616400234250ustar00rootroot00000000000000js_files = \ Clutter.js \ gjs/Gtk.js \ gjs/GObject.js \ gjs/Gio.js \ gjs/GLib.js \ GObject.js \ Gio.js \ Gst.js \ GLib.js \ Gtk.js \ repl.js \ $(NULL) resources = \ $(js_files) \ Seed.js \ $(NULL) Seed.js: Seed.js.in $(AM_V_GEN) $(SED) -e "s|%pkglibdir%|$(pkglibdir)@SEED_GTK_VERSION@|" -e "s|%pkgdatadir%|$(pkgdatadir)@SEED_GTK_VERSION@|" -e "s|%gnomejsdir%|$(GNOME_JS_DIR)|" $< > $@ libseed-resources.c: libseed.gresources.xml Seed.js $(resources) $(GLIB_COMPILE_RESOURCES) $(top_srcdir)/jsextensions/libseed.gresources.xml --target=$@ --sourcedir=$(top_srcdir)/jsextensions --sourcedir=. --generate-source BUILT_SOURCES = \ libseed-resources.c \ Seed.js \ $(NULL) CLEANFILES = $(BUILT_SOURCES) EXTRA_DIST = \ libseed.gresources.xml \ Seed.js.in \ $(js_files) -include $(top_srcdir)/git.mk seed-webkit2-4.0.0+20161014+6c77960+dfsg1/jsextensions/Seed.js.in000066400000000000000000000152561303774616400232160ustar00rootroot00000000000000if(!imports.searchPath || (imports.searchPath.length == 0)) { imports.searchPath = [ "/org/seed", "%gnomejsdir%", "%pkglibdir%", "%pkgdatadir%", "/usr/local/lib/seed", "/usr/local/share/seed", "/usr/lib/seed", "/usr/share/seed" ]; const GLib = imports.gi.GLib; if(Seed.argv.length > 1) { __script_path__ = GLib.path_get_dirname(Seed.argv[1]); try { if(!GLib.path_is_absolute(__script_path__)) { __script_path__ = GLib.build_filenamev([GLib.get_current_dir(), __script_path__]); } __script_path__ = imports.os.realpath(__script_path__); if(__script_path__ && __script_path__ != "") imports.searchPath.unshift(__script_path__); } catch(e) { print(imports.JSON.stringify(e)); } } imports.searchPath.unshift("."); var user_paths = GLib.getenv("SEED_MODULE_PATH"); if (user_paths != null) { var i = null; user_paths = user_paths.split(":"); for (i=0; i "); if (item == "continue") return false; print(eval(item)); } catch (e) { print(e.name + " " + e.message); } return true; } Seed.glib_repl = function() { GLib.idle_add(Seed.repl, null); } Seed.thread_repl = function() { GLib.thread_create_full(function() { while(Seed.repl()){} }, null, 0, true); } Seed.printf = function () { print(Seed.sprintf.apply(this, arguments)) }; seed-webkit2-4.0.0+20161014+6c77960+dfsg1/jsextensions/gjs/000077500000000000000000000000001303774616400221455ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/jsextensions/gjs/GLib.js000066400000000000000000000207261303774616400233270ustar00rootroot00000000000000// Copyright 2011 Giovanni Campagna // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. const ByteArray = imports.byteArray; let GLib; let originalVariantClass; const SIMPLE_TYPES = ['b', 'y', 'n', 'q', 'i', 'u', 'x', 't', 'h', 'd', 's', 'o', 'g']; function _read_single_type(signature, forceSimple) { let char = signature.shift(); let isSimple = false; if (SIMPLE_TYPES.indexOf(char) == -1) { if (forceSimple) throw new TypeError('Invalid GVariant signature (a simple type was expected)'); } else isSimple = true; if (char == 'm' || char == 'a') return [char].concat(_read_single_type(signature, false)); if (char == '{') { let key = _read_single_type(signature, true); let val = _read_single_type(signature, false); let close = signature.shift(); if (close != '}') throw new TypeError('Invalid GVariant signature for type DICT_ENTRY (expected "}"'); return [char].concat(key, val, close); } if (char == '(') { let res = [char]; while (true) { if (signature.length == 0) throw new TypeError('Invalid GVariant signature for type TUPLE (expected ")")'); let next = signature[0]; if (next == ')') { signature.shift(); return res.concat(next); } let el = _read_single_type(signature); res = res.concat(el); } } // Valid types are simple types, arrays, maybes, tuples, dictionary entries and variants if (!isSimple && char != 'v') throw new TypeError('Invalid GVariant signature (' + char + ' is not a valid type)'); return [char]; } function _makeBytes(byteArray) { if (byteArray instanceof ByteArray.ByteArray) return byteArray.toGBytes(); else return new GLib.Bytes(byteArray); } function _pack_variant(signature, value) { if (signature.length == 0) throw new TypeError('GVariant signature cannot be empty'); let char = signature.shift(); switch (char) { case 'b': return GLib.Variant.new_boolean(value); case 'y': return GLib.Variant.new_byte(value); case 'n': return GLib.Variant.new_int16(value); case 'q': return GLib.Variant.new_uint16(value); case 'i': return GLib.Variant.new_int32(value); case 'u': return GLib.Variant.new_uint32(value); case 'x': return GLib.Variant.new_int64(value); case 't': return GLib.Variant.new_uint64(value); case 'h': return GLib.Variant.new_handle(value); case 'd': return GLib.Variant.new_double(value); case 's': return GLib.Variant.new_string(value); case 'o': return GLib.Variant.new_object_path(value); case 'g': return GLib.Variant.new_signature(value); case 'v': return GLib.Variant.new_variant(value); case 'm': if (value != null) return GLib.Variant.new_maybe(null, _pack_variant(signature, value)); else return GLib.Variant.new_maybe(new GLib.VariantType(_read_single_type(signature, false).join('')), null); case 'a': let arrayType = _read_single_type(signature, false); if (arrayType[0] == 's') { // special case for array of strings return GLib.Variant.new_strv(value); } if (arrayType[0] == 'y') { // special case for array of bytes return GLib.Variant.new_from_bytes(new GLib.VariantType('ay'), _makeBytes(value), true); } let arrayValue = []; if (arrayType[0] == '{') { // special case for dictionaries for (let key in value) { let copy = [].concat(arrayType); let child = _pack_variant(copy, [key, value[key]]); arrayValue.push(child); } } else { for (let i = 0; i < value.length; i++) { let copy = [].concat(arrayType); let child = _pack_variant(copy, value[i]); arrayValue.push(child); } } return GLib.Variant.new_array(new GLib.VariantType(arrayType.join('')), arrayValue); case '(': let children = [ ]; for (let i = 0; i < value.length; i++) { let next = signature[0]; if (next == ')') break; children.push(_pack_variant(signature, value[i])); } if (signature[0] != ')') throw new TypeError('Invalid GVariant signature for type TUPLE (expected ")")'); signature.shift(); return GLib.Variant.new_tuple(children); case '{': let key = _pack_variant(signature, value[0]); let child = _pack_variant(signature, value[1]); if (signature[0] != '}') throw new TypeError('Invalid GVariant signature for type DICT_ENTRY (expected "}")'); signature.shift(); return GLib.Variant.new_dict_entry(key, child); default: throw new TypeError('Invalid GVariant signature (unexpected character ' + char + ')'); } } function _unpack_variant(variant, deep) { switch (String.fromCharCode(variant.classify())) { case 'b': return variant.get_boolean(); case 'y': return variant.get_byte(); case 'n': return variant.get_int16(); case 'q': return variant.get_uint16(); case 'i': return variant.get_int32(); case 'u': return variant.get_uint32(); case 'x': return variant.get_int64(); case 't': return variant.get_uint64(); case 'h': return variant.get_handle(); case 'd': return variant.get_double(); case 'o': case 'g': case 's': // g_variant_get_string has length as out argument return variant.get_string()[0]; case 'v': return variant.get_variant(); case 'm': let val = variant.get_maybe(); if (deep && val) return _unpack_variant(val, deep); else return val; case 'a': if (variant.is_of_type(new GLib.VariantType('a{?*}'))) { // special case containers let ret = { }; let nElements = variant.n_children(); for (let i = 0; i < nElements; i++) { // always unpack the dictionary entry, and always unpack // the key (or it cannot be added as a key) let val = _unpack_variant(variant.get_child_value(i), deep); let key; if (!deep) key = _unpack_variant(val[0], true); else key = val[0]; ret[key] = val[1]; } return ret; } if (variant.is_of_type(new GLib.VariantType('ay'))) { // special case byte arrays return variant.get_data_as_bytes().toArray(); } // fall through case '(': case '{': let ret = [ ]; let nElements = variant.n_children(); for (let i = 0; i < nElements; i++) { let val = variant.get_child_value(i); if (deep) ret.push(_unpack_variant(val, deep)); else ret.push(val); } return ret; } throw new Error('Assertion failure: this code should not be reached'); } function _init() { // this is imports.gi.GLib GLib = this; // small HACK: we add a matches() method to standard Errors so that // you can do "catch(e if e.matches(Ns.FooError, Ns.FooError.SOME_CODE))" // without checking instanceof Error.prototype.matches = function() { return false; }; this.Variant._new_internal = function(sig, value) { let signature = Array.prototype.slice.call(sig); let variant = _pack_variant(signature, value); if (signature.length != 0) throw new TypeError('Invalid GVariant signature (more than one single complete type)'); return variant; }; // Deprecate version of new GLib.Variant() this.Variant.new = function(sig, value) { return new GLib.Variant(sig, value); }; this.Variant.prototype.unpack = function() { return _unpack_variant(this, false); }; this.Variant.prototype.deep_unpack = function() { return _unpack_variant(this, true); }; this.Variant.prototype.toString = function() { return '[object variant of type "' + this.get_type_string() + '"]'; }; this.Bytes.prototype.toArray = function() { return imports.byteArray.fromGBytes(this); }; } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/jsextensions/gjs/GObject.js000066400000000000000000000370441303774616400240300ustar00rootroot00000000000000// Copyright 2011 Jasper St. Pierre // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. const Lang = imports.lang; const Gi = imports._gi; const GjsPrivate = imports.gi.GjsPrivate; let GObject; // Some common functions between GObject.Class and GObject.Interface function _createSignals(gtype, signals) { for (let signalName in signals) { let obj = signals[signalName]; let flags = (obj.flags !== undefined) ? obj.flags : GObject.SignalFlags.RUN_FIRST; let accumulator = (obj.accumulator !== undefined) ? obj.accumulator : GObject.AccumulatorType.NONE; let rtype = (obj.return_type !== undefined) ? obj.return_type : GObject.TYPE_NONE; let paramtypes = (obj.param_types !== undefined) ? obj.param_types : []; try { obj.signal_id = Gi.signal_new(gtype, signalName, flags, accumulator, rtype, paramtypes); } catch (e) { throw new TypeError('Invalid signal ' + signalName + ': ' + e.message); } } } function _createGTypeName(name, gtypename) { if (gtypename) return gtypename; else return 'Gjs_' + name; } function _getGObjectInterfaces(interfaces) { return interfaces.filter((iface) => iface.hasOwnProperty('$gtype')); } function _propertiesAsArray(propertyObj) { let propertiesArray = []; if (propertyObj) { for (let prop in propertyObj) { propertiesArray.push(propertyObj[prop]); } } return propertiesArray; } const GObjectMeta = new Lang.Class({ Name: 'GObjectClass', Extends: Lang.Class, _init: function (params) { // retrieve signals and remove them from params before chaining let signals = params.Signals; delete params.Signals; this.parent(params); if (signals) _createSignals(this.$gtype, signals); let propertyObj = { }; Object.getOwnPropertyNames(params).forEach(function(name) { if (name == 'Name' || name == 'Extends' || name == 'Abstract') return; let descriptor = Object.getOwnPropertyDescriptor(params, name); if (typeof descriptor.value === 'function') { let wrapped = this.prototype[name]; if (name.slice(0, 6) == 'vfunc_') { Gi.hook_up_vfunc(this.prototype, name.slice(6), wrapped); } else if (name.slice(0, 3) == 'on_') { let id = GObject.signal_lookup(name.slice(3).replace('_', '-'), this.$gtype); if (id != 0) { GObject.signal_override_class_closure(id, this.$gtype, function() { let argArray = Array.prototype.slice.call(arguments); let emitter = argArray.shift(); return wrapped.apply(emitter, argArray); }); } } } }.bind(this)); }, _isValidClass: function(klass) { let proto = klass.prototype; if (!proto) return false; // If proto == GObject.Object.prototype, then // proto.__proto__ is Object, so "proto instanceof GObject.Object" // will return false. return proto == GObject.Object.prototype || proto instanceof GObject.Object; }, // If we want an object with a custom JSClass, we can't just // use a function. We have to use a custom constructor here. _construct: function(params) { if (!params.Name) throw new TypeError("Classes require an explicit 'Name' parameter."); let name = params.Name; let gtypename = _createGTypeName(params.Name, params.GTypeName); if (!params.Extends) params.Extends = GObject.Object; let parent = params.Extends; if (!this._isValidClass(parent)) throw new TypeError('GObject.Class used with invalid base class (is ' + parent + ')'); let interfaces = params.Implements || []; if (parent instanceof Lang.Class) interfaces = interfaces.filter((iface) => !parent.implements(iface)); let gobjectInterfaces = _getGObjectInterfaces(interfaces); let propertiesArray = _propertiesAsArray(params.Properties); delete params.Properties; let newClass = Gi.register_type(parent.prototype, gtypename, gobjectInterfaces, propertiesArray); // See Class.prototype._construct in lang.js for the reasoning // behind this direct __proto__ set. newClass.__proto__ = this.constructor.prototype; newClass.__super__ = parent; newClass._init.apply(newClass, arguments); Object.defineProperties(newClass.prototype, { '__metaclass__': { writable: false, configurable: false, enumerable: false, value: this.constructor }, '__interfaces__': { writable: false, configurable: false, enumerable: false, value: interfaces } }); interfaces.forEach((iface) => { if (iface instanceof Lang.Interface) iface._check(newClass.prototype); }); return newClass; }, // Overrides Lang.Class.implements() implements: function (iface) { if (iface instanceof GObject.Interface) { return GObject.type_is_a(this.$gtype, iface.$gtype); } else { return this.parent(iface); } } }); function GObjectInterface(params) { return this._construct.apply(this, arguments); } GObjectMeta.MetaInterface = GObjectInterface; GObjectInterface.__super__ = Lang.Interface; GObjectInterface.prototype = Object.create(Lang.Interface.prototype); GObjectInterface.prototype.constructor = GObjectInterface; GObjectInterface.prototype.__name__ = 'GObjectInterface'; GObjectInterface.prototype._construct = function (params) { if (!params.Name) { throw new TypeError("Interfaces require an explicit 'Name' parameter."); } let gtypename = _createGTypeName(params.Name, params.GTypeName); delete params.GTypeName; let interfaces = params.Requires || []; let gobjectInterfaces = _getGObjectInterfaces(interfaces); let properties = _propertiesAsArray(params.Properties); delete params.Properties; let newInterface = Gi.register_interface(gtypename, gobjectInterfaces, properties); // See Class.prototype._construct in lang.js for the reasoning // behind this direct __proto__ set. newInterface.__proto__ = this.constructor.prototype; newInterface.__super__ = GObjectInterface; newInterface.prototype.constructor = newInterface; newInterface._init.apply(newInterface, arguments); Object.defineProperty(newInterface.prototype, '__metaclass__', { writable: false, configurable: false, enumerable: false, value: this.constructor }); return newInterface; }; GObjectInterface.prototype._init = function (params) { let signals = params.Signals; delete params.Signals; Lang.Interface.prototype._init.call(this, params); _createSignals(this.$gtype, signals); }; function _init() { GObject = this; function _makeDummyClass(obj, name, upperName, gtypeName, actual) { let gtype = GObject.type_from_name(gtypeName); obj['TYPE_' + upperName] = gtype; obj[name] = function(v) { return new actual(v); }; obj[name].$gtype = gtype; } _makeDummyClass(this, 'VoidType', 'NONE', 'void', function() {}); _makeDummyClass(this, 'Char', 'CHAR', 'gchar', Number); _makeDummyClass(this, 'UChar', 'UCHAR', 'guchar', Number); _makeDummyClass(this, 'Unichar', 'UNICHAR', 'gint', String); this.TYPE_BOOLEAN = GObject.type_from_name('gboolean'); this.Boolean = Boolean; Boolean.$gtype = this.TYPE_BOOLEAN; _makeDummyClass(this, 'Int', 'INT', 'gint', Number); _makeDummyClass(this, 'UInt', 'UINT', 'guint', Number); _makeDummyClass(this, 'Long', 'LONG', 'glong', Number); _makeDummyClass(this, 'ULong', 'ULONG', 'gulong', Number); _makeDummyClass(this, 'Int64', 'INT64', 'gint64', Number); _makeDummyClass(this, 'UInt64', 'UINT64', 'guint64', Number); this.TYPE_ENUM = GObject.type_from_name('GEnum'); this.TYPE_FLAGS = GObject.type_from_name('GFlags'); _makeDummyClass(this, 'Float', 'FLOAT', 'gfloat', Number); this.TYPE_DOUBLE = GObject.type_from_name('gdouble'); this.Double = Number; Number.$gtype = this.TYPE_DOUBLE; this.TYPE_STRING = GObject.type_from_name('gchararray'); this.String = String; String.$gtype = this.TYPE_STRING; this.TYPE_POINTER = GObject.type_from_name('gpointer'); this.TYPE_BOXED = GObject.type_from_name('GBoxed'); this.TYPE_PARAM = GObject.type_from_name('GParam'); this.TYPE_INTERFACE = GObject.type_from_name('GInterface'); this.TYPE_OBJECT = GObject.type_from_name('GObject'); this.TYPE_VARIANT = GObject.type_from_name('GVariant'); _makeDummyClass(this, 'Type', 'GTYPE', 'GType', GObject.type_from_name); this.ParamSpec.char = function(name, nick, blurb, flags, minimum, maximum, default_value) { return GObject.param_spec_char(name, nick, blurb, minimum, maximum, default_value, flags); }; this.ParamSpec.uchar = function(name, nick, blurb, flags, minimum, maximum, default_value) { return GObject.param_spec_uchar(name, nick, blurb, minimum, maximum, default_value, flags); }; this.ParamSpec.int = function(name, nick, blurb, flags, minimum, maximum, default_value) { return GObject.param_spec_int(name, nick, blurb, minimum, maximum, default_value, flags); }; this.ParamSpec.uint = function(name, nick, blurb, flags, minimum, maximum, default_value) { return GObject.param_spec_uint(name, nick, blurb, minimum, maximum, default_value, flags); }; this.ParamSpec.long = function(name, nick, blurb, flags, minimum, maximum, default_value) { return GObject.param_spec_long(name, nick, blurb, minimum, maximum, default_value, flags); }; this.ParamSpec.ulong = function(name, nick, blurb, flags, minimum, maximum, default_value) { return GObject.param_spec_ulong(name, nick, blurb, minimum, maximum, default_value, flags); }; this.ParamSpec.int64 = function(name, nick, blurb, flags, minimum, maximum, default_value) { return GObject.param_spec_int64(name, nick, blurb, minimum, maximum, default_value, flags); }; this.ParamSpec.uint64 = function(name, nick, blurb, flags, minimum, maximum, default_value) { return GObject.param_spec_uint64(name, nick, blurb, minimum, maximum, default_value, flags); }; this.ParamSpec.float = function(name, nick, blurb, flags, minimum, maximum, default_value) { return GObject.param_spec_float(name, nick, blurb, minimum, maximum, default_value, flags); }; this.ParamSpec.boolean = function(name, nick, blurb, flags, default_value) { return GObject.param_spec_boolean(name, nick, blurb, default_value, flags); }; this.ParamSpec.flags = function(name, nick, blurb, flags, flags_type, default_value) { return GObject.param_spec_flags(name, nick, blurb, flags_type, default_value, flags); }; this.ParamSpec.enum = function(name, nick, blurb, flags, enum_type, default_value) { return GObject.param_spec_enum(name, nick, blurb, enum_type, default_value, flags); }; this.ParamSpec.double = function(name, nick, blurb, flags, minimum, maximum, default_value) { return GObject.param_spec_double(name, nick, blurb, minimum, maximum, default_value, flags); }; this.ParamSpec.string = function(name, nick, blurb, flags, default_value) { return GObject.param_spec_string(name, nick, blurb, default_value, flags); }; this.ParamSpec.boxed = function(name, nick, blurb, flags, boxed_type) { return GObject.param_spec_boxed(name, nick, blurb, boxed_type, flags); }; this.ParamSpec.object = function(name, nick, blurb, flags, object_type) { return GObject.param_spec_object(name, nick, blurb, object_type, flags); }; this.ParamSpec.param = function(name, nick, blurb, flags, param_type) { return GObject.param_spec_param(name, nick, blurb, param_type, flags); }; // XXX:: Commented out due to compatibility issues //this.ParamSpec.override = Gi.override_property; Object.defineProperties(this.ParamSpec.prototype, { 'name': { configurable: false, enumerable: false, get: function() { return this.get_name() } }, '_nick': { configurable: false, enumerable: false, get: function() { return this.get_nick() } }, 'nick': { configurable: false, enumerable: false, get: function() { return this.get_nick() } }, '_blurb': { configurable: false, enumerable: false, get: function() { return this.get_blurb() } }, 'blurb': { configurable: false, enumerable: false, get: function() { return this.get_blurb() } }, 'default_value': { configurable: false, enumerable: false, get: function() { return this.get_default_value() } }, 'flags': { configurable: false, enumerable: false, get: function() { return GjsPrivate.param_spec_get_flags(this) } }, 'value_type': { configurable: false, enumerable: false, get: function() { return GjsPrivate.param_spec_get_value_type(this) } }, 'owner_type': { configurable: false, enumerable: false, get: function() { return GjsPrivate.param_spec_get_owner_type(this) } }, }); this.Class = GObjectMeta; this.Interface = GObjectInterface; /* XXX: removed due to compability issues between gjs and seed * * //this.Object.prototype.__metaclass__ = this.Class; * * // For compatibility with Lang.Class... we need a _construct * // or the Lang.Class constructor will fail. * this.Object.prototype._construct = function() { * this._init.apply(this, arguments); * return this; * }; * // fake enum for signal accumulators, keep in sync with gi/object.c * this.AccumulatorType = { * NONE: 0, * FIRST_WINS: 1, * TRUE_HANDLED: 2 * }; * this.Object.prototype.disconnect = function(id) { * return GObject.signal_handler_disconnect(this, id); * }; */ } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/jsextensions/gjs/Gio.js000066400000000000000000000334571303774616400232350ustar00rootroot00000000000000// Copyright 2011 Giovanni Campagna // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. var GLib = imports.gi.GLib; var GObject = imports.gi.GObject; var GjsPrivate = imports.gi.GjsPrivate; var Lang = imports.lang; var Signals = imports.signals; var Gio; function _signatureLength(sig) { var counter = 0; // make it an array var signature = Array.prototype.slice.call(sig); while (signature.length) { GLib._read_single_type(sig); counter++; } return counter; } function _proxyInvoker(methodName, sync, inSignature, arg_array) { var replyFunc; var flags = 0; var cancellable = null; /* Convert arg_array to a *real* array */ arg_array = Array.prototype.slice.call(arg_array); /* The default replyFunc only logs the responses */ replyFunc = _logReply; var signatureLength = inSignature.length; var minNumberArgs = signatureLength; var maxNumberArgs = signatureLength + 3; if (arg_array.length < minNumberArgs) { throw new Error("Not enough arguments passed for method: " + methodName + ". Expected " + minNumberArgs + ", got " + arg_array.length); } else if (arg_array.length > maxNumberArgs) { throw new Error("Too many arguments passed for method: " + methodName + ". Maximum is " + maxNumberArgs + " + one callback and/or flags"); } while (arg_array.length > signatureLength) { var argNum = arg_array.length - 1; var arg = arg_array.pop(); if (typeof(arg) == "function" && !sync) { replyFunc = arg; } else if (typeof(arg) == "number") { flags = arg; } else if (arg instanceof Gio.Cancellable) { cancellable = arg; } else { throw new Error("Argument " + argNum + " of method " + methodName + " is " + typeof(arg) + ". It should be a callback, flags or a Gio.Cancellable"); } } var inVariant = new GLib.Variant('(' + inSignature.join('') + ')', arg_array); var asyncCallback = function (proxy, result) { var outVariant = null, succeeded = false; try { outVariant = proxy.call_finish(result); succeeded = true; } catch (e) { replyFunc(null, e); } if (succeeded) replyFunc(outVariant.deep_unpack(), null); }; if (sync) { return this.call_sync(methodName, inVariant, flags, -1, cancellable).deep_unpack(); } else { return this.call(methodName, inVariant, flags, -1, cancellable, asyncCallback); } } function _logReply(result, exc) { if (exc != null) { log("Ignored exception from dbus method: " + exc.toString()); } } function _makeProxyMethod(method, sync) { var i; var name = method.name; var inArgs = method.in_args; var inSignature = [ ]; for (i = 0; i < inArgs.length; i++) inSignature.push(inArgs[i].signature); return function() { return _proxyInvoker.call(this, name, sync, inSignature, arguments); }; } function _convertToNativeSignal(proxy, sender_name, signal_name, parameters) { Signals._emit.call(proxy, signal_name, sender_name, parameters.deep_unpack()); } function _propertyGetter(name) { let value = this.get_cached_property(name); return value ? value.deep_unpack() : null; } function _propertySetter(value, name, signature) { let variant = new GLib.Variant(signature, value); this.set_cached_property(name, variant); this.call('org.freedesktop.DBus.Properties.Set', new GLib.Variant('(ssv)', [this.g_interface_name, name, variant]), Gio.DBusCallFlags.NONE, -1, null, Lang.bind(this, function(proxy, result) { try { this.call_finish(result); } catch(e) { log('Could not set property ' + name + ' on remote object ' + this.g_object_path + ': ' + e.message); } })); } function _addDBusConvenience() { let info = this.g_interface_info; if (!info) return; if (info.signals.length > 0) this.connect('g-signal', _convertToNativeSignal); let i, methods = info.methods; for (i = 0; i < methods.length; i++) { var method = methods[i]; this[method.name + 'Remote'] = _makeProxyMethod(methods[i], false); this[method.name + 'Sync'] = _makeProxyMethod(methods[i], true); } let properties = info.properties; for (i = 0; i < properties.length; i++) { let name = properties[i].name; let signature = properties[i].signature; Object.defineProperty(this, name, { get: Lang.bind(this, _propertyGetter, name), set: Lang.bind(this, _propertySetter, name, signature), configurable: true, enumerable: true }); } } function _makeProxyWrapper(interfaceXml) { var info = _newInterfaceInfo(interfaceXml); var iname = info.name; return function(bus, name, object, asyncCallback, cancellable) { var obj = new Gio.DBusProxy({ g_connection: bus, g_interface_name: iname, g_interface_info: info, g_name: name, g_object_path: object }); if (!cancellable) cancellable = null; if (asyncCallback) obj.init_async(GLib.PRIORITY_DEFAULT, cancellable, function(initable, result) { let caughtErrorWhenInitting = null; try { initable.init_finish(result); } catch(e) { caughtErrorWhenInitting = e; } if (caughtErrorWhenInitting === null) { asyncCallback(initable, null); } else { asyncCallback(null, caughtErrorWhenInitting); } }); else obj.init(cancellable); return obj; }; } function _newNodeInfo(constructor, value) { if (typeof value == 'string') return constructor(value); else if (value instanceof XML) return constructor(value.toXMLString()); else throw TypeError('Invalid type ' + Object.prototype.toString.call(value)); } function _newInterfaceInfo(value) { var nodeInfo = Gio.DBusNodeInfo.new_for_xml(value); return nodeInfo.interfaces[0]; } function _injectToMethod(klass, method, addition) { var previous = klass[method]; klass[method] = function() { addition.apply(this, arguments); return previous.apply(this, arguments); }; } function _wrapFunction(klass, method, addition) { var previous = klass[method]; klass[method] = function() { var args = Array.prototype.slice.call(arguments); args.unshift(previous); return addition.apply(this, args); }; } function _makeOutSignature(args) { var ret = '('; for (var i = 0; i < args.length; i++) ret += args[i].signature; return ret + ')'; } function _handleMethodCall(info, impl, method_name, parameters, invocation) { // prefer a sync version if available if (this[method_name]) { let retval; try { retval = this[method_name].apply(this, parameters.deep_unpack()); } catch (e) { if (e instanceof GLib.Error) { invocation.return_gerror(e); } else { let name = e.name; if (name.indexOf('.') == -1) { // likely to be a normal JS error name = 'org.gnome.gjs.JSError.' + name; } logError(e, "Exception in method call: " + method_name); invocation.return_dbus_error(name, e.message); } return; } if (retval === undefined) { // undefined (no return value) is the empty tuple retval = new GLib.Variant('()', []); } try { if (!(retval instanceof GLib.Variant)) { // attempt packing according to out signature let methodInfo = info.lookup_method(method_name); let outArgs = methodInfo.out_args; let outSignature = _makeOutSignature(outArgs); if (outArgs.length == 1) { // if one arg, we don't require the handler wrapping it // into an Array retval = [retval]; } retval = new GLib.Variant(outSignature, retval); } invocation.return_value(retval); } catch(e) { // if we don't do this, the other side will never see a reply invocation.return_dbus_error('org.gnome.gjs.JSError.ValueError', "Service implementation returned an incorrect value type"); } } else if (this[method_name + 'Async']) { this[method_name + 'Async'](parameters.deep_unpack(), invocation); } else { log('Missing handler for DBus method ' + method_name); invocation.return_gerror(new Gio.DBusError({ code: Gio.DBusError.UNKNOWN_METHOD, message: 'Method ' + method_name + ' is not implemented' })); } } function _handlePropertyGet(info, impl, property_name) { let propInfo = info.lookup_property(property_name); let jsval = this[property_name]; if (jsval != undefined) return new GLib.Variant(propInfo.signature, jsval); else return null; } function _handlePropertySet(info, impl, property_name, new_value) { this[property_name] = new_value.deep_unpack(); } function _wrapJSObject(interfaceInfo, jsObj) { var info; if (interfaceInfo instanceof Gio.DBusInterfaceInfo) info = interfaceInfo; else info = Gio.DBusInterfaceInfo.new_for_xml(interfaceInfo); info.cache_build(); var impl = new GjsPrivate.DBusImplementation({ g_interface_info: info }); impl.connect('handle-method-call', function(impl, method_name, parameters, invocation) { return _handleMethodCall.call(jsObj, info, impl, method_name, parameters, invocation); }); impl.connect('handle-property-get', function(impl, property_name) { return _handlePropertyGet.call(jsObj, info, impl, property_name); }); impl.connect('handle-property-set', function(impl, property_name, value) { return _handlePropertySet.call(jsObj, info, impl, property_name, value); }); return impl; } function _init() { Gio = this; Gio.DBus = { get session() { return Gio.bus_get_sync(Gio.BusType.SESSION, null); }, get system() { return Gio.bus_get_sync(Gio.BusType.SYSTEM, null); }, // Namespace some functions get: Gio.bus_get, get_finish: Gio.bus_get_finish, get_sync: Gio.bus_get_sync, own_name: Gio.bus_own_name, own_name_on_connection: Gio.bus_own_name_on_connection, unown_name: Gio.bus_unown_name, watch_name: Gio.bus_watch_name, watch_name_on_connection: Gio.bus_watch_name_on_connection, unwatch_name: Gio.bus_unwatch_name }; Gio.DBusConnection.prototype.watch_name = function(name, flags, appeared, vanished) { return Gio.bus_watch_name_on_connection(this, name, flags, appeared, vanished); }; Gio.DBusConnection.prototype.unwatch_name = function(id) { return Gio.bus_unwatch_name(id); }; Gio.DBusConnection.prototype.own_name = function(name, flags, acquired, lost) { return Gio.bus_own_name_on_connection(this, name, flags, acquired, lost); }; Gio.DBusConnection.prototype.unown_name = function(id) { return Gio.bus_unown_name(id); }; _injectToMethod(Gio.DBusProxy.prototype, 'init', _addDBusConvenience); _injectToMethod(Gio.DBusProxy.prototype, 'init_async', _addDBusConvenience); Gio.DBusProxy.prototype.connectSignal = Signals._connect; Gio.DBusProxy.prototype.disconnectSignal = Signals._disconnect; Gio.DBusProxy.makeProxyWrapper = _makeProxyWrapper; // Some helpers _wrapFunction(Gio.DBusNodeInfo, 'new_for_xml', _newNodeInfo); Gio.DBusInterfaceInfo.new_for_xml = _newInterfaceInfo; Gio.DBusExportedObject = GjsPrivate.DBusImplementation; Gio.DBusExportedObject.wrapJSObject = _wrapJSObject; } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/jsextensions/gjs/Gtk.js000066400000000000000000000075651303774616400232450ustar00rootroot00000000000000// application/javascript;version=1.8 // Copyright 2013 Giovanni Campagna // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. const Lang = imports.lang; const GObject = imports.gi.GObject; var GjsPrivate = imports.gi.GjsPrivate; let Gtk; const GtkWidgetClass = new Lang.Class({ Name: 'GtkWidgetClass', Extends: GObject.Class, _init: function(params) { let template = params.Template; delete params.Template; let children = params.Children; delete params.Children; let internalChildren = params.InternalChildren; delete params.InternalChildren; if (template) { params._instance_init = function() { this.init_template(); }; } this.parent(params); if (template) { if (typeof template == 'string' && template.startsWith('resource:///')) Gtk.Widget.set_template_from_resource.call(this, template.slice(11)); else Gtk.Widget.set_template.call(this, template); } this.Template = template; this.Children = children; this.InternalChildren = internalChildren; if (children) { for (let i = 0; i < children.length; i++) Gtk.Widget.bind_template_child_full.call(this, children[i], false, 0); } if (internalChildren) { for (let i = 0; i < internalChildren.length; i++) Gtk.Widget.bind_template_child_full.call(this, internalChildren[i], true, 0); } }, _isValidClass: function(klass) { let proto = klass.prototype; if (!proto) return false; // If proto == Gtk.Widget.prototype, then // proto.__proto__ is GObject.InitiallyUnowned, so // "proto instanceof Gtk.Widget" // will return false. return proto == Gtk.Widget.prototype || proto instanceof Gtk.Widget; }, }); function _init() { Gtk = this; Gtk.Widget.prototype.__metaclass__ = GtkWidgetClass; if (GjsPrivate.gtk_container_child_set_property) { Gtk.Container.prototype.child_set_property = function(child, property, value) { GjsPrivate.gtk_container_child_set_property(this, child, property, value); }; } Gtk.Widget.prototype._init = function(params) { GObject.Object.prototype._init.call(this, params); if (this.constructor.Template) { let children = this.constructor.Children || []; for (let child of children) this[child.replace('-', '_', 'g')] = this.get_template_child(this.constructor, child); let internalChildren = this.constructor.InternalChildren || []; for (let child of internalChildren) this['_' + child.replace('-', '_', 'g')] = this.get_template_child(this.constructor, child); } }; } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/jsextensions/libseed.gresources.xml000066400000000000000000000007121303774616400256730ustar00rootroot00000000000000 Gio.js GLib.js Gtk.js GObject.js Gst.js gjs/Gio.js gjs/GLib.js gjs/Gtk.js gjs/GObject.js Seed.js Clutter.js repl.js seed-webkit2-4.0.0+20161014+6c77960+dfsg1/jsextensions/repl.js000077500000000000000000000016521303774616400226710ustar00rootroot00000000000000#!/usr/bin/env seed readline = imports.readline; sandbox = imports.sandbox; os = imports.os; var lastLastLength = '-1'; context = new sandbox.Context(); context.add_globals(); bind_cr = function(){ var buffer = readline.buffer(); if (buffer.length == lastLastLength) readline.done(); try { Seed.check_syntax(buffer); readline.done(); } catch (e){ os.write(1, "\n.."); lastLastLength = buffer.length; return; } os.write(1, "\n"); lastLastLength = buffer.length; } readline.bind('\n', bind_cr); readline.bind('\r', bind_cr); readline.bind('\t', function(){ readline.insert("\t"); }); //var re = /[^=<>*-^/]=[^=<>*-^/]\(*\s*(new\s*)?[^:punct:]|'|"+\)*$/ while(1){ try{ item = readline.readline("> "); result = context.eval(item); // if (!re.exec(item) && (result != undefined)) if (result != undefined) print(result) } catch(e){ print(e.name + " " + e.message); } } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/libgjs-private/000077500000000000000000000000001303774616400215505ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/libgjs-private/Makefile.am000066400000000000000000000027231303774616400236100ustar00rootroot00000000000000-include $(INTROSPECTION_MAKEFILE) INTROSPECTION_GIRS = lib_LTLIBRARIES = \ libseed_gjsprivate.la libgjs_private_source_files = \ gjs-gdbus-wrapper.c \ gjs-gdbus-wrapper.h \ gjs-util.c \ gjs-util.h \ gjs-gtk-util.h \ gjs-gtk-util.c \ $(NULL) libseed_gjsprivate_la_SOURCES = $(libgjs_private_source_files) AM_CPPFLAGS = \ -I@top_srcdir@/libseed/ \ $(GOBJECT_INTROSPECTION_CFLAGS) \ $(SEED_DEBUG_CFLAGS) \ $(GTK_CFLAGS) \ $(SEED_PROFILE_CFLAGS) libseed_gjsprivate_la_LDFLAGS = \ -module -avoid-version \ $(GOBJECT_INTROSPECTION_LDFLAGS) libseed_gjsprivate_la_LIBADD = \ $(top_builddir)/libseed/libseed@SEED_GTK_VERSION@.la \ $(GTK_LIBS) \ $(SEED_PROFILE_LIBS) INTROSPECTION_SCANNER_ARGS = \ --add-include-path=@top_srcdir@ --add-include-path=$(GTK_CFLAGS) --warn-all INTROSPECTION_COMPILER_ARGS = \ --includedir=@top_srcdir@ GjsPrivate-1.0.gir: libseed_gjsprivate.la GjsPrivate_1_0_gir_INCLUDES = GObject-2.0 Gio-2.0 GjsPrivate_1_0_gir_CFLAGS = $(INCLUDES) GjsPrivate_1_0_gir_LIBS = libseed_gjsprivate.la GjsPrivate_1_0_gir_FILES = $(libgjs_private_source_files) INTROSPECTION_GIRS += GjsPrivate-1.0.gir GjsPrivate_1_0_gir_SCANNERFLAGS = --identifier-prefix=Gjs --symbol-prefix=gjs_ --warn-all girdir = $(datadir)/gir-1.0 gir_DATA = $(INTROSPECTION_GIRS) typelibdir = $(pkglibdir)@SEED_GTK_VERSION@/girepository-1.0 typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib) CLEANFILES = $(gir_DATA) $(typelib_DATA) -include $(top_srcdir)/git.mk seed-webkit2-4.0.0+20161014+6c77960+dfsg1/libgjs-private/gjs-gdbus-wrapper.c000066400000000000000000000273671303774616400252760ustar00rootroot00000000000000/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ /* Copyright 2011 Giovanni Campagna. All Rights Reserved. */ #include #include #include "gjs-gdbus-wrapper.h" enum { PROP_0, PROP_G_INTERFACE_INFO, PROP_LAST }; enum { SIGNAL_HANDLE_METHOD, SIGNAL_HANDLE_PROPERTY_GET, SIGNAL_HANDLE_PROPERTY_SET, SIGNAL_LAST, }; static guint signals[SIGNAL_LAST]; struct _GjsDBusImplementationPrivate { GDBusInterfaceVTable vtable; GDBusInterfaceInfo* ifaceinfo; // from gchar* to GVariant* GHashTable* outstanding_properties; guint idle_id; }; G_DEFINE_TYPE(GjsDBusImplementation, gjs_dbus_implementation, G_TYPE_DBUS_INTERFACE_SKELETON) static void gjs_dbus_implementation_method_call(GDBusConnection* connection, const char* sender, const char* object_path, const char* interface_name, const char* method_name, GVariant* parameters, GDBusMethodInvocation* invocation, gpointer user_data) { GjsDBusImplementation* self = GJS_DBUS_IMPLEMENTATION(user_data); g_signal_emit(self, signals[SIGNAL_HANDLE_METHOD], 0, method_name, parameters, invocation); g_object_unref(invocation); } static GVariant* gjs_dbus_implementation_property_get(GDBusConnection* connection, const char* sender, const char* object_path, const char* interface_name, const char* property_name, GError** error, gpointer user_data) { GjsDBusImplementation* self = GJS_DBUS_IMPLEMENTATION(user_data); GVariant* value; g_signal_emit(self, signals[SIGNAL_HANDLE_PROPERTY_GET], 0, property_name, &value); /* Marshaling GErrors is not supported, so this is the best we can do (GIO will assert if value is NULL and error is not set) */ if (!value) g_set_error(error, g_quark_from_static_string("gjs-error-domain"), 0, "Property retrieval failed"); return value; } static gboolean gjs_dbus_implementation_property_set(GDBusConnection* connection, const char* sender, const char* object_path, const char* interface_name, const char* property_name, GVariant* value, GError** error, gpointer user_data) { GjsDBusImplementation* self = GJS_DBUS_IMPLEMENTATION(user_data); g_signal_emit(self, signals[SIGNAL_HANDLE_PROPERTY_SET], 0, property_name, value); return TRUE; } static void gjs_dbus_implementation_init(GjsDBusImplementation* self) { GjsDBusImplementationPrivate* priv = G_TYPE_INSTANCE_GET_PRIVATE(self, GJS_TYPE_DBUS_IMPLEMENTATION, GjsDBusImplementationPrivate); self->priv = priv; priv->vtable.method_call = gjs_dbus_implementation_method_call; priv->vtable.get_property = gjs_dbus_implementation_property_get; priv->vtable.set_property = gjs_dbus_implementation_property_set; priv->outstanding_properties = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_variant_unref); } static void gjs_dbus_implementation_finalize(GObject* object) { GjsDBusImplementation* self = GJS_DBUS_IMPLEMENTATION(object); g_dbus_interface_info_unref(self->priv->ifaceinfo); g_hash_table_unref(self->priv->outstanding_properties); G_OBJECT_CLASS(gjs_dbus_implementation_parent_class)->finalize(object); } static void gjs_dbus_implementation_set_property(GObject* object, guint property_id, const GValue* value, GParamSpec* pspec) { GjsDBusImplementation* self = GJS_DBUS_IMPLEMENTATION(object); switch (property_id) { case PROP_G_INTERFACE_INFO: self->priv->ifaceinfo = (GDBusInterfaceInfo*) g_value_dup_boxed(value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); } } static GDBusInterfaceInfo* gjs_dbus_implementation_get_info(GDBusInterfaceSkeleton* skeleton) { GjsDBusImplementation* self = GJS_DBUS_IMPLEMENTATION(skeleton); return self->priv->ifaceinfo; } static GDBusInterfaceVTable* gjs_dbus_implementation_get_vtable(GDBusInterfaceSkeleton* skeleton) { GjsDBusImplementation* self = GJS_DBUS_IMPLEMENTATION(skeleton); return &(self->priv->vtable); } static GVariant* gjs_dbus_implementation_get_properties(GDBusInterfaceSkeleton* skeleton) { GjsDBusImplementation* self = GJS_DBUS_IMPLEMENTATION(skeleton); GDBusInterfaceInfo* info = self->priv->ifaceinfo; GDBusPropertyInfo** props; GVariantBuilder builder; g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); for (props = info->properties; *props; ++props) { GDBusPropertyInfo* prop = *props; GVariant* value; /* If we have a cached value, we use that instead of querying again */ if ((value = (GVariant*) g_hash_table_lookup( self->priv->outstanding_properties, prop->name))) { g_variant_builder_add(&builder, "{sv}", prop->name, value); continue; } g_signal_emit(self, signals[SIGNAL_HANDLE_PROPERTY_GET], 0, prop->name, &value); g_variant_builder_add(&builder, "{sv}", prop->name, value); } return g_variant_builder_end(&builder); } static void gjs_dbus_implementation_flush(GDBusInterfaceSkeleton* skeleton) { GjsDBusImplementation* self = GJS_DBUS_IMPLEMENTATION(skeleton); GVariantBuilder changed_props; GVariantBuilder invalidated_props; GHashTableIter iter; GVariant* val; gchar* prop_name; g_variant_builder_init(&changed_props, G_VARIANT_TYPE_VARDICT); g_variant_builder_init(&invalidated_props, G_VARIANT_TYPE_STRING_ARRAY); g_hash_table_iter_init(&iter, self->priv->outstanding_properties); while (g_hash_table_iter_next(&iter, (void**) &prop_name, (void**) &val)) { if (val) g_variant_builder_add(&changed_props, "{sv}", prop_name, val); else g_variant_builder_add(&invalidated_props, "s", prop_name); } g_dbus_connection_emit_signal( g_dbus_interface_skeleton_get_connection(skeleton), NULL, /* bus name */ g_dbus_interface_skeleton_get_object_path(skeleton), "org.freedesktop.DBus.Properties", "PropertiesChanged", g_variant_new("(s@a{sv}@as)", self->priv->ifaceinfo->name, g_variant_builder_end(&changed_props), g_variant_builder_end(&invalidated_props)), NULL /* error */); g_hash_table_remove_all(self->priv->outstanding_properties); if (self->priv->idle_id) { g_source_remove(self->priv->idle_id); self->priv->idle_id = 0; } } void gjs_dbus_implementation_class_init(GjsDBusImplementationClass* klass) { GObjectClass* gobject_class = G_OBJECT_CLASS(klass); GDBusInterfaceSkeletonClass* skeleton_class = G_DBUS_INTERFACE_SKELETON_CLASS(klass); g_type_class_add_private(klass, sizeof(GjsDBusImplementationPrivate)); gobject_class->finalize = gjs_dbus_implementation_finalize; gobject_class->set_property = gjs_dbus_implementation_set_property; skeleton_class->get_info = gjs_dbus_implementation_get_info; skeleton_class->get_vtable = gjs_dbus_implementation_get_vtable; skeleton_class->get_properties = gjs_dbus_implementation_get_properties; skeleton_class->flush = gjs_dbus_implementation_flush; g_object_class_install_property( gobject_class, PROP_G_INTERFACE_INFO, g_param_spec_boxed("g-interface-info", "Interface Info", "A DBusInterfaceInfo representing the exported object", G_TYPE_DBUS_INTERFACE_INFO, (GParamFlags)(G_PARAM_STATIC_STRINGS | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY))); signals[SIGNAL_HANDLE_METHOD] = g_signal_new("handle-method-call", G_TYPE_FROM_CLASS(klass), (GSignalFlags) 0, /* flags */ 0, /* closure */ NULL, /* accumulator */ NULL, /* accumulator data */ NULL, /* C marshal */ G_TYPE_NONE, 3, G_TYPE_STRING, /* method name */ G_TYPE_VARIANT, /* parameters */ G_TYPE_DBUS_METHOD_INVOCATION); signals[SIGNAL_HANDLE_PROPERTY_GET] = g_signal_new("handle-property-get", G_TYPE_FROM_CLASS(klass), (GSignalFlags) 0, /* flags */ 0, /* closure */ g_signal_accumulator_first_wins, NULL, /* accumulator data */ NULL, /* C marshal */ G_TYPE_VARIANT, 1, G_TYPE_STRING /* property name */); signals[SIGNAL_HANDLE_PROPERTY_SET] = g_signal_new("handle-property-set", G_TYPE_FROM_CLASS(klass), (GSignalFlags) 0, /* flags */ 0, /* closure */ NULL, /* accumulator */ NULL, /* accumulator data */ NULL, /* C marshal */ G_TYPE_NONE, 2, G_TYPE_STRING, /* property name */ G_TYPE_VARIANT /* parameters */); } static gboolean idle_cb(gpointer data) { GDBusInterfaceSkeleton* skeleton = G_DBUS_INTERFACE_SKELETON(data); g_dbus_interface_skeleton_flush(skeleton); return FALSE; } /** * gjs_dbus_implementation_emit_property_changed: * @self: a #GjsDBusImplementation * @property: the name of the property that changed * @newvalue: (allow-none): the new value, or %NULL to just invalidate it * * Queue a PropertyChanged signal for emission, or update the one queued * adding @property */ void gjs_dbus_implementation_emit_property_changed(GjsDBusImplementation* self, gchar* property, GVariant* newvalue) { g_hash_table_replace(self->priv->outstanding_properties, g_strdup(property), g_variant_ref(newvalue)); if (!self->priv->idle_id) self->priv->idle_id = g_idle_add(idle_cb, self); } /** * gjs_dbus_implementation_emit_signal: * @self: a #GjsDBusImplementation * @signal_name: the name of the signal * @parameters: (allow-none): signal parameters, or %NULL for none * * Emits a signal named @signal_name from the object and interface represented * by @self. This signal has no destination. */ void gjs_dbus_implementation_emit_signal(GjsDBusImplementation* self, gchar* signal_name, GVariant* parameters) { GDBusInterfaceSkeleton* skeleton = G_DBUS_INTERFACE_SKELETON(self); g_dbus_connection_emit_signal( g_dbus_interface_skeleton_get_connection(skeleton), NULL, g_dbus_interface_skeleton_get_object_path(skeleton), self->priv->ifaceinfo->name, signal_name, parameters, NULL); } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/libgjs-private/gjs-gdbus-wrapper.h000066400000000000000000000063111303774616400252650ustar00rootroot00000000000000/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ /* Copyright 2011 Giovanni Campagna * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #ifndef __GJS_UTIL_DBUS_H__ #define __GJS_UTIL_DBUS_H__ #include #include #include G_BEGIN_DECLS typedef struct _GjsDBusImplementation GjsDBusImplementation; typedef struct _GjsDBusImplementationClass GjsDBusImplementationClass; typedef struct _GjsDBusImplementationPrivate GjsDBusImplementationPrivate; #define GJS_TYPE_DBUS_IMPLEMENTATION (gjs_dbus_implementation_get_type()) #define GJS_DBUS_IMPLEMENTATION(object) \ (G_TYPE_CHECK_INSTANCE_CAST((object), GJS_TYPE_DBUS_IMPLEMENTATION, \ GjsDBusImplementation)) #define GJS_DBUS_IMPLEMENTATION_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST((klass), GJS_TYPE_DBUS_IMPLEMENTATION, \ GjsDBusImplementationClass)) #define GJS_IS_DBUS_IMPLEMENTATION(object) \ (G_TYPE_CHECK_INSTANCE_TYPE((object), GJS_TYPE_DBUS_IMPLEMENTATION)) #define GJS_IS_DBUS_IMPLEMENTATION_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE((klass), GJS_TYPE_DBUS_IMPLEMENTATION)) #define GJS_DBUS_IMPLEMENTATION_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS((obj), GJS_TYPE_DBUS_IMPLEMENTATION, \ GjsDBusImplementationClass)) struct _GjsDBusImplementation { GDBusInterfaceSkeleton parent; GjsDBusImplementationPrivate* priv; }; struct _GjsDBusImplementationClass { GDBusInterfaceSkeletonClass parent_class; }; GType gjs_dbus_implementation_get_type(void); void gjs_dbus_implementation_emit_property_changed(GjsDBusImplementation* self, gchar* property, GVariant* newvalue); void gjs_dbus_implementation_emit_signal(GjsDBusImplementation* self, gchar* signal_name, GVariant* parameters); G_END_DECLS #endif /* __GJS_UTIL_DBUS_H__ */ seed-webkit2-4.0.0+20161014+6c77960+dfsg1/libgjs-private/gjs-gtk-util.c000066400000000000000000000052611303774616400242410ustar00rootroot00000000000000/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ /* Copyright 2014 Endless Mobile, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #include #include #include "gjs-gtk-util.h" void gjs_gtk_container_child_set_property(GtkContainer* container, GtkWidget* child, const gchar* property, const GValue* value) { GParamSpec* pspec; pspec = gtk_container_class_find_child_property(G_OBJECT_GET_CLASS(container), property); if (pspec == NULL) { g_warning("%s does not have a property called %s", g_type_name(G_OBJECT_TYPE(container)), property); return; } if ((G_VALUE_TYPE(value) == G_TYPE_POINTER) && (g_value_get_pointer(value) == NULL) && !g_value_type_transformable(G_VALUE_TYPE(value), pspec->value_type)) { /* Set an empty value. This will happen when we set a NULL value from * JS. * Since GJS doesn't know the GParamSpec for this property, it * will just put NULL into a G_TYPE_POINTER GValue, which will later * fail when trying to transform it to the GParamSpec's GType. */ GValue null_value = G_VALUE_INIT; g_value_init(&null_value, pspec->value_type); gtk_container_child_set_property(container, child, property, &null_value); g_value_unset(&null_value); } else { gtk_container_child_set_property(container, child, property, value); } } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/libgjs-private/gjs-gtk-util.h000066400000000000000000000031021303774616400242360ustar00rootroot00000000000000/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ /* Copyright 2014 Endless Mobile, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #ifndef __GJS_PRIVATE_GTK_UTIL_H__ #define __GJS_PRIVATE_GTK_UTIL_H__ #include G_BEGIN_DECLS void gjs_gtk_container_child_set_property(GtkContainer* container, GtkWidget* child, const gchar* property, const GValue* value); G_END_DECLS #endif /* __GJS_PRIVATE_GTK_UTIL_H__ */ seed-webkit2-4.0.0+20161014+6c77960+dfsg1/libgjs-private/gjs-util.c000066400000000000000000000065751303774616400234670ustar00rootroot00000000000000/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ /* Copyright 2012 Giovanni Campagna * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #include #include #include #include #include "gjs-util.h" char* gjs_format_int_alternative_output(int n) { return g_strdup_printf("%Id", n); } GType gjs_locale_category_get_type(void) { static volatile size_t g_define_type_id__volatile = 0; if (g_once_init_enter(&g_define_type_id__volatile)) { static const GEnumValue v[] = { { GJS_LOCALE_CATEGORY_ALL, "GJS_LOCALE_CATEGORY_ALL", "all" }, { GJS_LOCALE_CATEGORY_COLLATE, "GJS_LOCALE_CATEGORY_COLLATE", "collate" }, { GJS_LOCALE_CATEGORY_CTYPE, "GJS_LOCALE_CATEGORY_CTYPE", "ctype" }, { GJS_LOCALE_CATEGORY_MESSAGES, "GJS_LOCALE_CATEGORY_MESSAGES", "messages" }, { GJS_LOCALE_CATEGORY_MONETARY, "GJS_LOCALE_CATEGORY_MONETARY", "monetary" }, { GJS_LOCALE_CATEGORY_NUMERIC, "GJS_LOCALE_CATEGORY_NUMERIC", "numeric" }, { GJS_LOCALE_CATEGORY_TIME, "GJS_LOCALE_CATEGORY_TIME", "time" }, { 0, NULL, NULL } }; GType g_define_type_id = g_enum_register_static(g_intern_static_string("GjsLocaleCategory"), v); g_once_init_leave(&g_define_type_id__volatile, g_define_type_id); } return g_define_type_id__volatile; } /** * gjs_setlocale: * @category: * @locale: (allow-none): * * Returns: */ const char* gjs_setlocale(GjsLocaleCategory category, const char* locale) { /* According to man setlocale(3), the return value may be allocated in * static storage. */ return (const char*) setlocale(category, locale); } void gjs_textdomain(const char* domain) { textdomain(domain); } void gjs_bindtextdomain(const char* domain, const char* location) { bindtextdomain(domain, location); /* Always use UTF-8; we assume it internally here */ bind_textdomain_codeset(domain, "UTF-8"); } GParamFlags gjs_param_spec_get_flags(GParamSpec* pspec) { return pspec->flags; } GType gjs_param_spec_get_value_type(GParamSpec* pspec) { return pspec->value_type; } GType gjs_param_spec_get_owner_type(GParamSpec* pspec) { return pspec->owner_type; } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/libgjs-private/gjs-util.h000066400000000000000000000043241303774616400234620ustar00rootroot00000000000000/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ /* Copyright 2012 Giovanni Campagna * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #ifndef __GJS_PRIVATE_UTIL_H__ #define __GJS_PRIVATE_UTIL_H__ #include #include #include G_BEGIN_DECLS /* For imports.format */ char* gjs_format_int_alternative_output(int n); /* For imports.gettext */ typedef enum { GJS_LOCALE_CATEGORY_ALL = LC_ALL, GJS_LOCALE_CATEGORY_COLLATE = LC_COLLATE, GJS_LOCALE_CATEGORY_CTYPE = LC_CTYPE, GJS_LOCALE_CATEGORY_MESSAGES = LC_MESSAGES, GJS_LOCALE_CATEGORY_MONETARY = LC_MONETARY, GJS_LOCALE_CATEGORY_NUMERIC = LC_NUMERIC, GJS_LOCALE_CATEGORY_TIME = LC_TIME } GjsLocaleCategory; const char* gjs_setlocale(GjsLocaleCategory category, const char* locale); void gjs_textdomain(const char* domain); void gjs_bindtextdomain(const char* domain, const char* location); GType gjs_locale_category_get_type(void) G_GNUC_CONST; /* For imports.overrides.GObject */ GParamFlags gjs_param_spec_get_flags(GParamSpec* pspec); GType gjs_param_spec_get_value_type(GParamSpec* pspec); GType gjs_param_spec_get_owner_type(GParamSpec* pspec); G_END_DECLS #endif seed-webkit2-4.0.0+20161014+6c77960+dfsg1/libseed/000077500000000000000000000000001303774616400202355ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/libseed/Makefile.am000066400000000000000000000024001303774616400222650ustar00rootroot00000000000000lib_LTLIBRARIES = \ libseed@SEED_GTK_VERSION@.la libseed@SEED_GTK_VERSION@_la_SOURCES = \ seed-closure.c \ seed-api.c \ seed-closure.h \ seed-builtins.c \ seed-builtins.h \ seed-debug.h \ seed-exceptions.c \ seed-exceptions.h \ seed-engine.c \ seed-engine.h \ seed-private.h \ seed-signals.c \ seed-signals.h \ seed-structs.c \ seed-gtype.c \ seed-gtype.h \ seed-structs.h \ seed-types.c \ seed-types.h \ seed-importer.c \ seed-importer.h \ seed-path.h nodist_libseed@SEED_GTK_VERSION@_la_SOURCES = \ ../jsextensions/libseed-resources.c libseed@SEED_GTK_VERSION@_la_CFLAGS = \ -Wall \ $(GOBJECT_INTROSPECTION_CFLAGS) \ $(WEBKIT_CFLAGS) \ $(SEED_OSX_CFLAGS) \ $(SEED_DEBUG_CFLAGS) \ $(SEED_GJSCOMPAT_CFLAGS) \ $(SEED_PROFILE_CFLAGS) \ $(FFI_CFLAGS) \ -DGOBJECT_INTROSPECTION_VERSION=$(GOBJECT_INTROSPECTION_VERSION) libseed@SEED_GTK_VERSION@_la_LDFLAGS = \ $(FFI_LDFLAGS) \ -export-symbols-regex "^seed_.*" libseed@SEED_GTK_VERSION@_la_LIBADD = \ $(GOBJECT_INTROSPECTION_LIBS) \ $(WEBKIT_LIBS) \ $(SEED_PROFILE_LIBS) \ $(SEED_OSX_LIBS) \ $(GIO_LIBS) \ $(GMODULE_LIBS) \ $(FFI_LIBS) $(LIBDL) seedheaders_HEADERS = seed.h seed-debug.h seed-module.h seedheadersdir = $(pkgincludedir)@SEED_GTK_VERSION@ -include $(top_srcdir)/git.mk seed-webkit2-4.0.0+20161014+6c77960+dfsg1/libseed/seed-api.c000066400000000000000000000574471303774616400221110ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #include "seed-private.h" #include /** * seed_value_protect: * @ctx: A #SeedContext. * @value: The #SeedValue to protect. * * Increments the "protection count" of @value, in case you want to store * a reference somewhere where the garbage collector won't be able to find it, * and don't want it to be collected! * * In order for @value to be collected afterwards, it will need to be * unprotected the same number of times with seed_value_unprotect(). * */ void seed_value_protect(JSContextRef ctx, JSValueRef value) { JSValueProtect(ctx, value); } /** * seed_value_unprotect: * @ctx: A #SeedContext. * @value: The #SeedValue to unprotect. * * Decrements the "protection count" of @value, as explained in * seed_value_protect(). * */ void seed_value_unprotect(JSContextRef ctx, JSValueRef value) { JSValueUnprotect(ctx, value); } /** * seed_context_create: * @group: A #SeedContextGroup in which to create the new context, or %NULL to * create it in the default context group. * @global_class: The #SeedClass to use to create the global object, or %NULL to * create it with the default class. * * Create a new #SeedContext. By default, this creates a new context * which has no global objects; you can add the default set using * seed_prepare_global_context(). * * Return value: A new #SeedContext. * */ JSGlobalContextRef seed_context_create(JSContextGroupRef group, JSClassRef global_class) { return JSGlobalContextCreateInGroup(group, global_class); } /** * seed_context_ref: * @ctx: A #SeedContext. * * Increments the reference count of @ctx. * * Return value: @ctx * */ JSGlobalContextRef seed_context_ref(JSGlobalContextRef ctx) { return JSGlobalContextRetain(ctx); } /** * seed_context_unref: * @ctx: A #SeedContext. * * Decrements the reference count of @ctx. * */ void seed_context_unref(JSGlobalContextRef ctx) { JSGlobalContextRelease(ctx); } /** * seed_context_collect: * @ctx: A #SeedContext. * * Instructs JavaScriptCore to make a garbage collection pass. * The context parameter is currently unused, and a pass is made * through all contexts. * */ void seed_context_collect(JSGlobalContextRef ctx) { JSGarbageCollect(ctx); } /** * seed_make_object: * @ctx: The #SeedContext in which to create the new object. * @class: The #SeedClass to use to create the new object, or %NULL to use the * default object class. * @private: The initial private data of the new object. * * Return value: A new #SeedObject. * */ JSObjectRef seed_make_object(JSContextRef ctx, JSClassRef class, gpointer private) { return JSObjectMake(ctx, class, private); } /** * seed_object_set_property_at_index: * @ctx: A #SeedContext. * @object: A #SeedObject on which to set the property. * @index: The index of the property to set. * @value: The #SeedValue to use as the property's value. * @exception: A reference to a #SeedValue in which to store any exceptions. * Pass %NULL to ignore exceptions. * * Sets the property @index on @object to @value. * */ void seed_object_set_property_at_index(JSContextRef ctx, JSObjectRef object, gint index, JSValueRef value, JSValueRef* exception) { JSObjectSetPropertyAtIndex(ctx, object, index, value, exception); } JSValueRef seed_object_get_property_at_index(JSContextRef ctx, JSObjectRef object, gint index, JSValueRef* exception) { return JSObjectGetPropertyAtIndex(ctx, object, index, exception); } /** * seed_object_call * @ctx: A #SeedContext. * @object: A #SeedObject to call. * @this: The #SeedObject to use as the 'this' object inside the called * function. * @argument_count: The number of arguments in the @arguments array. * @arguments: An array (@argument_count long) of #SeedValues to pass in as the * function's arguments. * @exception: A reference to a #SeedValue in which to store any exceptions. * Pass %NULL to ignore exceptions. * * Calls @object as a function. * * Return value: The @SeedValue returned by the called function, or %NULL if an * exception occurs or the object is not a function. * */ JSValueRef seed_object_call(JSContextRef ctx, JSObjectRef object, JSObjectRef this, size_t argument_count, const JSValueRef arguments[], JSValueRef* exception) { return JSObjectCallAsFunction(ctx, object, this, argument_count, arguments, exception); } /** * seed_make_script: * @ctx: A #SeedContext. * @js: A string representing the contents of the script. * @source_url: The filename of the script, for reference in errors, or %NULL. * @line_number: The line number of the beginning of the script, for reference * in error messages, or 0. * * Creates a new #SeedScript instance with @js as the contents, then * checks for proper syntax. * * Note: seed_make_script() does not handle the shebang line, and will return a * parse error if one is included in @js. * * Return value: The newly created #SeedScript. * */ SeedScript* seed_make_script(JSContextRef ctx, const gchar* js, const gchar* source_url, gint line_number) { SeedScript* ret = g_new0(SeedScript, 1); if (js) ret->script = JSStringCreateWithUTF8CString(js); else ret->script = JSStringCreateWithUTF8CString(""); if (source_url) { ret->source_url = JSStringCreateWithUTF8CString(source_url); } ret->line_number = line_number; JSCheckScriptSyntax(ctx, ret->script, ret->source_url, ret->line_number, &ret->exception); return ret; } /** * seed_script_new_from_file: * @ctx: A #SeedContext. * @file: The filename of the script to load. * * Uses seed_make_script() to create a #SeedScript from the contents of @file. * * Return value: The newly created #SeedScript. * */ SeedScript* seed_script_new_from_file(JSContextRef ctx, gchar* file) { SeedScript* script; GError* e = NULL; gchar* contents = NULL; seed_importer_get_file_contents(file, &contents, NULL, &e); script = seed_make_script(ctx, contents, file, 0); if (e) { seed_make_exception_from_gerror(ctx, &script->exception, e); g_error_free(e); } return script; } /** * seed_evaluate: * @ctx: A #SeedContext. * @s: A #SeedScript to evaluate. * @this: The object which should be assigned to the "this" global. * * Evaluates a #SeedScript with @this as the global "this" object. * * Return value: The #SeedValue returned by evaluating the script. * */ JSValueRef seed_evaluate(JSContextRef ctx, SeedScript* s, JSObjectRef this) { JSValueRef ret; s->exception = 0; ret = JSEvaluateScript(ctx, s->script, this, s->source_url, s->line_number, &s->exception); return ret; } /** * seed_simple_evaluate: * @ctx: A #SeedContext. * @source: A string representing the JavaScript to evaluate. * @exception: A #SeedException pointer to store an exception in. * * Evaluates a string of JavaScript in @ctx; if an exception * is raised in the context of the script, it will be placed in @exception. * * Return value: The #SeedValue returned by evaluating the script. * */ JSValueRef seed_simple_evaluate(JSContextRef ctx, const gchar* source, JSValueRef* exception) { JSValueRef ret; JSStringRef script = JSStringCreateWithUTF8CString(source); ret = JSEvaluateScript(ctx, script, NULL, NULL, 0, exception); JSStringRelease(script); return ret; } /** * seed_script_exception: * @s: A #SeedScript. * * Retrieves the exception (if any) raised during the evaluation of @s. * * Return value: A #SeedException representing the exception of @s. * */ JSValueRef seed_script_exception(SeedScript* s) { return s->exception; } /** * seed_string_get_maximum_size: * @string: A #SeedString. * * Return value: The maximum number of bytes @string will take up if converted * to a null-terminated UTF8 string. * */ gsize seed_string_get_maximum_size(JSStringRef string) { return JSStringGetMaximumUTF8CStringSize(string); } /** * seed_string_to_utf8_buffer: * @string: A #SeedString. * @buffer: An allocated string. * @buffer_size: The length of @buffer, in bytes. * * Return value: A the number of bytes copied into @buffer. * */ gsize seed_string_to_utf8_buffer(JSStringRef string, gchar* buffer, size_t buffer_size) { return JSStringGetUTF8CString(string, buffer, buffer_size); } /** * seed_string_is_equal: * @a: The first #SeedString to compare. * @b: The second #SeedString to compare. * * Return value: #true, if a and b are equal, #false otherwise. * */ gboolean seed_string_is_equal(JSStringRef a, JSStringRef b) { return JSStringIsEqual(a, b); } /** * seed_string_is_equal_utf8: * @a: The #SeedString to compare. * @b: A #gchar* to compare to. * * Tests the equality of a SeedString and a UTF-8 C-style string. * * Return value: #true, if a and b are equal, #false otherwise. * */ gboolean seed_string_is_equal_utf8(JSStringRef a, const gchar* b) { return JSStringIsEqualToUTF8CString(a, b); } /** * seed_string_ref: * @string: A #SeedString. * * Increments the reference count of @string. * * Return value: @string * */ JSStringRef seed_string_ref(JSStringRef string) { return JSStringRetain(string); } /** * seed_string_unref: * @string: A #SeedString. * * Decrements the reference count of @string. * */ void seed_string_unref(JSStringRef string) { JSStringRelease(string); } void seed_script_destroy(SeedScript* s) { seed_string_unref(s->script); if (s->source_url) seed_string_unref(s->source_url); g_free(s); } // TODO:FIXME: Do we have an external typedef or anything for JSClassDefinition? /** * seed_create_class: * @def: A #JSClassDefinition. * * Return value: A #SeedClass, described by @def. * */ JSClassRef seed_create_class(JSClassDefinition* def) { return JSClassCreate(def); } /* TODO:FIXME: GtkDoc is choking on JSObjectCallAsConstructorCallback, and merging it into the parameter name...??! */ /** * seed_make_constructor: * @ctx: A #SeedContext. * @class: A #SeedClass to use as the default for constructed objects. * @constructor: The #JSObjectCallAsConstructorCallback function to call when * the constructor is invoked with 'new'. * * Return value: A #SeedObject, which is a constructor function. * */ JSObjectRef seed_make_constructor(JSContextRef ctx, JSClassRef class, JSObjectCallAsConstructorCallback constructor) { return JSObjectMakeConstructor(ctx, class, constructor); } /** * seed_object_get_private: * @object: A #SeedObject. * * Retrieves the private data of @object. * * Return value: A pointer to the private data of @object. * */ gpointer seed_object_get_private(JSObjectRef object) { return (gpointer) JSObjectGetPrivate(object); } /** * seed_object_set_private: * @object: A #SeedObject. * @value: A #gpointer to set the private data of @object to. * * Sets the private data of @object to @value. * */ void seed_object_set_private(JSObjectRef object, gpointer value) { JSObjectSetPrivate(object, value); } /** * seed_value_is_null: * @ctx: A #SeedContext. * @value: A #SeedValue. * * Determine whether or not @value represents the JavaScript null value * * Return value: A #gboolean (%true if @value is 'null') * */ gboolean seed_value_is_null(JSContextRef ctx, JSValueRef value) { return JSValueIsNull(ctx, value); } /** * seed_value_is_undefined: * @ctx: A #SeedContext. * @value: A #SeedValue. * * Determine whether or not @value represents the JavaScript undefined value * * Return value: A #gboolean (%true if @value is 'undefined') * */ gboolean seed_value_is_undefined(JSContextRef ctx, JSValueRef value) { return JSValueIsUndefined(ctx, value); } /** * seed_value_is_object: * @ctx: A #SeedContext. * @value: A #SeedValue. * * Determine whether or not @value is a JavaScript object * * Return value: A #gboolean (%true if @value is an object) * */ gboolean seed_value_is_object(JSContextRef ctx, JSValueRef value) { return !seed_value_is_null(ctx, value) && JSValueIsObject(ctx, value); } /** * seed_value_is_object_of_class: * @ctx: A #SeedContext. * @value: A #SeedValue. * @klass: A #SeedClass. * * Determine whether or not @value is an object of the specified class * * Return value: A #gboolean (%true if @value is of class @klass) * */ gboolean seed_value_is_object_of_class(JSContextRef ctx, JSValueRef value, JSClassRef klass) { return !seed_value_is_null(ctx, value) && JSValueIsObjectOfClass(ctx, value, klass); } /** * seed_value_is_function: * @ctx: A #SeedContext. * @value: A #SeedValue. * * Determine whether or not @value is a JavaScript function (and, therefore, * an object) * * Return value: A #gboolean (%true if @value is a function) * */ gboolean seed_value_is_function(JSContextRef ctx, JSObjectRef value) { return seed_value_is_object(ctx, value) && JSObjectIsFunction(ctx, value); } /** * seed_value_is_string: * @ctx: A #SeedContext. * @value: A #SeedValue. * * Determine whether or not @value is a JavaScript string * * Return value: A #gboolean (%true if @value is a string) * */ gboolean seed_value_is_string(JSContextRef ctx, JSValueRef value) { return JSValueIsString(ctx, value); } /** * seed_value_is_number: * @ctx: A #SeedContext. * @value: A #SeedValue. * * Determine whether or not @value is a JavaScript number * * Return value: A #gboolean (%true if @value is a number) * */ gboolean seed_value_is_number(JSContextRef ctx, JSValueRef value) { return JSValueIsNumber(ctx, value); } /** * seed_engine_set_search_path: * @eng: A #SeedEngine, on which to set the path. * @path: A #const gchar*, a colon separated string containing the path to set * * Sets the search path for the imports system. * */ void seed_engine_set_search_path(SeedEngine* eng, const gchar* path) { /* this should be null from seed_init unless there's already a path set. */ g_strfreev(eng->search_path); eng->search_path = g_strsplit(path, ":", -1); } /** * seed_engine_get_search_path: * @eng: A #SeedEngine, to get the currently set search path. * * Retrieves the search path for the imports system. The returned value is * owned by the #SeedEngine, and shouldn't be freed by the application writer. * * Return value: A null-terminated array of strings containing the paths. * */ gchar** seed_engine_get_search_path(SeedEngine* eng) { return eng->search_path; } /** * seed_signal_connect_full: * @ctx: A valid #SeedContext * @object: A #GObject, to connect the signal on. * @signal: A signal specification. * @function: The JavaScript function to connect to the signal. * @user_data: An additional parameter to pass to the function. * * Connects @function to the signal specified by @signal on @object. @user_data * is passed as the user_data argument to the callback function. * */ void seed_signal_connect_full(JSContextRef ctx, GObject* object, const gchar* signal, JSObjectRef function, JSObjectRef user_data) { seed_gobject_signal_connect(ctx, signal, object, function, NULL, user_data); } /** * seed_signal_connect: * @ctx: A valid #SeedContext * @object: A #GObject, to connect the signal on. * @signal: A signal specification. * @script: The script to connect to the signal. Should return a function. * * Evaluates @script, which should return a function, then connects the returned * function to the signal specified by @signal on @object. @user_data * is passed as the user_data argument to the callback function. * */ void seed_signal_connect(JSContextRef ctx, GObject* object, const gchar* signal, const gchar* script) { JSValueRef func; func = seed_simple_evaluate(ctx, script, NULL); seed_signal_connect_full(ctx, object, signal, (JSObjectRef) func, NULL); } /** * seed_context_get_global_object: * @ctx: A valid #SeedContext * * Return value: The global object for @ctx. */ JSObjectRef seed_context_get_global_object(JSGlobalContextRef ctx) { return JSContextGetGlobalObject(ctx); } /** * seed_make_array: * @ctx: A valid #SeedContext * @elements: An array of #SeedValue's with which to populate the array. * @num_elements: The number of values, in @elements * @exception: A #SeedException in which to store an exception. * Pass %NULL to ignore exceptions. * * Creates a JavaScript Array object from @elements, a C-style array of * SeedValues. * * Return value: A new array object, populated with @elements. */ JSObjectRef seed_make_array(JSContextRef ctx, const JSValueRef elements[], gsize num_elements, JSValueRef* exception) { return JSObjectMakeArray(ctx, num_elements, elements, exception); } /** * seed_make_null: * @ctx: A valid #SeedContext * * Note that this function returns a valid SeedValue, * representing the null JavaScript value, and not a * null SeedValue. * * Return value: A #SeedValue of the 'null' type. * */ JSValueRef seed_make_null(JSContextRef ctx) { return JSValueMakeNull(ctx); } /** * seed_make_undefined: * @ctx: A valid #SeedContext * * Note that this function returns a valid SeedValue, * representing the undefined JavaScript value, and not an * undefined SeedValue. * * Return value: A #SeedValue of the 'undefined' type. */ JSValueRef seed_make_undefined(JSContextRef ctx) { return JSValueMakeUndefined(ctx); } /** * seed_value_get_type: * @ctx: A valid #SeedContext * @value: A #SeedValue * * Return value: The type of @value */ JSType seed_value_get_type(JSContextRef ctx, JSValueRef value) { return JSValueGetType(ctx, value); } /** * seed_object_copy_property_names: * @ctx: A valid #SeedContext * @object: An object from which to copy property names. * * Return value: A %NULL terminated array containing the property names of * @object */ gchar** seed_object_copy_property_names(JSContextRef ctx, JSObjectRef object) { JSPropertyNameArrayRef names; JSStringRef name; guint i, length; gsize max_length; gchar* c_name; gchar** ret; names = JSObjectCopyPropertyNames(ctx, object); length = JSPropertyNameArrayGetCount(names); ret = (gchar**) g_malloc((length + 1) * sizeof(gchar*)); for (i = 0; i < length; i++) { name = JSPropertyNameArrayGetNameAtIndex(names, i); max_length = JSStringGetMaximumUTF8CStringSize(name); c_name = (gchar*) g_malloc(max_length * sizeof(gchar)); JSStringGetUTF8CString(name, c_name, max_length); ret[i] = c_name; } ret[length] = NULL; JSPropertyNameArrayRelease(names); return ret; } /** * seed_object_get_prototype: * @ctx: A valid #SeedContext * @obj: A #SeedObject * * Return value: The prototype of @obj. */ JSObjectRef seed_object_get_prototype(JSContextRef ctx, JSObjectRef obj) { return (JSObjectRef) JSObjectGetPrototype(ctx, obj); } gboolean seed_object_is_of_class(JSContextRef ctx, JSObjectRef obj, JSClassRef class) { return JSValueIsObjectOfClass(ctx, obj, class); } /** * seed_make_function: * @ctx: A valid #SeedContext * @func: A #SeedFunctionCallback to implement the function. * @name: The name of the function (used in exceptions). * * Creates a JavaScript object representing a first-class function; when * the function is called from JavaScript, @func will be called. * * Return value: A #SeedObject representing the function */ JSObjectRef seed_make_function(JSContextRef ctx, gpointer func, gchar* name) { JSObjectRef oref; JSStringRef jsname = NULL; if (name) jsname = JSStringCreateWithUTF8CString(name); oref = JSObjectMakeFunctionWithCallback(ctx, NULL, func); if (jsname) JSStringRelease(jsname); return oref; } /** * seed_value_to_format: * @ctx: A valid #SeedContext * @format: Format string to use. * @exception: Location to store an exception. * @values: The values to convert. * @Varargs: A %NULL-terminated list of locations to store the results of * conversion. * * A convenience API for converting multiple values at once, the format string * is composed of single characters specifying types, for example: * i: gint * u: guint * o: GObject * * s: gchar * * f: gdouble * c: gchar * * and a valid format string could be "iuo". * * This function may be in particular useful in converting arguments * in a #SeedFunctionCallback. * Return value: Whether conversion was successful. */ gboolean seed_value_to_format(JSContextRef ctx, const gchar* format, JSValueRef* values, JSValueRef* exception, ...) { va_list argp; const gchar* c; guint i = 0; va_start(argp, exception); for (c = format; *c; c++) { JSValueRef val = values[i]; gpointer p = va_arg(argp, gpointer); if (!val || !p) { va_end(argp); return FALSE; } switch (*c) { case 'i': { *((gint*) p) = seed_value_to_int(ctx, val, exception); break; } case 'u': { *((guint*) p) = seed_value_to_uint(ctx, val, exception); break; } case 's': { *((gchar**) p) = seed_value_to_string(ctx, val, exception); break; } case 'f': { *((gdouble*) p) = seed_value_to_int(ctx, val, exception); break; } case 'o': { *((GObject**) p) = seed_value_to_object(ctx, val, exception); break; } case 'c': { *((gchar*) c) = seed_value_to_char(ctx, val, exception); break; } } i++; } va_end(argp); return TRUE; } /*************************** CALLBACK DOCUMENTATION **************************/ /** * SeedFunctionCallback: * @ctx: A #SeedContext * @function: The #SeedObject representing the function * @this_object: The #SeedObject representing the "this" object in the caller * @argument_count: The number of arguments passed into the callback * @arguments: An array of #SeedValues; the value of the arguments passed in * @exception: A reference to a #SeedException; use seed_make_exception() in * order * to throw a JavaScript exception from the callback. * * All native C function callbacks should use the prototype of * SeedFunctionCallback. * * Return value: The #SeedValue to return to the caller */ seed-webkit2-4.0.0+20161014+6c77960+dfsg1/libseed/seed-builtins.c000066400000000000000000000511201303774616400231470ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #include #include "seed-private.h" #include #include #include #include JSValueRef seed_print_ref; JSValueRef seed_printerr_ref; JSValueRef seed_log_error_ref; static JSValueRef seed_include(JSContextRef ctx, JSObjectRef function, JSObjectRef this_object, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { JSStringRef file_contents, file_name; GDir* dir; gchar *import_file, *abs_path; gchar *walk, *buffer = NULL; guint i, len; if (argumentCount != 1) { seed_make_exception(ctx, exception, "ArgumentError", "Seed.include expected 1 argument, " "got %zd", argumentCount); return JSValueMakeNull(ctx); } import_file = seed_value_to_string(ctx, arguments[0], exception); /* just try current dir if no path set, or use the absolute path */ if (!eng->search_path || g_path_is_absolute(import_file)) seed_importer_get_file_contents(import_file, &buffer, 0, NULL); else /* A search path is set and path given is not absolute. */ { len = g_strv_length(eng->search_path); for (i = 0; i < len; ++i) { dir = g_dir_open(eng->search_path[i], 0, NULL); if (!dir) /* skip bad path entries */ continue; abs_path = g_build_filename(eng->search_path[i], import_file, NULL); if (seed_importer_get_file_contents(abs_path, &buffer, 0, NULL)) { g_free(abs_path); g_dir_close(dir); break; } g_dir_close(dir); g_free(abs_path); } } if (!buffer) { seed_make_exception(ctx, exception, "FileNotFound", "File not found: %s", import_file); g_free(import_file); g_free(buffer); return JSValueMakeNull(ctx); } walk = buffer; if (*walk == '#') { while (*walk != '\n') walk++; walk++; } walk = g_strdup(walk); g_free(buffer); file_contents = JSStringCreateWithUTF8CString(walk); file_name = JSStringCreateWithUTF8CString(import_file); JSEvaluateScript(ctx, file_contents, NULL, file_name, 0, exception); JSStringRelease(file_contents); JSStringRelease(file_name); g_free(import_file); g_free(walk); return JSValueMakeUndefined(ctx); } static JSValueRef seed_scoped_include(JSContextRef ctx, JSObjectRef function, JSObjectRef this_object, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { JSContextRef nctx; JSObjectRef global; JSStringRef file_contents, file_name; GDir* dir; gchar *import_file, *abs_path; gchar *walk, *buffer = NULL; guint i; if (argumentCount != 1) { seed_make_exception(ctx, exception, "ArgumentError", "Seed.include expected 1 argument, " "got %zd", argumentCount); return JSValueMakeNull(ctx); } import_file = seed_value_to_string(ctx, arguments[0], exception); /* just try current dir if no path set, or use the absolute path */ if (!eng->search_path || g_path_is_absolute(import_file)) seed_importer_get_file_contents(import_file, &buffer, 0, NULL); else /* A search path is set and path given is not absolute. */ { for (i = 0; i < g_strv_length(eng->search_path); ++i) { dir = g_dir_open(eng->search_path[i], 0, NULL); if (!dir) /* skip bad path entries */ continue; abs_path = g_build_filename(eng->search_path[i], import_file, NULL); if (seed_importer_get_file_contents(abs_path, &buffer, 0, NULL)) { g_free(abs_path); break; } g_dir_close(dir); g_free(abs_path); } } if (!buffer) { seed_make_exception(ctx, exception, "FileNotFound", "File not found: %s", import_file); g_free(import_file); g_free(buffer); return JSValueMakeNull(ctx); } walk = buffer; if (*walk == '#') { while (*walk != '\n') walk++; walk++; } walk = g_strdup(walk); g_free(buffer); file_contents = JSStringCreateWithUTF8CString(walk); file_name = JSStringCreateWithUTF8CString(import_file); nctx = JSGlobalContextCreateInGroup(context_group, 0); seed_prepare_global_context(nctx); JSEvaluateScript(nctx, file_contents, NULL, file_name, 0, exception); global = JSContextGetGlobalObject(nctx); JSGlobalContextRelease((JSGlobalContextRef) nctx); JSStringRelease(file_contents); JSStringRelease(file_name); g_free(import_file); g_free(walk); return global; } static JSValueRef seed_print(JSContextRef ctx, JSObjectRef function, JSObjectRef this_object, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { gchar* buf; if (argumentCount != 1) { seed_make_exception(ctx, exception, "ArgumentError", "print expected 1 argument, got %zd", argumentCount); return JSValueMakeNull(ctx); } buf = seed_value_to_string(ctx, arguments[0], exception); g_print("%s\n", buf); g_free(buf); return JSValueMakeUndefined(ctx); } static JSValueRef seed_log_error(JSContextRef ctx, JSObjectRef function, JSObjectRef this_object, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { gchar* buf1; gchar* buf2 = NULL; if (argumentCount != 1 && argumentCount != 2) { seed_make_exception(ctx, exception, "ArgumentError", "logError expected 1 or 2 argument, got %zd", argumentCount); return JSValueMakeNull(ctx); } buf1 = seed_value_to_string(ctx, arguments[0], exception); if (argumentCount == 2) { buf2 = seed_value_to_string(ctx, arguments[1], exception); g_print("%s - %s\n", buf1, buf2); } else { g_print("%s\n", buf1); } g_free(buf1); g_free(buf2); return JSValueMakeUndefined(ctx); } static JSValueRef seed_printerr(JSContextRef ctx, JSObjectRef function, JSObjectRef this_object, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { gchar* buf; if (argumentCount != 1) { seed_make_exception(ctx, exception, "ArgumentError", "printerr expected 1 argument, got %zd", argumentCount); return JSValueMakeNull(ctx); } buf = seed_value_to_string(ctx, arguments[0], exception); g_printerr("%s\n", buf); g_free(buf); return JSValueMakeUndefined(ctx); } const gchar* seed_g_type_name_to_string(GITypeInfo* type) { GITypeTag type_tag = g_type_info_get_tag(type); const gchar* type_name; GIBaseInfo* interface; if (type_tag == GI_TYPE_TAG_INTERFACE) { interface = g_type_info_get_interface(type); type_name = g_base_info_get_name(interface); g_base_info_unref(interface); } else { type_name = g_type_tag_to_string(type_tag); } return type_name; } static JSValueRef seed_introspect(JSContextRef ctx, JSObjectRef function, JSObjectRef this_object, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { // TODO: LEAKY! GICallableInfo* info; JSObjectRef data_obj, args_obj, argument; guint i, nargs; if (argumentCount != 1) { seed_make_exception(ctx, exception, "ArgumentError", "Seed.introspect expected 1 argument, " "got %zd", argumentCount); return JSValueMakeNull(ctx); } if (!JSValueIsObject(ctx, arguments[0])) return JSValueMakeNull(ctx); if (!JSValueIsObjectOfClass(ctx, arguments[0], gobject_method_class)) return JSValueMakeNull(ctx); info = (GICallableInfo*) JSObjectGetPrivate((JSObjectRef) arguments[0]); data_obj = JSObjectMake(ctx, NULL, NULL); seed_object_set_property(ctx, data_obj, "name", (JSValueRef) seed_value_from_string( ctx, g_base_info_get_name((GIBaseInfo*) info), exception)); seed_object_set_property( ctx, data_obj, "return_type", seed_value_from_string(ctx, seed_g_type_name_to_string( g_callable_info_get_return_type(info)), exception)); args_obj = JSObjectMake(ctx, NULL, NULL); seed_object_set_property(ctx, data_obj, "args", args_obj); nargs = g_callable_info_get_n_args(info); for (i = 0; i < nargs; ++i) { argument = JSObjectMake(ctx, NULL, NULL); GIArgInfo* arg_info = g_callable_info_get_arg(info, i); const gchar* arg_type = seed_g_type_name_to_string(g_arg_info_get_type(arg_info)); const gchar* arg_name = g_base_info_get_name((GIBaseInfo*) arg_info); GIDirection dir = g_arg_info_get_direction(arg_info); seed_object_set_property(ctx, argument, "type", seed_value_from_string(ctx, arg_type, exception)); seed_object_set_property(ctx, argument, "name", seed_value_from_string(ctx, arg_name, exception)); seed_object_set_property( ctx, argument, "allow_none", seed_value_from_boolean(ctx, g_arg_info_may_be_null(arg_info) ? 1 : 0, exception)); seed_object_set_property( ctx, argument, "direction", seed_value_from_string(ctx, dir == GI_DIRECTION_OUT ? "out" : (dir == GI_DIRECTION_IN ? "in" : "inout"), exception)); JSObjectSetPropertyAtIndex(ctx, args_obj, i, argument, NULL); } return data_obj; } static JSValueRef seed_check_syntax(JSContextRef ctx, JSObjectRef function, JSObjectRef this_object, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { JSStringRef jsstr; if (argumentCount == 1) { jsstr = JSValueToStringCopy(ctx, arguments[0], exception); JSCheckScriptSyntax(ctx, jsstr, 0, 0, exception); if (jsstr) JSStringRelease(jsstr); } else { seed_make_exception(ctx, exception, "ArgumentError", "Seed.check_syntax expected " "1 argument, got %zd", argumentCount); } return JSValueMakeNull(ctx); } static JSValueRef seed_spawn(JSContextRef ctx, JSObjectRef function, JSObjectRef this_object, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { gchar *line, *stdoutstr, *stderrstr; JSObjectRef ret; GError* error = NULL; if (argumentCount != 1) { // I am so lazy seed_make_exception(ctx, exception, "ArgumentError", "Seed.spawn expected 1 argument"); return JSValueMakeNull(ctx); } line = seed_value_to_string(ctx, arguments[0], exception); g_spawn_command_line_sync(line, &stdoutstr, &stderrstr, NULL, &error); if (error) { seed_make_exception_from_gerror(ctx, exception, error); g_free(line); g_error_free(error); return JSValueMakeNull(ctx); } ret = JSObjectMake(ctx, NULL, NULL); seed_object_set_property(ctx, ret, "stdout", seed_value_from_string(ctx, stdoutstr, exception)); seed_object_set_property(ctx, ret, "stderr", seed_value_from_string(ctx, stderrstr, exception)); g_free(line); g_free(stdoutstr); g_free(stderrstr); return ret; } static JSValueRef seed_quit(JSContextRef ctx, JSObjectRef function, JSObjectRef this_object, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { if (argumentCount == 1) { exit(seed_value_to_int(ctx, arguments[0], NULL)); } else if (argumentCount > 1) { seed_make_exception(ctx, exception, "ArgumentError", "Seed.quit expected " "1 argument, got %zd", argumentCount); } exit(EXIT_SUCCESS); } static JSValueRef seed_breakpoint(JSContextRef ctx, JSObjectRef function, JSObjectRef this_object, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { G_BREAKPOINT(); return JSValueMakeUndefined(ctx); } static JSValueRef seed_argv_get_property(JSContextRef ctx, JSObjectRef object, JSStringRef property_name, JSValueRef* exception) { SeedArgvPrivates* priv; gchar* cproperty_name; gsize length; gint index; priv = JSObjectGetPrivate(object); if (!priv->argc) return JSValueMakeUndefined(ctx); length = JSStringGetMaximumUTF8CStringSize(property_name); cproperty_name = g_alloca(length * sizeof(gchar)); JSStringGetUTF8CString(property_name, cproperty_name, length); if (!g_strcmp0(cproperty_name, "length")) { return seed_value_from_int(ctx, priv->argc, exception); } index = atoi(cproperty_name); if (index >= 0 && index < priv->argc) { return seed_value_from_string(ctx, priv->argv[index], exception); } else { seed_make_exception(ctx, exception, "ArgumentError", "ArgumentCount " "%d, got %d", priv->argc, index); return JSValueMakeNull(ctx); } } JSClassDefinition seed_argv_def = { 0, /* Version, always 0 */ kJSClassAttributeNoAutomaticPrototype, /* JSClassAttributes */ "argv_array", /* Class Name */ NULL, /* Parent Class */ NULL, /* Static Values */ NULL, NULL, NULL, NULL, /* Has Property */ seed_argv_get_property, /* Get Property */ NULL, NULL, /* Delete Property */ NULL, /* Get Property Names */ NULL, /* Call As Function */ NULL, /* Call As Constructor */ NULL, /* Has Instance */ NULL /* Convert To Type */ }; JSClassRef seed_argv_class; static JSValueRef seed_ARGV_get_property(JSContextRef ctx, JSObjectRef object, JSStringRef property_name, JSValueRef* exception) { SeedArgvPrivates* priv; gchar* cproperty_name; gsize length; gint index; priv = JSObjectGetPrivate(object); if (!priv->argc) return JSValueMakeUndefined(ctx); length = JSStringGetMaximumUTF8CStringSize(property_name); cproperty_name = g_alloca(length * sizeof(gchar)); JSStringGetUTF8CString(property_name, cproperty_name, length); if (!g_strcmp0(cproperty_name, "length")) { return seed_value_from_int(ctx, priv->argc - 2, exception); } index = atoi(cproperty_name); if (index >= 0 && index < priv->argc - 2) { return seed_value_from_string(ctx, priv->argv[index + 2], exception); } else { seed_make_exception(ctx, exception, "ArgumentError", "ArgumentCount " "%d, got %d", priv->argc - 2, index); return JSValueMakeNull(ctx); } } JSClassDefinition seed_ARGV_def = { 0, /* Version, always 0 */ kJSClassAttributeNoAutomaticPrototype, /* JSClassAttributes */ "argv_array", /* Class Name */ NULL, /* Parent Class */ NULL, /* Static Values */ NULL, NULL, NULL, NULL, /* Has Property */ seed_ARGV_get_property, /* Get Property */ NULL, NULL, /* Delete Property */ NULL, /* Get Property Names */ NULL, /* Call As Function */ NULL, /* Call As Constructor */ NULL, /* Has Instance */ NULL /* Convert To Type */ }; JSClassRef seed_ARGV_class; void seed_init_builtins(SeedEngine* local_eng, gint* argc, gchar*** argv) { SeedArgvPrivates* priv; JSObjectRef argvArrayObj; JSObjectRef ARGVArrayObj; JSObjectRef obj = (JSObjectRef) seed_object_get_property(local_eng->context, local_eng->global, "Seed"); seed_create_function(local_eng->context, "include", &seed_include, obj); seed_create_function(local_eng->context, "scoped_include", &seed_scoped_include, obj); seed_print_ref = JSObjectMakeFunctionWithCallback(local_eng->context, NULL, &seed_print); seed_object_set_property(local_eng->context, obj, "print", seed_print_ref); seed_object_set_property(local_eng->context, local_eng->global, "print", seed_print_ref); seed_object_set_property(local_eng->context, local_eng->global, "log", seed_print_ref); JSValueProtect(local_eng->context, seed_print_ref); seed_printerr_ref = JSObjectMakeFunctionWithCallback(local_eng->context, NULL, &seed_printerr); seed_object_set_property(local_eng->context, obj, "printerr", seed_printerr_ref); seed_object_set_property(local_eng->context, local_eng->global, "printerr", seed_printerr_ref); JSValueProtect(local_eng->context, seed_printerr_ref); seed_log_error_ref = JSObjectMakeFunctionWithCallback(local_eng->context, NULL, &seed_log_error); seed_object_set_property(local_eng->context, local_eng->global, "logError", seed_log_error_ref); JSValueProtect(local_eng->context, seed_log_error_ref); seed_create_function(local_eng->context, "check_syntax", &seed_check_syntax, obj); seed_create_function(local_eng->context, "introspect", &seed_introspect, obj); seed_create_function(local_eng->context, "spawn", &seed_spawn, obj); seed_create_function(local_eng->context, "quit", &seed_quit, obj); seed_create_function(local_eng->context, "breakpoint", &seed_breakpoint, obj); priv = g_new0(SeedArgvPrivates, 1); priv->argv = argv ? *argv : 0; priv->argc = argc ? *argc : 0; seed_argv_class = JSClassCreate(&seed_argv_def); argvArrayObj = JSObjectMake(local_eng->context, seed_argv_class, priv); seed_object_set_property(local_eng->context, obj, "argv", argvArrayObj); seed_ARGV_class = JSClassCreate(&seed_ARGV_def); ARGVArrayObj = JSObjectMake(local_eng->context, seed_ARGV_class, priv); seed_object_set_property(local_eng->context, local_eng->global, "ARGV", ARGVArrayObj); } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/libseed/seed-builtins.h000066400000000000000000000023011303774616400231510ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #ifndef _SEED_BUILTINS_H_ #define _SEED_BUILTINS_H_ #include "seed-private.h" extern JSValueRef seed_print_ref; extern JSValueRef seed_printerr_ref; void seed_init_builtins(SeedEngine* local_eng, gint* argc, gchar*** argv); extern JSClassRef seed_argv_class; typedef struct _SeedArgvPrivates { gchar** argv; gint argc; } SeedArgvPrivates; #endif seed-webkit2-4.0.0+20161014+6c77960+dfsg1/libseed/seed-closure.c000066400000000000000000000370031303774616400227760ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #include "seed-private.h" #include #include JSClassRef seed_native_callback_class; static void seed_closure_finalize(JSObjectRef object) { SeedNativeClosure* privates = (SeedNativeClosure*) JSObjectGetPrivate(object); SEED_NOTE(FINALIZATION, "Finalizing closure object %p with " "GIBaseInfo: %s \n", object, g_base_info_get_name((GIBaseInfo*) privates->info)); g_free(privates->cif->arg_types); g_free(privates->cif); g_callable_info_free_closure(privates->info, privates->closure); g_base_info_unref((GIBaseInfo*) privates->info); } static void seed_handle_closure(ffi_cif* cif, void* result, void** args, gpointer userdata) { SeedNativeClosure* privates = userdata; gint num_args, i; JSValueRef* jsargs; JSValueRef return_value, exception = 0; GITypeTag return_tag; GIArgInfo* arg_info; GITypeInfo* return_type; GITypeInfo* arg_type; GITypeTag tag; GArgument rarg, return_arg; JSContextRef ctx = JSGlobalContextCreateInGroup(context_group, 0); GArgument* arg = &rarg; gchar* mes; seed_prepare_global_context(ctx); SEED_NOTE(INVOCATION, "Invoking closure of type: %s \n", g_base_info_get_name((GIBaseInfo*) privates->info)); num_args = g_callable_info_get_n_args(privates->info); return_type = g_callable_info_get_return_type(privates->info); return_tag = g_type_info_get_tag(return_type); jsargs = (JSValueRef*) g_newa(JSValueRef, num_args); for (i = 0; i < num_args; i++) { arg_info = g_callable_info_get_arg(privates->info, i); arg_type = g_arg_info_get_type(arg_info); tag = g_type_info_get_tag(arg_type); switch (tag) { #if GOBJECT_INTROSPECTION_VERSION < 0x000900 case GI_TYPE_TAG_LONG: arg->v_long = *(glong*) args[i]; break; case GI_TYPE_TAG_ULONG: arg->v_ulong = *(gulong*) args[i]; break; case GI_TYPE_TAG_INT: arg->v_int = *(gint*) args[i]; break; case GI_TYPE_TAG_SSIZE: arg->v_ssize = *(gssize*) args[i]; break; case GI_TYPE_TAG_SIZE: arg->v_size = *(gsize*) args[i]; break; case GI_TYPE_TAG_UINT: arg->v_uint = *(guint*) args[i]; break; #endif case GI_TYPE_TAG_BOOLEAN: arg->v_boolean = *(gboolean*) args[i]; break; case GI_TYPE_TAG_INT8: arg->v_int8 = *(gint8*) args[i]; break; case GI_TYPE_TAG_UINT8: arg->v_uint8 = *(guint8*) args[i]; break; case GI_TYPE_TAG_INT16: arg->v_int16 = *(gint16*) args[i]; break; case GI_TYPE_TAG_UINT16: arg->v_uint16 = *(guint16*) args[i]; break; case GI_TYPE_TAG_INT32: arg->v_int32 = *(gint32*) args[i]; break; case GI_TYPE_TAG_UINT32: arg->v_uint32 = *(guint32*) args[i]; break; case GI_TYPE_TAG_INT64: arg->v_int64 = *(gint64*) args[i]; break; case GI_TYPE_TAG_UINT64: arg->v_uint64 = *(guint64*) args[i]; break; case GI_TYPE_TAG_FLOAT: arg->v_float = *(gfloat*) args[i]; break; case GI_TYPE_TAG_DOUBLE: arg->v_double = *(gdouble*) args[i]; break; case GI_TYPE_TAG_UTF8: arg->v_string = *(gchar**) args[i]; break; case GI_TYPE_TAG_INTERFACE: { GIBaseInfo* interface; GIInfoType interface_type; interface = g_type_info_get_interface(arg_type); interface_type = g_base_info_get_type(interface); if (interface_type == GI_INFO_TYPE_OBJECT || interface_type == GI_INFO_TYPE_INTERFACE) { arg->v_pointer = *(gpointer*) args[i]; g_base_info_unref(interface); break; } else if (interface_type == GI_INFO_TYPE_ENUM || interface_type == GI_INFO_TYPE_FLAGS) { arg->v_double = *(double*) args[i]; g_base_info_unref(interface); break; } else if (interface_type == GI_INFO_TYPE_STRUCT) { arg->v_pointer = *(gpointer*) args[i]; g_base_info_unref(interface); break; } g_base_info_unref(interface); } case GI_TYPE_TAG_GLIST: case GI_TYPE_TAG_GSLIST: case GI_TYPE_TAG_GHASH: arg->v_pointer = *(gpointer*) args[i]; break; default: arg->v_pointer = 0; } jsargs[i] = seed_value_from_gi_argument(ctx, arg, arg_type, 0); seed_gi_release_arg(g_arg_info_get_ownership_transfer(arg_info), arg_type, arg); g_base_info_unref((GIBaseInfo*) arg_info); g_base_info_unref((GIBaseInfo*) arg_type); } return_value = (JSValueRef) JSObjectCallAsFunction(ctx, (JSObjectRef) privates->function, 0, num_args, jsargs, &exception); if (exception) { mes = seed_exception_to_string(ctx, exception); g_warning("Exception in closure marshal. %s \n", mes); g_free(mes); exception = 0; } seed_value_to_gi_argument(ctx, (JSValueRef) return_value, return_type, GI_TRANSFER_NOTHING, &return_arg, 0); switch (return_tag) { #if GOBJECT_INTROSPECTION_VERSION < 0x000900 case GI_TYPE_TAG_LONG: *(glong*) result = return_arg.v_long; break; case GI_TYPE_TAG_ULONG: *(gulong*) result = return_arg.v_ulong; break; case GI_TYPE_TAG_INT: *(gint*) result = return_arg.v_int; break; case GI_TYPE_TAG_SSIZE: *(gssize*) result = return_arg.v_ssize; break; case GI_TYPE_TAG_SIZE: *(gsize*) result = return_arg.v_size; break; case GI_TYPE_TAG_UINT: *(guint*) result = return_arg.v_uint; break; #endif case GI_TYPE_TAG_BOOLEAN: *(gboolean*) result = return_arg.v_boolean; break; case GI_TYPE_TAG_INT8: *(gint8*) result = return_arg.v_int8; break; case GI_TYPE_TAG_UINT8: *(guint8*) result = return_arg.v_uint8; break; case GI_TYPE_TAG_INT16: *(gint16*) result = return_arg.v_int16; break; case GI_TYPE_TAG_UINT16: *(guint16*) result = return_arg.v_uint16; break; case GI_TYPE_TAG_INT32: *(gint32*) result = return_arg.v_int32; break; case GI_TYPE_TAG_UINT32: *(guint32*) result = return_arg.v_uint32; break; case GI_TYPE_TAG_INT64: *(gint64*) result = return_arg.v_int64; break; case GI_TYPE_TAG_UINT64: *(guint64*) result = return_arg.v_uint64; break; case GI_TYPE_TAG_FLOAT: *(gfloat*) result = return_arg.v_float; break; case GI_TYPE_TAG_DOUBLE: *(gdouble*) result = return_arg.v_double; break; case GI_TYPE_TAG_UTF8: *(gchar**) result = return_arg.v_string; break; case GI_TYPE_TAG_INTERFACE: { GIBaseInfo* interface; GIInfoType interface_type; interface = g_type_info_get_interface(return_type); interface_type = g_base_info_get_type(interface); if (interface_type == GI_INFO_TYPE_OBJECT || interface_type == GI_INFO_TYPE_INTERFACE) { *(gpointer*) result = return_arg.v_pointer; break; } else if (interface_type == GI_INFO_TYPE_ENUM || interface_type == GI_INFO_TYPE_FLAGS) { *(double*) result = return_arg.v_double; break; } else if (interface_type == GI_INFO_TYPE_STRUCT) { *(gpointer*) result = return_arg.v_pointer; break; } } case GI_TYPE_TAG_GLIST: case GI_TYPE_TAG_GSLIST: case GI_TYPE_TAG_GHASH: *(gpointer*) result = return_arg.v_pointer; break; default: *(gpointer*) result = 0; } g_base_info_unref((GIBaseInfo*) return_type); JSGarbageCollect(ctx); JSGlobalContextRelease((JSGlobalContextRef) ctx); } SeedNativeClosure* seed_make_native_closure(JSContextRef ctx, GICallableInfo* info, JSValueRef function) { ffi_cif* cif; ffi_closure* closure; GITypeInfo* return_type; SeedNativeClosure* privates; JSObjectRef cached; cached = (JSObjectRef) seed_object_get_property(ctx, (JSObjectRef) function, "__seed_native_closure"); if (cached && JSValueIsObjectOfClass(ctx, cached, seed_native_callback_class)) { return (SeedNativeClosure*) JSObjectGetPrivate(cached); } return_type = g_callable_info_get_return_type(info); cif = g_new0(ffi_cif, 1); privates = g_new0(SeedNativeClosure, 1); privates->ctx = ctx; privates->info = (GICallableInfo*) g_base_info_ref((GIBaseInfo*) info); privates->function = function; privates->cif = cif; closure = g_callable_info_prepare_closure(info, cif, seed_handle_closure, privates); privates->closure = closure; JSValueProtect(ctx, function); seed_object_set_property( ctx, (JSObjectRef) function, "__seed_native_closure", (JSValueRef) JSObjectMake(ctx, seed_native_callback_class, privates)); g_base_info_unref((GIBaseInfo*) return_type); return privates; } static void closure_invalidated(gpointer data, GClosure* c) { SeedClosure* closure = (SeedClosure*) c; SEED_NOTE(FINALIZATION, "Finalizing closure."); if (closure->user_data && !JSValueIsUndefined(eng->context, closure->user_data)) JSValueUnprotect(eng->context, closure->user_data); if (!JSValueIsUndefined(eng->context, closure->function)) JSValueUnprotect(eng->context, closure->function); g_free(closure->description); } JSObjectRef seed_closure_get_callable(GClosure* c) { return ((SeedClosure*) c)->function; } JSValueRef seed_closure_invoke(GClosure* closure, JSValueRef* args, guint argc, JSValueRef* exception) { JSContextRef ctx = JSGlobalContextCreateInGroup(context_group, 0); JSValueRef ret; seed_prepare_global_context(ctx); ret = seed_closure_invoke_with_context(ctx, closure, args, argc, exception); JSGlobalContextRelease((JSGlobalContextRef) ctx); return ret; } JSValueRef seed_closure_invoke_with_context(JSContextRef ctx, GClosure* closure, JSValueRef* args, guint argc, JSValueRef* exception) { JSValueRef* real_args = g_newa(JSValueRef, argc + 1); guint i; for (i = 0; i < argc; i++) real_args[i] = args[i]; real_args[argc] = ((SeedClosure*) closure)->user_data ? ((SeedClosure*) closure)->user_data : JSValueMakeNull(ctx); return JSObjectCallAsFunction(ctx, ((SeedClosure*) closure)->function, NULL, argc + 1, real_args, exception); } GClosure* seed_closure_new_for_signal(JSContextRef ctx, JSObjectRef function, JSObjectRef user_data, const gchar* description, guint signal_id) { GClosure* closure; closure = g_closure_new_simple(sizeof(SeedClosure), 0); g_closure_add_finalize_notifier(closure, 0, closure_invalidated); g_closure_set_meta_marshal(closure, GUINT_TO_POINTER(signal_id), seed_signal_marshal_func); JSValueProtect(ctx, function); ((SeedClosure*) closure)->function = function; if (user_data && !JSValueIsNull(ctx, user_data)) { ((SeedClosure*) closure)->user_data = user_data; JSValueProtect(ctx, user_data); } if (description) ((SeedClosure*) closure)->description = g_strdup(description); return closure; } GClosure* seed_closure_new(JSContextRef ctx, JSObjectRef function, JSObjectRef user_data, const gchar* description) { return seed_closure_new_for_signal(ctx, function, user_data, description, 0); } void seed_closure_warn_exception(GClosure* c, JSContextRef ctx, JSValueRef exception) { JSObjectRef callable = seed_closure_get_callable(c); gchar* name = seed_value_to_string(ctx, seed_object_get_property(ctx, callable, "name"), NULL); gchar* mes = seed_exception_to_string(ctx, exception); g_warning("Exception in closure (%p) for %s (handler %s). %s", c, ((SeedClosure*) c)->description, *name == '\0' ? "[anonymous]" : name, mes); g_free(name); g_free(mes); } JSClassDefinition seed_native_callback_def = { 0, /* Version, always 0 */ 0, "seed_native_callback", /* Class Name */ 0, /* Parent Class */ NULL, /* Static Values */ NULL, /* Static Functions */ NULL, seed_closure_finalize, /* Finalize */ NULL, /* Has Property */ NULL, /* Get Property */ NULL, /* Set Property */ NULL, /* Delete Property */ NULL, /* Get Property Names */ NULL, /* Call As Function */ NULL, /* Call As Constructor */ NULL, /* Has Instance */ NULL /* Convert To Type */ }; void seed_closures_init(void) { seed_native_callback_class = JSClassCreate(&seed_native_callback_def); JSClassRetain(seed_native_callback_class); } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/libseed/seed-closure.h000066400000000000000000000053221303774616400230020ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #ifndef _SEED_CLOSURE_H_ #define _SEED_CLOSURE_H_ #include "seed-private.h" typedef struct _SeedClosure { GClosure closure; JSObjectRef function; JSValueRef user_data; GType return_type; gchar* description; } SeedClosure; typedef struct _SeedNativeClosure { JSContextRef ctx; GICallableInfo* info; JSValueRef function; ffi_closure* closure; ffi_cif* cif; } SeedNativeClosure; extern JSClassRef seed_native_callback_class; SeedNativeClosure* seed_make_native_closure(JSContextRef ctx, GICallableInfo* info, JSValueRef function); GClosure* seed_closure_new(JSContextRef ctx, JSObjectRef function, JSObjectRef user_data, const gchar* description); GClosure* seed_closure_new_for_signal(JSContextRef ctx, JSObjectRef function, JSObjectRef user_data, const gchar* description, guint signal_id); JSObjectRef seed_closure_get_callable(GClosure* c); JSValueRef seed_closure_invoke(GClosure* closure, JSValueRef* args, guint argc, JSValueRef* exception); JSValueRef seed_closure_invoke_with_context(JSContextRef ctx, GClosure* closure, JSValueRef* args, guint argc, JSValueRef* exception); void seed_closure_warn_exception(GClosure* c, JSContextRef ctx, JSValueRef exception); void seed_closures_init(); #endif seed-webkit2-4.0.0+20161014+6c77960+dfsg1/libseed/seed-debug.h000066400000000000000000000052061303774616400224150ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #ifndef _SEED_DEBUG_H #define _SEED_DEBUG_H // Borrowed from Clutter, more or less. #include typedef enum { SEED_DEBUG_ALL = 1 << 0, SEED_DEBUG_MISC = 1 << 1, SEED_DEBUG_FINALIZATION = 1 << 2, SEED_DEBUG_INITIALIZATION = 1 << 3, SEED_DEBUG_CONSTRUCTION = 1 << 4, SEED_DEBUG_INVOCATION = 1 << 5, SEED_DEBUG_SIGNAL = 1 << 6, SEED_DEBUG_STRUCTS = 1 << 7, SEED_DEBUG_GTYPE = 1 << 8, SEED_DEBUG_IMPORTER = 1 << 9, SEED_DEBUG_MODULE = 1 << 10 } SeedDebugFlag; #ifdef SEED_ENABLE_DEBUG #define SEED_NOTE(type, ...) \ G_STMT_START \ { \ if ((seed_debug_flags & SEED_DEBUG_##type) \ || seed_debug_flags & SEED_DEBUG_ALL) { \ gchar* _fmt = g_strdup_printf(__VA_ARGS__); \ g_message("[" #type "] " G_STRLOC ": %s", _fmt); \ g_free(_fmt); \ } \ } \ G_STMT_END #define SEED_MARK() SEED_NOTE(MISC, "== mark ==") #define SEED_DBG(x) \ { \ a \ } #else /* !SEED_ENABLE_DEBUG */ #define SEED_NOTE(type, ...) #define SEED_MARK() #define SEED_DBG(x) #endif /* SEED_ENABLE_DEBUG */ extern guint seed_debug_flags; #endif seed-webkit2-4.0.0+20161014+6c77960+dfsg1/libseed/seed-engine.c000066400000000000000000002210651303774616400225720ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #include "seed-private.h" #include "seed-path.h" #include #include #include #include #include #include "seed-signals.h" #include "config.h" JSObjectRef function_proto; JSObjectRef seed_obj_ref; JSObjectRef ARGV_obj_ref; JSObjectRef window_obj_ref; GQuark qname; GQuark qprototype; JSClassRef gobject_signal_class; JSClassRef gobject_named_constructor_class; JSClassRef seed_struct_constructor_class; JSContextGroupRef context_group; JSStringRef defaults_script; gchar* glib_message = 0; GIBaseInfo* base_info_info = 0; GQuark js_ref_quark; guint seed_debug_flags = 0; /* global seed debug flag */ gboolean seed_arg_print_version = FALSE; // Flag to print version and quit pthread_key_t seed_next_gobject_wrapper_key; #ifdef SEED_ENABLE_DEBUG static const GDebugKey seed_debug_keys[] = { { "misc", SEED_DEBUG_MISC }, { "finalization", SEED_DEBUG_FINALIZATION }, { "initialization", SEED_DEBUG_INITIALIZATION }, { "signal", SEED_DEBUG_SIGNAL }, { "invocation", SEED_DEBUG_INVOCATION }, { "structs", SEED_DEBUG_STRUCTS }, { "construction", SEED_DEBUG_CONSTRUCTION }, { "gtype", SEED_DEBUG_GTYPE }, { "importer", SEED_DEBUG_IMPORTER }, { "module", SEED_DEBUG_MODULE } }; #endif /* SEED_ENABLE_DEBUG */ static bool seed_gobject_has_instance(JSContextRef ctx, JSObjectRef constructor, JSValueRef possible_instance, JSValueRef* exception) { GType constructor_type, value_type; if (JSValueIsNull(ctx, possible_instance) || !JSValueIsObject(ctx, possible_instance) || !JSValueIsObjectOfClass(ctx, possible_instance, gobject_class)) return FALSE; constructor_type = (GType) JSObjectGetPrivate(constructor); value_type = G_OBJECT_TYPE( (GObject*) JSObjectGetPrivate((JSObjectRef) possible_instance)); return g_type_is_a(value_type, constructor_type); } /** * seed_prepare_global_context: * @ctx: A #SeedContext on which to add the default set of global objects. * * Adds the default set of global objects (imports, GType, Seed, and print) * to a fresh #SeedContext. * */ void seed_prepare_global_context(JSContextRef ctx) { JSObjectRef global = JSContextGetGlobalObject(ctx); JSStringRef check_sprintf = JSStringCreateWithUTF8CString("sprintf"); seed_object_set_property(ctx, global, "imports", importer); seed_object_set_property(ctx, global, "GType", seed_gtype_constructor); seed_object_set_property(ctx, global, "Seed", seed_obj_ref); seed_object_set_property(ctx, global, "ARGV", ARGV_obj_ref); seed_object_set_property(ctx, global, "window", window_obj_ref); seed_object_set_property(ctx, global, "print", seed_print_ref); seed_object_set_property(ctx, global, "printerr", seed_printerr_ref); /* No need to re-import Seed.js if not needed. */ if (!JSObjectHasProperty(ctx, seed_obj_ref, check_sprintf)) { JSEvaluateScript(ctx, defaults_script, NULL, NULL, 0, NULL); } JSStringRelease(check_sprintf); } static JSObjectRef seed_struct_constructor_invoked(JSContextRef ctx, JSObjectRef constructor, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { GIBaseInfo* info = JSObjectGetPrivate(constructor); JSValueRef ret; JSObjectRef parameters = 0; GType gtype = g_registered_type_info_get_g_type((GIRegisteredTypeInfo*) info); if (gtype == G_TYPE_VARIANT) { JSObjectRef new_internal = (JSObjectRef) seed_object_get_property(ctx, constructor, "_new_internal"); if (JSObjectIsFunction(ctx, new_internal)) { ret = JSObjectCallAsFunction(ctx, new_internal, NULL, argumentCount, arguments, exception); return (JSObjectRef) ret; } } if (argumentCount == 1) { if (!JSValueIsObject(ctx, arguments[0])) { // new GObject.GValue() can accept anything as a argument... if (!g_type_is_a(gtype, G_TYPE_VALUE)) { seed_make_exception(ctx, exception, "ArgumentError", "Constructor expects object as argument"); return (JSObjectRef) JSValueMakeNull(ctx); } } parameters = (JSObjectRef) arguments[0]; } ret = seed_construct_struct_type_with_parameters(ctx, info, parameters, exception); return (JSObjectRef) ret; } static JSObjectRef seed_gobject_constructor_invoked(JSContextRef ctx, JSObjectRef constructor, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { GType type; GParameter* params; GObjectClass* oclass; GObject* gobject; GParamSpec* param_spec; gchar* prop_name; gint i, nparams = 0, length, ri; JSObjectRef ret; JSPropertyNameArrayRef jsprops = 0; JSStringRef jsprop_name; JSValueRef jsprop_value; type = (GType) JSObjectGetPrivate(constructor); if (!type) return 0; oclass = g_type_class_ref(type); // Check for an exception in class init (which may have just been called // by g_type_class_ref, if this is the first construction of this class). // Bubble up the exception, and clear it from the class's qdata so that // this doesn't happen on subsequent construction. GQuark class_init_exception_q = g_quark_from_static_string("type-class-init-exception"); JSValueRef class_init_exception = (JSValueRef) g_type_get_qdata(type, class_init_exception_q); if (class_init_exception) { *exception = class_init_exception; g_type_set_qdata(type, class_init_exception_q, NULL); return NULL; } if (argumentCount > 1) { seed_make_exception(ctx, exception, "ArgumentError", "Constructor expects" " 1 argument, got %zd", argumentCount); return NULL; } if (argumentCount == 1) { if (!JSValueIsObject(ctx, arguments[0])) { seed_make_exception(ctx, exception, "ArgumentError", "Constructor expects object as argument"); g_type_class_unref(oclass); return NULL; } jsprops = JSObjectCopyPropertyNames(ctx, (JSObjectRef) arguments[0]); nparams = JSPropertyNameArrayGetCount(jsprops); } ri = i = 0; params = g_new0(GParameter, nparams + 1); SEED_NOTE(INITIALIZATION, "Constructing object of type %s", g_type_name(type)); pthread_setspecific(seed_next_gobject_wrapper_key, seed_make_wrapper_for_type(ctx, type)); while (i < nparams) { GType type; jsprop_name = JSPropertyNameArrayGetNameAtIndex(jsprops, i); length = JSStringGetMaximumUTF8CStringSize(jsprop_name); prop_name = g_alloca(length * sizeof(gchar)); JSStringGetUTF8CString(jsprop_name, prop_name, length); param_spec = g_object_class_find_property(oclass, prop_name); jsprop_value = JSObjectGetProperty(ctx, (JSObjectRef) arguments[0], jsprop_name, NULL); if (param_spec == NULL) { JSObjectSetProperty(ctx, pthread_getspecific( seed_next_gobject_wrapper_key), jsprop_name, jsprop_value, 0, NULL); ++i; continue; } // TODO: exception handling if (g_type_is_a(param_spec->value_type, G_TYPE_ENUM)) type = G_TYPE_INT; else type = param_spec->value_type; seed_value_to_gvalue(ctx, jsprop_value, type, ¶ms[ri].value, exception); if (*exception) { g_free(params); JSPropertyNameArrayRelease(jsprops); pthread_setspecific(seed_next_gobject_wrapper_key, NULL); return 0; } params[ri].name = prop_name; ++i; ++ri; } if (jsprops) JSPropertyNameArrayRelease(jsprops); SEED_NOTE(INITIALIZATION, "G_TYPE_IS_INSTANTIATABLE = %d G_TYPE_IS_ABSTRACT = %d", G_TYPE_IS_INSTANTIATABLE(type), G_TYPE_IS_ABSTRACT(type)); if (!G_TYPE_IS_INSTANTIATABLE(type) || G_TYPE_IS_ABSTRACT(type)) { seed_make_exception(ctx, exception, "ArgumentError", "Type can not be created - not INSTANTIATABLE"); return (JSObjectRef) JSValueMakeNull(ctx); } gobject = g_object_newv(type, ri, params); if (G_IS_INITIALLY_UNOWNED(gobject) && !g_object_is_floating(gobject)) g_object_ref(gobject); else if (g_object_is_floating(gobject)) g_object_ref_sink(gobject); if (!gobject) ret = (JSObjectRef) JSValueMakeNull(ctx); else ret = (JSObjectRef) seed_value_from_object(ctx, gobject, exception); for (i = 0; i < ri; i++) { g_value_unset(¶ms[i].value); } g_object_unref(gobject); g_type_class_unref(oclass); g_free(params); return ret; } static JSValueRef seed_gobject_property_type(JSContextRef ctx, JSObjectRef function, JSObjectRef this_object, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { GParamSpec* spec; gchar* name; GObject* this; if (argumentCount != 1) { seed_make_exception(ctx, exception, "ArgumentError", "__property_type expects 1 argument" "got %zd", argumentCount); return JSValueMakeNull(ctx); } this = seed_value_to_object(ctx, this_object, exception); name = seed_value_to_string(ctx, arguments[0], exception); spec = g_object_class_find_property(G_OBJECT_GET_CLASS(this), name); g_free(name); return seed_value_from_long(ctx, spec->value_type, exception); } static JSValueRef seed_gobject_ref_count(JSContextRef ctx, JSObjectRef function, JSObjectRef this_object, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { GObject* this; this = seed_value_to_object(ctx, (JSValueRef) this_object, exception); return seed_value_from_int(ctx, this->ref_count, exception); } static void seed_gobject_method_finalize(JSObjectRef method) { GIBaseInfo* info = (GIBaseInfo*) JSObjectGetPrivate(method); if (info) g_base_info_unref(info); } typedef void (*InitMethodCallback)(gint* argc, gchar*** argv); static gboolean seed_gobject_init_build_argv(JSContextRef ctx, JSObjectRef array, SeedArgvPrivates* priv, JSValueRef* exception) { guint i, length; JSValueRef jsl; jsl = seed_object_get_property(ctx, array, "length"); if (JSValueIsNull(ctx, jsl) || JSValueIsUndefined(ctx, jsl)) return FALSE; length = seed_value_to_uint(ctx, jsl, exception); priv->argv = g_new(gchar*, length); priv->argc = length; for (i = 0; i < length; i++) { priv->argv[i] = seed_value_to_string( ctx, JSObjectGetPropertyAtIndex(ctx, array, i, exception), exception); } return TRUE; } static JSValueRef seed_gobject_init_method_invoked(JSContextRef ctx, JSObjectRef function, JSObjectRef this_object, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { GIBaseInfo* info; GTypelib* typelib; InitMethodCallback c; SeedArgvPrivates* priv = NULL; gboolean allocated = FALSE; if (argumentCount != 1 && argumentCount != 2) { seed_make_exception(ctx, exception, "ArgumentError", "init method expects 1 argument, got %zd", argumentCount); return JSValueMakeUndefined(ctx); } if (argumentCount == 1) { if (!JSValueIsNull(ctx, arguments[0]) && !JSValueIsObject(ctx, arguments[0])) { seed_make_exception( ctx, exception, "ArgumentError", "init method expects an array object as argument"); return JSValueMakeUndefined(ctx); } if (JSValueIsNull(ctx, arguments[0])) { priv = NULL; } else if (JSValueIsObjectOfClass(ctx, arguments[0], seed_argv_class)) { priv = JSObjectGetPrivate((JSObjectRef) arguments[0]); } else { priv = g_newa(SeedArgvPrivates, 1); if (!seed_gobject_init_build_argv(ctx, (JSObjectRef) arguments[0], priv, exception)) { seed_make_exception(ctx, exception, "ArgumentError", "Init method expects an array as argument"); return JSValueMakeUndefined(ctx); } allocated = TRUE; } } info = JSObjectGetPrivate(function); typelib = g_base_info_get_typelib(info); g_typelib_symbol(typelib, g_function_info_get_symbol((GIFunctionInfo*) info), (gpointer*) &c); // Backwards compatibility if (!priv) { c(NULL, NULL); return JSValueMakeUndefined(ctx); } c(&priv->argc, &priv->argv); if (allocated) g_free(priv->argv); return JSValueMakeUndefined(ctx); } // Pre-process the arguments list to find which arguments needs to be skipped. gint* _process_skipped_arguments(const JSValueRef arguments[], GIBaseInfo* info, gint* out_skipped_args) { int n_args = g_callable_info_get_n_args((GICallableInfo*) info); int skipped_args = 0; ; int i; gint* skip = g_new0(gint, n_args + 1); GITypeInfo* type_info = NULL; GIArgInfo* arg_info = NULL; for (i = 0; (i < (n_args)); i++) { arg_info = g_callable_info_get_arg((GICallableInfo*) info, i); type_info = g_arg_info_get_type(arg_info); GIDirection dir = g_arg_info_get_direction(arg_info); GITypeTag type_tag = g_type_info_get_tag(type_info); gint array_len_pos = g_type_info_get_array_length(type_info); if (dir == GI_DIRECTION_IN) if (type_tag == GI_TYPE_TAG_ARRAY && g_type_info_get_array_type(type_info) == GI_ARRAY_TYPE_C && array_len_pos >= 0) { skip[array_len_pos] = 1; skipped_args++; } g_base_info_unref((GIBaseInfo*) type_info); g_base_info_unref((GIBaseInfo*) arg_info); type_info = NULL; arg_info = NULL; } *out_skipped_args = skipped_args; return skip; } void _add_jsvalue_in_array(JSContextRef ctx, JSObjectRef dest, gint pos, JSValueRef obj) { gchar* int_str = g_strdup_printf("%d", pos); seed_object_set_property(ctx, (JSObjectRef) dest, int_str, obj); g_free(int_str); } static JSValueRef seed_gobject_method_invoked(JSContextRef ctx, JSObjectRef function, JSObjectRef this_object, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { GIBaseInfo* info; GObject* object = NULL; gboolean instance_method = TRUE; gboolean is_caller_allocates = FALSE; gboolean* caller_allocated; GIBaseInfo* iface_info = NULL; GArgument retval; GArgument* in_args; GArgument* out_args; GArgument* out_values; gint* skipped_args = NULL; gint* out_pos; gint first_out = -1; guint use_return_as_out = 0; guint n_args, n_in_args, n_out_args, i, j; guint in_args_pos, out_args_pos; GIArgInfo* arg_info = NULL; GITypeInfo* type_info = NULL; GITypeTag tag; GIDirection dir; GITransfer transfer; JSValueRef retval_ref; GError* error = 0; gint length_arg_pos = 0; guint64 array_len = 0; gint array_return_value_count = 0; gboolean return_only_one_out = false; info = JSObjectGetPrivate(function); // We just want to check if there IS an object, not actually throw an // exception if we don't get it. if (!this_object || !((object = seed_value_to_object(ctx, this_object, 0)) || (object = seed_pointer_get_pointer(ctx, this_object)))) instance_method = FALSE; n_args = g_callable_info_get_n_args((GICallableInfo*) info); out_pos = g_new0(gint, n_args + 1); in_args = g_new0(GArgument, n_args + 1); out_args = g_new0(GArgument, n_args + 1); out_values = g_new0(GArgument, n_args + 1); n_in_args = n_out_args = 0; caller_allocated = g_new0(gboolean, n_args + 1); // start by pushing the object onto the call stack. if (instance_method) in_args[n_in_args++].v_pointer = object; int out_skipped_args = 0; skipped_args = _process_skipped_arguments(arguments, info, &out_skipped_args); SEED_NOTE(INVOCATION, "Calling seed_object_method_invoked for function %s", g_base_info_get_name(info)); // now loop through all the other args. for (i = 0, j = 0; (i < (n_args)); i++) { if (skipped_args[i]) { SEED_NOTE(INVOCATION, "Skipping parameter %d", i); n_in_args++; j++; continue; } out_pos[i] = -1; arg_info = g_callable_info_get_arg((GICallableInfo*) info, i); dir = g_arg_info_get_direction(arg_info); type_info = g_arg_info_get_type(arg_info); transfer = g_arg_info_get_ownership_transfer(arg_info); is_caller_allocates = FALSE; #if GOBJECT_INTROSPECTION_VERSION > 0x000613 is_caller_allocates = (dir == GI_DIRECTION_OUT) && g_arg_info_is_caller_allocates(arg_info); /* caller allocates only applies to structures but GI has * no way to denote that yet, so we only use caller allocates * if we see a structure */ if (is_caller_allocates) { GITypeTag type_tag = g_type_info_get_tag(type_info); is_caller_allocates = FALSE; if (type_tag == GI_TYPE_TAG_INTERFACE) { GIInfoType info_type; iface_info = g_type_info_get_interface(type_info); g_assert(info != NULL); info_type = g_base_info_get_type(iface_info); if (info_type == GI_INFO_TYPE_STRUCT) is_caller_allocates = TRUE; } } #endif SEED_NOTE(INVOCATION, "Converting arg: %s (%d) of function %s, exception is %p", g_base_info_get_name((GIBaseInfo*) arg_info), i, g_base_info_get_name(info), exception); if (i + 1 > argumentCount + out_skipped_args) { if (dir == GI_DIRECTION_OUT) { GArgument* out_value = &out_values[n_out_args]; out_values[n_out_args].v_pointer = NULL; out_args[n_out_args].v_pointer = out_value; out_pos[i] = n_out_args; if (is_caller_allocates) { gsize size = g_struct_info_get_size((GIStructInfo*) iface_info); out_args[n_out_args].v_pointer = g_malloc0(size); out_values[n_out_args].v_pointer = out_args[n_out_args].v_pointer; caller_allocated[i] = TRUE; } n_out_args++; } else in_args[n_in_args++].v_pointer = 0; } else if (dir == GI_DIRECTION_IN || dir == GI_DIRECTION_INOUT) { if (!g_arg_info_may_be_null(arg_info)) { gboolean is_null = (!arguments[i - j] || JSValueIsNull(ctx, arguments[i - j])); if (!is_null && (g_type_info_get_tag(type_info) == GI_TYPE_TAG_INTERFACE)) { /* see if the pointer is null for struct/unions. */ GIBaseInfo* interface = g_type_info_get_interface( type_info); GIInfoType interface_type = g_base_info_get_type(interface); gboolean arg_is_object = JSValueIsObject(ctx, arguments[i - j]); gboolean is_gvalue = (interface_type == GI_INFO_TYPE_STRUCT) && !g_strcmp0(g_base_info_get_name( (GIBaseInfo*) interface), "Value") && !g_strcmp0(g_base_info_get_namespace( (GIBaseInfo*) interface), "GObject"); gboolean is_struct_or_union = (interface_type == GI_INFO_TYPE_STRUCT || interface_type == GI_INFO_TYPE_UNION); /* this test ignores non-objects being sent where interfaces are expected hopefully our type manipluation code will pick that up. The only exception to this is GObject.GValues which are arrays. */ if (!is_gvalue && is_struct_or_union && arg_is_object && (seed_pointer_get_pointer(ctx, arguments[i - j]) == 0)) { is_null = TRUE; } g_base_info_unref(interface); } if (is_null) { GIBaseInfo* ctr = g_base_info_get_container((GIBaseInfo*) info); // note - ctr does not need unref'ing (see ginfo.c source // for why) // RE-INSTATE THIS CODE LATER.. - when gtk etc. has be // release with fixes // seed_make_exception (ctx, exception, // "ArgumentError", g_warning("ArgumentError - probably due to incorrect gir " "file (which may be fixed upstream)" " argument %d must not be null for" " function: %s%s%s \n", i + 1, ctr ? g_base_info_get_name((GIBaseInfo*) ctr) : "", ctr ? "." : "", g_base_info_get_name((GIBaseInfo*) info)); // goto arg_error; } } guint out_length = 0; if (!seed_value_to_gi_argument_with_out_length( ctx, arguments[i - j], type_info, transfer, &in_args[n_in_args++], &out_length, exception)) { seed_make_exception(ctx, exception, "ArgumentError", "Unable to make argument %d for" " function: %s. \n", i + 1, g_base_info_get_name((GIBaseInfo*) info)); retval_ref = JSValueMakeNull(ctx); goto invoke_return; } // check if what we did we did on an array, // if yes, fill the g_type_info_get_array_length() position with the // size of the array and mark it as already skipped. GITypeTag type_tag = g_type_info_get_tag(type_info); gint array_len_pos = g_type_info_get_array_length(type_info); if (type_tag == GI_TYPE_TAG_ARRAY && g_type_info_get_array_type(type_info) == GI_ARRAY_TYPE_C && array_len_pos >= 0) { skipped_args[array_len_pos] = TRUE; in_args[array_len_pos + 1].v_uint64 = out_length; } if (dir == GI_DIRECTION_INOUT) { GArgument* out_value = &out_values[n_out_args]; out_args[n_out_args++].v_pointer = out_value; out_pos[i] = n_out_args; } } else if (dir == GI_DIRECTION_OUT) { GArgument* out_value = &out_values[n_out_args]; out_values[n_out_args].v_pointer = NULL; out_args[n_out_args].v_pointer = out_value; out_pos[i] = n_out_args; if (is_caller_allocates) { gsize size = g_struct_info_get_size((GIStructInfo*) iface_info); out_args[n_out_args].v_pointer = g_malloc0(size); out_values[n_out_args].v_pointer = out_args[n_out_args].v_pointer; caller_allocated[i] = TRUE; } n_out_args++; first_out = first_out > -1 ? first_out : i; } g_base_info_unref((GIBaseInfo*) type_info); g_base_info_unref((GIBaseInfo*) arg_info); if (iface_info) g_base_info_unref(iface_info); iface_info = NULL; type_info = NULL; arg_info = NULL; } // --- Finished building the args, now call the method / function. SEED_NOTE(INVOCATION, "Invoking method: %s with %d 'in' arguments" " and %d 'out' arguments", g_base_info_get_name(info), n_in_args, n_out_args); if (!g_function_info_invoke((GIFunctionInfo*) info, in_args, n_in_args, out_args, n_out_args, &retval, &error)) { // failed... seed_make_exception_from_gerror(ctx, exception, error); g_error_free(error); retval_ref = JSValueMakeNull(ctx); goto invoke_return; } // -- returned OK.. type_info = g_callable_info_get_return_type((GICallableInfo*) info); tag = g_type_info_get_tag(type_info); // might need to add g_type_info_is_pointer (type_info) check here.. // We force a return array in the following situation: // There's more than one n_out_args OR // There's one out_arg AND tag != GI_TYPE_TAG_VOID // AND, of course, if it's not an INTERFACE. gboolean force_return_array = false; force_return_array = (tag != GI_TYPE_TAG_INTERFACE); if (force_return_array) { if (n_out_args + !!(tag != GI_TYPE_TAG_VOID) > 1) { retval_ref = JSObjectMakeArray(ctx, 0, NULL, NULL); use_return_as_out = 1; } } if (tag == GI_TYPE_TAG_VOID) { // * if we have no out args - returns undefined // * if we have *one* out_arg but no return type, // do nothing here and return the OUT as return later. // * otherwise we return an object, and put the return values into that // along with supporting the old object.value way if (n_out_args < 1) retval_ref = JSValueMakeUndefined(ctx); else if (n_out_args == 1) { return_only_one_out = true; use_return_as_out = 1; } else { retval_ref = JSObjectMake(ctx, NULL, NULL); use_return_as_out = 1; } } else { // not a void return. GIBaseInfo* interface; gboolean sunk = FALSE; // for most returns we just pump it though our type convert calls. // however gobjects are different, if they are not owned by anybody, // then we add a ref so that it can not be destroyed during this // process. // this ref is removed after we have converted it to a JSObject. if (tag == GI_TYPE_TAG_INTERFACE) { GIInfoType interface_type; interface = g_type_info_get_interface(type_info); interface_type = g_base_info_get_type(interface); g_base_info_unref(interface); if (interface_type == GI_INFO_TYPE_OBJECT || interface_type == GI_INFO_TYPE_INTERFACE) { if (G_IS_OBJECT(retval.v_pointer)) { sunk = G_IS_INITIALLY_UNOWNED(G_OBJECT(retval.v_pointer)); if (sunk) g_object_ref_sink(G_OBJECT(retval.v_pointer)); } } } length_arg_pos = g_type_info_get_array_length(type_info); SEED_NOTE(INVOCATION, "length_arg_pos=%d\n", length_arg_pos); if (length_arg_pos < 0) { array_len = 0; } else { array_len = (&out_values[out_pos[length_arg_pos]])->v_uint32; } SEED_NOTE(INVOCATION, "array_len=%" G_GUINT64_FORMAT "\n", array_len); JSValueRef jsout_val = seed_value_from_gi_argument_full(ctx, &retval, type_info, exception, array_len, tag); if (use_return_as_out && force_return_array) { _add_jsvalue_in_array(ctx, (JSObjectRef) retval_ref, array_return_value_count++, jsout_val); } else retval_ref = jsout_val; if (sunk) g_object_unref(G_OBJECT(retval.v_pointer)); else seed_gi_release_arg(g_callable_info_get_caller_owns( (GICallableInfo*) info), type_info, &retval); } if (type_info) g_base_info_unref((GIBaseInfo*) type_info); type_info = NULL; // finished with return.. now go thorugh the args and handle any out/inout // etc.. in_args_pos = out_args_pos = 0; for (i = 0; (i < n_args); i++) { JSValueRef jsout_val; arg_info = g_callable_info_get_arg((GICallableInfo*) info, i); dir = g_arg_info_get_direction(arg_info); type_info = g_arg_info_get_type(arg_info); // since we succesfully called, we can presume that if (dir == GI_DIRECTION_IN || dir == GI_DIRECTION_INOUT) { seed_gi_release_in_arg( g_arg_info_get_ownership_transfer(arg_info), type_info, &in_args[in_args_pos + (instance_method ? 1 : 0)]); in_args_pos++; g_base_info_unref((GIBaseInfo*) type_info); g_base_info_unref((GIBaseInfo*) arg_info); type_info = NULL; arg_info = NULL; continue; } // we are now only dealing with OUT arguments. // if the type_info is an array with a length position, we // need to send that as well, so it can be used to build the seed value. { length_arg_pos = g_type_info_get_array_length(type_info); array_len = 0; if (length_arg_pos > -1) { GIArgInfo* array_arg_info; GITypeInfo* array_type_info; GArgument* array_len_arg; g_assert(out_pos[length_arg_pos] > -1); array_arg_info = g_callable_info_get_arg((GICallableInfo*) info, length_arg_pos); array_type_info = g_arg_info_get_type(array_arg_info); array_len_arg = &out_values[out_pos[length_arg_pos]]; array_len = 0; switch (g_type_info_get_tag(array_type_info)) { // not sure if the non-unsigned versions are need as length // should not be -ve.. case GI_TYPE_TAG_INT8: array_len = (guint64) array_len_arg->v_int8; break; case GI_TYPE_TAG_UINT8: array_len = (guint64) array_len_arg->v_uint8; break; case GI_TYPE_TAG_INT16: array_len = (guint64) array_len_arg->v_int16; break; case GI_TYPE_TAG_UINT16: array_len = (guint64) array_len_arg->v_uint16; break; case GI_TYPE_TAG_INT32: array_len = (guint64) array_len_arg->v_int32; break; case GI_TYPE_TAG_UINT32: array_len = (guint64) array_len_arg->v_uint32; break; case GI_TYPE_TAG_INT64: array_len = (guint64) array_len_arg->v_int64; break; case GI_TYPE_TAG_UINT64: array_len = (guint64) array_len_arg->v_uint64; break; default: g_assert(1 == 0); break; } // this may work, but the above should be more accurate.. // array_len = (&out_values[ out_pos[length_arg_pos] // ])->v_uint32; SEED_NOTE(INVOCATION, "Getting length from OUTPOS=%d, ORIGPOS=%d : " "result = %" G_GUINT64_FORMAT, out_pos[length_arg_pos], length_arg_pos, array_len); // free stuff. g_base_info_unref((GIBaseInfo*) array_type_info); g_base_info_unref((GIBaseInfo*) array_arg_info); } jsout_val = seed_value_from_gi_argument_full( ctx, &out_values[out_args_pos], type_info, exception, array_len, g_type_info_get_tag(type_info)); } /* caller allocates only applies to structures but GI has * no way to denote that yet, so we only use caller allocates * if we see a structure */ if (caller_allocated[i]) { // this is the old python code.. // if we are going to do this, the caching the iface_info at the top // would be a better idea. // if (g_registered_type_info_get_g_type ( (GIRegisteredTypeInfo *) // iface_info) == G_TYPE_VALUE) // g_value_unset ( (GValue *) state->args[i]); // clear the caller allocated flag so it's not free'd at the end.. caller_allocated[i] = FALSE; } // old ? depreciated ? way to handle out args -> set 'value' on object // that was send through. out_args_pos++; if ((i < argumentCount) && !JSValueIsNull(ctx, arguments[i]) && JSValueIsObject(ctx, arguments[i])) { seed_object_set_property(ctx, (JSObjectRef) arguments[i], "value", jsout_val); } // if we add it to the return argument and/or the first out arguement if (use_return_as_out) { if (return_only_one_out) { retval_ref = jsout_val; } else if (force_return_array) { _add_jsvalue_in_array(ctx, (JSObjectRef) retval_ref, array_return_value_count++, jsout_val); } else { seed_object_set_property(ctx, (JSObjectRef) retval_ref, g_base_info_get_name( (GIBaseInfo*) arg_info), jsout_val); } } if ((first_out > -1) && !JSValueIsNull(ctx, arguments[first_out]) && JSValueIsObject(ctx, arguments[first_out])) { seed_object_set_property(ctx, (JSObjectRef) arguments[first_out], g_base_info_get_name( (GIBaseInfo*) arg_info), jsout_val); } g_base_info_unref((GIBaseInfo*) arg_info); g_base_info_unref((GIBaseInfo*) type_info); type_info = NULL; arg_info = NULL; } invoke_return: SEED_NOTE(INVOCATION, "END seed_object_method_invoked for function %s", g_base_info_get_name(info)); // clean up everything.. for (i = 0; (i < (n_args)); i++) if (caller_allocated[i]) g_free(out_args[out_pos[i]].v_pointer); g_free(caller_allocated); if (type_info) g_base_info_unref((GIBaseInfo*) type_info); if (arg_info) g_base_info_unref((GIBaseInfo*) arg_info); if (iface_info) g_base_info_unref(iface_info); g_free(in_args); g_free(out_args); g_free(out_pos); g_free(out_values); return retval_ref; } static JSObjectRef seed_gobject_named_constructor_invoked(JSContextRef ctx, JSObjectRef constructor, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { return (JSObjectRef) seed_gobject_method_invoked(ctx, constructor, NULL, argumentCount, arguments, exception); } void seed_gobject_define_property_from_function_info(JSContextRef ctx, GIFunctionInfo* info, JSObjectRef object, gboolean instance) { GIFunctionInfoFlags flags; JSObjectRef method_ref; const gchar* name; // if (g_base_info_is_deprecated ((GIBaseInfo *) info)) // g_printf("Not defining deprecated symbol: %s \n", // g_base_info_get_name((GIBaseInfo *)info)); flags = g_function_info_get_flags(info); if (instance && (flags & GI_FUNCTION_IS_CONSTRUCTOR)) { return; } method_ref = JSObjectMake(ctx, gobject_method_class, g_base_info_ref((GIBaseInfo*) info)); JSObjectSetPrototype(ctx, method_ref, function_proto); name = g_base_info_get_name((GIBaseInfo*) info); if (!g_strcmp0(name, "new")) { // To be compatible with gjs, we need to have new as function, too. seed_object_set_property(ctx, object, name, method_ref); name = "c_new"; } seed_object_set_property(ctx, object, name, method_ref); seed_object_set_property (ctx, method_ref, "info", seed_make_struct (ctx, g_base_info_ref ((GIBaseInfo *) info), base_info_info)); } static void seed_gobject_add_methods_for_interfaces(JSContextRef ctx, GIObjectInfo* oinfo, JSObjectRef object) { GIInterfaceInfo* interface; GIFunctionInfo* function; gint n_interfaces, i, n_functions, k; n_interfaces = g_object_info_get_n_interfaces(oinfo); for (i = 0; i < n_interfaces; i++) { interface = g_object_info_get_interface(oinfo, i); n_functions = g_interface_info_get_n_methods(interface); for (k = 0; k < n_functions; k++) { function = g_interface_info_get_method(interface, k); seed_gobject_define_property_from_function_info(ctx, function, object, TRUE); } g_base_info_unref((GIBaseInfo*) interface); } } static void seed_gobject_add_methods_for_type(JSContextRef ctx, GIObjectInfo* oinfo, JSObjectRef object) { gint n_methods; gint i; GIFunctionInfo* info; n_methods = g_object_info_get_n_methods(oinfo); for (i = 0; i < n_methods; i++) { info = g_object_info_get_method(oinfo, i); seed_gobject_define_property_from_function_info(ctx, info, object, TRUE); g_base_info_unref((GIBaseInfo*) info); } } JSClassRef seed_gobject_get_class_for_gtype(JSContextRef ctx, GType type) { JSClassDefinition def; GType parent; JSClassRef ref; JSClassRef parent_class = 0; GIBaseInfo* info; JSObjectRef prototype_obj; JSObjectRef parent_prototype; if ((ref = g_type_get_qdata(type, qname)) != NULL) { return ref; } info = g_irepository_find_by_gtype(g_irepository_get_default(), type); memset(&def, 0, sizeof(JSClassDefinition)); def.className = g_type_name(type); if ((parent = g_type_parent(type))) parent_class = seed_gobject_get_class_for_gtype(ctx, parent); def.parentClass = parent_class; def.attributes = kJSClassAttributeNoAutomaticPrototype; prototype_obj = JSObjectMake(ctx, 0, 0); if (parent) { parent_prototype = seed_gobject_get_prototype_for_gtype(parent); if (parent_prototype) JSObjectSetPrototype(ctx, prototype_obj, parent_prototype); } ref = JSClassCreate(&def); JSClassRetain(ref); JSValueProtect(ctx, prototype_obj); g_type_set_qdata(type, qname, ref); g_type_set_qdata(type, qprototype, prototype_obj); if (info && (g_base_info_get_type(info) == GI_INFO_TYPE_OBJECT)) { seed_gobject_add_methods_for_interfaces(ctx, (GIObjectInfo*) info, prototype_obj); seed_gobject_add_methods_for_type(ctx, (GIObjectInfo*) info, prototype_obj); g_base_info_unref(info); } else { GType* interfaces; GIFunctionInfo* function; GIBaseInfo* interface; gint n_functions, k; guint i, n; interfaces = g_type_interfaces(type, &n); for (i = 0; i < n; i++) { interface = g_irepository_find_by_gtype(0, interfaces[i]); if (!interface) break; n_functions = g_interface_info_get_n_methods((GIInterfaceInfo*) interface); for (k = 0; k < n_functions; k++) { function = g_interface_info_get_method((GIInterfaceInfo*) interface, k); seed_gobject_define_property_from_function_info(ctx, function, prototype_obj, TRUE); } } } return ref; } JSObjectRef seed_gobject_get_prototype_for_gtype(GType type) { JSObjectRef prototype = 0; while (type && !prototype) { prototype = g_type_get_qdata(type, qprototype); type = g_type_parent(type); } return prototype; } static void seed_gobject_finalize(JSObjectRef object) { GObject* gobject; JSObjectRef js_ref; gobject = (GObject*) JSObjectGetPrivate((JSObjectRef) object); if (!gobject) { SEED_NOTE(FINALIZATION, "Attempting to finalize already destroyed object."); return; } SEED_NOTE(FINALIZATION, "%s at %p (%d refs)", g_type_name(G_OBJECT_TYPE(gobject)), gobject, gobject->ref_count); js_ref = g_object_get_qdata(gobject, js_ref_quark); if (js_ref) { /* Steal the qdata here as otherwise we will call * JSValueUnprotect() from the destroy notify of * the qdata, which is not allowed to be called * from a finalizer! */ g_object_steal_qdata(gobject, js_ref_quark); g_object_remove_toggle_ref(gobject, seed_toggle_ref, js_ref); } else { g_object_run_dispose(gobject); } } static JSValueRef seed_gobject_get_property(JSContextRef context, JSObjectRef object, JSStringRef property_name, JSValueRef* exception) { GParamSpec* spec; GObject* b; GValue gval = { 0 }; char* cproperty_name; gint length; JSValueRef ret; guint i; gsize len; b = seed_value_to_object(context, (JSValueRef) object, exception); if (!b) return 0; length = JSStringGetMaximumUTF8CStringSize(property_name); cproperty_name = g_alloca(length * sizeof(gchar)); JSStringGetUTF8CString(property_name, cproperty_name, length); spec = g_object_class_find_property(G_OBJECT_GET_CLASS(b), cproperty_name); if (!spec) { len = strlen(cproperty_name) - 1; for (i = 0; i < len; i++) { if (cproperty_name[i] == '_') cproperty_name[i] = '-'; } spec = g_object_class_find_property(G_OBJECT_GET_CLASS(b), cproperty_name); if (spec) goto found; else { GIFieldInfo* field = NULL; GIBaseInfo* info = (GIBaseInfo*) g_irepository_find_by_gtype(0, G_OBJECT_TYPE(b)); gint n; const gchar* name; for (i = 0; i < len; i++) { if (cproperty_name[i] == '-') cproperty_name[i] = '_'; } if (!info) { return NULL; } n = g_object_info_get_n_fields((GIObjectInfo*) info); for (i = 0; i < n; i++) { field = g_object_info_get_field((GIObjectInfo*) info, i); name = g_base_info_get_name((GIBaseInfo*) field); if (!g_strcmp0(name, cproperty_name)) goto found_field; else { g_base_info_unref((GIBaseInfo*) field); field = 0; } } found_field: if (field) { ret = seed_field_get_value(context, b, field, exception); g_base_info_unref((GIBaseInfo*) info); return ret; } g_base_info_unref((GIBaseInfo*) info); } return NULL; } found: g_value_init(&gval, spec->value_type); g_object_get_property(b, cproperty_name, &gval); ret = seed_value_from_gvalue(context, &gval, exception); g_value_unset(&gval); return (JSValueRef) ret; } static bool seed_gobject_set_property(JSContextRef context, JSObjectRef object, JSStringRef property_name, JSValueRef value, JSValueRef* exception) { GParamSpec* spec = 0; GObject* obj; GValue gval = { 0 }; GType type; gchar* cproperty_name; gsize length; gsize i, len; if (pthread_getspecific(seed_next_gobject_wrapper_key) || JSValueIsNull(context, value)) return 0; obj = seed_value_to_object(context, object, 0); length = JSStringGetMaximumUTF8CStringSize(property_name); cproperty_name = g_alloca(length * sizeof(gchar)); JSStringGetUTF8CString(property_name, cproperty_name, length); spec = g_object_class_find_property(G_OBJECT_GET_CLASS(obj), cproperty_name); if (!spec) { len = strlen(cproperty_name); for (i = 0; i < len; i++) { if (cproperty_name[i] == '_') cproperty_name[i] = '-'; } spec = g_object_class_find_property(G_OBJECT_GET_CLASS(obj), cproperty_name); if (!spec) { return FALSE; } } if (g_type_is_a(spec->value_type, G_TYPE_ENUM)) type = G_TYPE_LONG; else type = spec->value_type; seed_value_to_gvalue(context, value, type, &gval, exception); if (*exception) { return FALSE; } if (glib_message) { g_free(glib_message); glib_message = 0; } g_object_set_property(obj, cproperty_name, &gval); if (glib_message != 0) { seed_make_exception(context, exception, "PropertyError", glib_message, NULL); return FALSE; } g_value_unset(&gval); return TRUE; } static JSValueRef seed_gobject_convert_to_type(JSContextRef ctx, JSObjectRef object, JSType type, JSValueRef* exception) { GObject* obj; gchar* as_string; if (type == kJSTypeString) { JSValueRef ret; obj = (GObject*) JSObjectGetPrivate(object); as_string = g_strdup_printf("[gobject %s %p]", G_OBJECT_TYPE_NAME(obj), obj); ret = seed_value_from_string(ctx, as_string, exception); g_free(as_string); return ret; } return FALSE; } static JSValueRef seed_gobject_constructor_convert_to_type(JSContextRef ctx, JSObjectRef object, JSType type, JSValueRef* exception) { GType gtype; gchar* as_string; if (type == kJSTypeString) { JSValueRef ret; gtype = (GType) JSObjectGetPrivate(object); as_string = g_strdup_printf("[gobject_constructor %s]", g_type_name(gtype)); ret = seed_value_from_string(ctx, as_string, exception); g_free(as_string); return ret; } return FALSE; } JSStaticFunction gobject_static_funcs[] = { { "__debug_ref_count", seed_gobject_ref_count, 0 }, { "__property_type", seed_gobject_property_type, 0 }, { "connect", seed_gobject_signal_connect_by_name, 0 }, { 0, 0, 0 } }; JSClassDefinition gobject_def = { 0, /* Version, always 0 */ kJSClassAttributeNoAutomaticPrototype, /* JSClassAttributes */ "gobject", /* Class Name */ NULL, /* Parent Class */ NULL, /* Static Values */ gobject_static_funcs, /* Static Functions */ NULL, seed_gobject_finalize, /* Finalize */ NULL, /* Has Property */ seed_gobject_get_property, /* Get Property */ seed_gobject_set_property, /* Set Property */ NULL, /* Delete Property */ NULL, /* Get Property Names */ NULL, /* Call As Function */ NULL, /* Call As Constructor */ NULL, /* Has Instance */ seed_gobject_convert_to_type /* Convert To Type */ }; JSClassDefinition gobject_method_def = { 0, /* Version, always 0 */ 0, "gobject_method", /* Class Name */ NULL, /* Parent Class */ NULL, /* Static Values */ NULL, /* Static Functions */ NULL, seed_gobject_method_finalize, /* Finalize */ NULL, /* Has Property */ NULL, /* Get Property */ NULL, /* Set Property */ NULL, /* Delete Property */ NULL, /* Get Property Names */ seed_gobject_method_invoked, /* Call As Function */ NULL, /* Call As Constructor */ NULL, /* Has Instance */ NULL /* Convert To Type */ }; JSClassDefinition gobject_init_method_def = { 0, /* Version, always 0 */ 0, "init_method", /* Class Name */ NULL, /* Parent Class */ NULL, /* Static Values */ NULL, /* Static Functions */ NULL, seed_gobject_method_finalize, /* Finalize */ NULL, /* Has Property */ NULL, /* Get Property */ NULL, /* Set Property */ NULL, /* Delete Property */ NULL, /* Get Property Names */ seed_gobject_init_method_invoked, /* Call As Function */ NULL, /* Call As Constructor */ NULL, /* Has Instance */ NULL /* Convert To Type */ }; JSClassDefinition seed_callback_def = { 0, /* Version, always 0 */ 0, "seed_callback", /* Class Name */ NULL, /* Parent Class */ NULL, /* Static Values */ NULL, /* Static Functions */ NULL, NULL, /* Finalize */ NULL, /* Has Property */ NULL, /* Get Property */ NULL, /* Set Property */ NULL, /* Delete Property */ NULL, /* Get Property Names */ NULL, /* Call As Function */ NULL, /* Call As Constructor */ NULL, /* Has Instance */ NULL /* Convert To Type */ }; JSClassDefinition gobject_constructor_def = { 0, /* Version, always 0 */ 0, "gobject_constructor", /* Class Name */ NULL, /* Parent Class */ NULL, /* Static Values */ NULL, /* Static Functions */ NULL, NULL, /* Finalize */ NULL, /* Has Property */ NULL, /* Get Property */ NULL, /* Set Property */ NULL, /* Delete Property */ NULL, /* Get Property Names */ NULL, /* Call As Function */ seed_gobject_constructor_invoked, /* Call As Constructor */ seed_gobject_has_instance, /* Has Instance */ seed_gobject_constructor_convert_to_type }; JSClassDefinition gobject_named_constructor_def = { 0, /* Version, always 0 */ 0, "gobject_named_constructor", /* Class Name */ NULL, /* Parent Class */ NULL, /* Static Values */ NULL, /* Static Functions */ NULL, NULL, /* Finalize */ NULL, /* Has Property */ NULL, /* Get Property */ NULL, /* Set Property */ NULL, /* Delete Property */ NULL, /* Get Property Names */ // To be compatible with gjs you need to be able to call named // constructors without the new in front seed_gobject_method_invoked, /* Call As Function */ seed_gobject_named_constructor_invoked, /* Call As Constructor */ seed_gobject_has_instance, /* Has Instance */ seed_gobject_constructor_convert_to_type }; JSClassDefinition struct_constructor_def = { 0, /* Version, always 0 */ 0, "struct_constructor", /* Class Name */ NULL, /* Parent Class */ NULL, /* Static Values */ NULL, /* Static Functions */ NULL, NULL, /* Finalize */ NULL, /* Has Property */ NULL, /* Get Property */ NULL, /* Set Property */ NULL, /* Delete Property */ NULL, /* Get Property Names */ NULL, /* Call As Function */ seed_struct_constructor_invoked, /* Call As Constructor */ NULL, /* Has Instance */ NULL /* Convert To Type */ }; /** * seed_create_function: * @ctx: A valid #SeedContext * @name: The name of the function (used in exceptions). * @func: A #SeedFunctionCallback to implement the function. * @obj: The #SeedObject on which to put the function. * * Creates a JavaScript object representing a first-class function; when * the function is called from JavaScript, @func will be called. Places * the created function as the property @name on @obj. * */ void seed_create_function(JSContextRef ctx, gchar* name, gpointer func, JSObjectRef obj) { JSObjectRef oref; oref = JSObjectMakeFunctionWithCallback(ctx, NULL, func); seed_object_set_property(ctx, obj, name, oref); } void seed_repl_expose(JSContextRef ctx, ...) { va_list argp; void* expose; JSObjectRef arrayObj; guint i = 0; JSStringRef script; JSObjectRef seed = (JSObjectRef) seed_object_get_property(ctx, JSContextGetGlobalObject(ctx), "Seed"); va_start(argp, ctx); arrayObj = JSObjectMake(ctx, NULL, NULL); g_print("Seed Debug REPL\n\nExposing:\n"); while ((expose = va_arg(argp, void*) )) { g_print(" Seed.debug_argv[%u] = %p\n", i, expose); JSObjectSetPropertyAtIndex(ctx, arrayObj, i++, expose, NULL); } g_print("\n"); seed_object_set_property(ctx, seed, "debug_argv", arrayObj); script = JSStringCreateWithUTF8CString( "readline = imports.readline;" "while(1) { try { print(eval(" "readline.readline(\"> \"))); } catch(e) {" "print(e.name + \" \" + e.message);}}"); JSEvaluateScript(ctx, script, NULL, NULL, 0, NULL); JSStringRelease(script); va_end(argp); } static void seed_log_handler(const gchar* domain, GLogLevelFlags log_level, const gchar* message, gpointer user_data) { if (glib_message) g_free(glib_message); glib_message = g_strdup(message); } #ifdef SEED_ENABLE_DEBUG static gboolean seed_arg_debug_cb(const char* key, const char* value, gpointer user_data) { seed_debug_flags |= g_parse_debug_string(value, seed_debug_keys, G_N_ELEMENTS(seed_debug_keys)); return TRUE; } static gboolean seed_arg_no_debug_cb(const char* key, const char* value, gpointer user_data) { seed_debug_flags &= ~g_parse_debug_string(value, seed_debug_keys, G_N_ELEMENTS(seed_debug_keys)); return TRUE; } #endif /* SEED_ENABLE_DEBUG */ GOptionGroup* seed_get_option_group(SeedEngine* eng) { GOptionGroup* group; GOptionEntry seed_args[] = { #ifdef SEED_ENABLE_DEBUG { "seed-debug", 0, 0, G_OPTION_ARG_CALLBACK, seed_arg_debug_cb, "Seed debugging messages to show. Comma separated list of: all, " "misc, " "finalization, initialization, construction, invocation, signal, " "structs, gtype.", "FLAGS" }, { "seed-no-debug", 0, 0, G_OPTION_ARG_CALLBACK, seed_arg_no_debug_cb, "Disable Seed debugging", "FLAGS" }, #endif /* SEED_ENABLE_DEBUG */ { "seed-version", 0, 0, G_OPTION_ARG_NONE, &seed_arg_print_version, "Print libseed version", 0 }, { "program-name", 0, 0, G_OPTION_ARG_STRING, &eng->program_name, "Program Name", 0 }, { NULL, }, }; group = g_option_group_new("seed", "Seed Options", "Show Seed Options", NULL, NULL); g_option_group_add_entries(group, seed_args); return group; } static gboolean seed_parse_args(SeedEngine* eng, int* argc, char*** argv) { GOptionContext* option_context; GOptionGroup* seed_group; GError* error = NULL; gboolean ret = TRUE; option_context = g_option_context_new(NULL); g_option_context_set_ignore_unknown_options(option_context, TRUE); g_option_context_set_help_enabled(option_context, TRUE); /* Initiate any command line options from the backend */ seed_group = seed_get_option_group(eng); g_option_context_add_group(option_context, seed_group); if (!g_option_context_parse(option_context, argc, argv, &error)) { if (error) { g_warning("%s", error->message); g_error_free(error); } ret = FALSE; } if (!eng->program_name) eng->program_name = g_strdup(*argv[0]); g_option_context_free(option_context); return ret; } void seed_engine_destroy(SeedEngine* eng) { JSValueUnprotect(eng->context, eng->global); JSGlobalContextRelease(eng->context); JSContextGroupRelease(eng->group); g_free(eng); } /** * seed_init_constrained_with_context_and_group: * @argc: A reference to the number of arguments remaining to parse. * @argv: A reference to an array of string arguments remaining to parse. * @context A reference to an existing JavascriptCore context * @group: A #SeedContextGroup within which to create the initial context. * * Initializes an empty new #SeedEngine. The Javascript context of this engine * is * *not* filled with any builtins functions and the import system. * * The javascript code executed with this engine can't import arbitrary * GObject introspected librairies. * * Use this when control over what is exposed in the Javascript context is * required, * for security concerns for example. * GObject instances can be selectively exposed by calling * @seed_engine_expose_gobject. * Namespaces can be selectively exposed by calling * * This function should only be called once within a single Seed application. * * Return value: The newly created and initialized #SeedEngine. * */ SeedEngine* seed_init_constrained_with_context_and_group(gint* argc, gchar*** argv, JSGlobalContextRef context, JSContextGroupRef group) { #if !GLIB_CHECK_VERSION(2, 36, 0) g_type_init(); #endif g_log_set_handler("GLib-GObject", G_LOG_LEVEL_WARNING, seed_log_handler, 0); eng = (SeedEngine*) g_malloc(sizeof(SeedEngine)); if ((argc != 0) && seed_parse_args(eng, argc, argv) == FALSE) { SEED_NOTE(MISC, "failed to parse arguments."); return FALSE; } if (seed_arg_print_version) { g_print("%s\n", "Seed " VERSION); exit(EXIT_SUCCESS); } qname = g_quark_from_static_string("js-type"); qprototype = g_quark_from_static_string("js-prototype"); js_ref_quark = g_quark_from_static_string("js-ref"); pthread_key_create(&seed_next_gobject_wrapper_key, NULL); context_group = group; eng->context = context; eng->global = JSContextGetGlobalObject(eng->context); eng->group = context_group; eng->search_path = NULL; eng->program_name = NULL; eng->importer_initialized = FALSE; function_proto = (JSObjectRef) seed_simple_evaluate(eng->context, "Function.prototype", NULL); gobject_class = JSClassCreate(&gobject_def); JSClassRetain(gobject_class); gobject_method_class = JSClassCreate(&gobject_method_def); JSClassRetain(gobject_method_class); gobject_constructor_class = JSClassCreate(&gobject_constructor_def); JSClassRetain(gobject_constructor_class); gobject_named_constructor_class = JSClassCreate(&gobject_named_constructor_def); JSClassRetain(gobject_named_constructor_class); gobject_signal_class = JSClassCreate(seed_get_signal_class()); JSClassRetain(gobject_signal_class); seed_callback_class = JSClassCreate(&seed_callback_def); JSClassRetain(seed_callback_class); seed_struct_constructor_class = JSClassCreate(&struct_constructor_def); JSClassRetain(seed_struct_constructor_class); gobject_init_method_class = JSClassCreate(&gobject_init_method_def); JSClassRetain(gobject_init_method_class); g_type_set_qdata(G_TYPE_OBJECT, qname, gobject_class); seed_obj_ref = JSObjectMake(eng->context, NULL, NULL); seed_object_set_property(eng->context, eng->global, "Seed", seed_obj_ref); JSValueProtect(eng->context, seed_obj_ref); window_obj_ref = JSObjectMake(eng->context, NULL, NULL); seed_object_set_property(eng->context, eng->global, "window", window_obj_ref); JSValueProtect(eng->context, window_obj_ref); g_irepository_require(g_irepository_get_default(), "GObject", NULL, 0, 0); g_irepository_require(g_irepository_get_default(), "GIRepository", NULL, 0, 0); seed_structs_init(); seed_closures_init(); return eng; } /** * seed_init_with_context_and_group: * @argc: A reference to the number of arguments remaining to parse. * @argv: A reference to an array of string arguments remaining to parse. * @context A reference to an existing JavascriptCore context * @group: A #SeedContextGroup within which to create the initial context. * * Initializes a new #SeedEngine using an existing JavascriptCore context. * This involves initializing GLib, adding @instance to @group, adding the * default globals to the provided context, and initializing various internal * parts of Seed. * * This function should only be called once within a single Seed application. * * Return value: The newly created and initialized #SeedEngine. * */ SeedEngine* seed_init_with_context_and_group(gint* argc, gchar*** argv, JSGlobalContextRef context, JSContextGroupRef group) { eng = seed_init_constrained_with_context_and_group(argc, argv, context, group); seed_init_builtins(eng, argc, argv); seed_initialize_importer(eng->context, eng->global); seed_gtype_init(eng); defaults_script = JSStringCreateWithUTF8CString( "Seed.include(\"/org/seed/extensions/Seed.js\");"); JSEvaluateScript(eng->context, defaults_script, NULL, NULL, 0, NULL); base_info_info = g_irepository_find_by_name(0, "GIRepository", "BaseInfo"); return eng; } /** * seed_init_with_context_group: * @argc: A reference to the number of arguments remaining to parse. * @argv: A reference to an array of string arguments remaining to parse. * @group: A #SeedContextGroup within which to create the initial context. * * Initializes a new #SeedEngine. This involves initializing GLib, creating * an initial context (in #group) with all of the default globals, and * initializing various internal parts of Seed. * * This function should only be called once within a single Seed application. * * Return value: The newly created and initialized #SeedEngine. * */ SeedEngine* seed_init_with_context_group(gint* argc, gchar*** argv, JSContextGroupRef group) { return seed_init_with_context_and_group( argc, argv, JSGlobalContextCreateInGroup(group, NULL), group); } /** * seed_init: * @argc: A reference to the number of arguments remaining to parse. * @argv: A reference to an array of string arguments remaining to parse. * * Initializes a new #SeedEngine. This involves initializing GLib, creating * an initial context with all of the default globals, and initializing * various internal parts of Seed. * * This function should only be called once within a single Seed application. * * Return value: The newly created and initialized #SeedEngine. * */ SeedEngine* seed_init(gint* argc, gchar*** argv) { context_group = JSContextGroupCreate(); return seed_init_with_context_group(argc, argv, context_group); } /** * seed_init_with_context: * @argc: A reference to the number of arguments remaining to parse. * @argv: A reference to an array of string arguments remaining to parse. * @context A reference to an existing JavascriptCore context * Initializes a new #SeedEngine using an existing JavascriptCore context. * This involves initializing GLib, adding the default globals to the provided * @context and initializing various internal parts of Seed. * * This function should only be called once within a single Seed application. * * Return value: The newly created and initialized #SeedEngine. * */ SeedEngine* seed_init_with_context(gint* argc, gchar*** argv, JSGlobalContextRef context) { context_group = JSContextGetGroup(context); return seed_init_with_context_and_group(argc, argv, context, context_group); } /** * seed_init_constrained: * @argc: A reference to the number of arguments remaining to parse. * @argv: A reference to an array of string arguments remaining to parse. * * Initializes an empty new #SeedEngine. The Javascript context of this engine * is * *not* filled with any builtins functions and the import system. * * The javascript code executed with this engine can't import arbitrary * GObject introspected librairies. * * Use this when control over what is exposed in the Javascript context is * required, * for security concerns for example. * GObject instances can be selectively exposed by calling * @seed_engine_expose_gobject. * Namespaces can be selectively exposed by calling * * This function should only be called once within a single Seed application. * * Return value: The newly created and initialized #SeedEngine. * */ SeedEngine* seed_init_constrained(gint* argc, gchar*** argv) { context_group = JSContextGroupCreate(); return seed_init_constrained_with_context_and_group( argc, argv, JSGlobalContextCreateInGroup(context_group, NULL), context_group); } /* * seed_engine_initialize_importer: * @engine: A #SeedEngine created with seed_init_constrained() or * seed_init_constrained_with_context_and_group(). * * Initializes the importer for this engine, if it was not done before, * otherwise silently returns. */ void seed_engine_initialize_importer(SeedEngine *engine) { if (!engine->importer_initialized) seed_initialize_importer(eng->context, eng->global); engine->importer_initialized = TRUE; } /* * seed_engine_expose_gobject: * @engine: * @name: The name of the global javascript variable pointing to @object * @object: The #GObject instance that will be exposed in the the javascript * context * @gir_namespace: The Introspection namespace containing the type of the * provided * object. * * Expose a GObject instance to the global Javascript context and makes it * accessible * under the provided @js_name * * return: the SeedValue representing @object, NULL in case of error */ JSValueRef seed_engine_expose_gobject(SeedEngine* engine, gchar* js_name, GObject* object, gchar* gir_namespace, JSValueRef* exception) { GError* error = NULL; g_assert(engine != NULL && gir_namespace != NULL && js_name != NULL); GITypelib* type_lib = g_irepository_require(g_irepository_get_default(), gir_namespace, NULL, 0, &error); if (type_lib == NULL) { seed_make_exception_from_gerror(engine->context, exception, error); g_error_free(error); return NULL; } JSValueRef obj_js_value = seed_value_from_object(engine->context, G_OBJECT(object), exception); g_return_val_if_fail(obj_js_value != NULL, NULL); g_return_val_if_fail(engine->global != NULL, NULL); gboolean ok = seed_object_set_property(engine->context, engine->global, js_name, obj_js_value); g_return_val_if_fail(ok == TRUE, NULL); return obj_js_value; } /* * seed_engine_expose_namespace: * @engine: * @namespace: Name of the GIR Namespace that should be exposed in the JS * context. * * Expose a GIR namespace in the global Javascript context and makes it * accessible * under a variable named after the namespace (ex: the namespace 'Notify' is * held * by the 'Notify' javascript variable. * * return: the SeedValue representing @namespace in the javascript context, * NULL in case of error */ JSValueRef seed_engine_expose_namespace(SeedEngine* engine, gchar* namespace_name, JSValueRef* exception) { g_assert(engine != NULL && namespace_name != NULL); JSValueRef namespace = seed_gi_importer_do_namespace(engine->context, namespace_name, exception); g_return_val_if_fail(namespace != NULL, NULL); gboolean ok = seed_object_set_property(engine->context, engine->global, namespace_name, namespace); g_return_val_if_fail(ok == TRUE, FALSE); return namespace; } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/libseed/seed-engine.h000066400000000000000000000057511303774616400226010ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #ifndef _SEED_ENGINE_H #define _SEED_ENGINE_H #include "seed-private.h" extern JSClassRef gobject_class; extern JSClassRef gobject_method_class; extern JSClassRef gobject_constructor_class; extern JSClassRef gobject_named_constructor_class; extern JSClassRef seed_struct_constructor_class; extern JSClassRef gobject_init_method_class; extern pthread_key_t seed_next_gobject_wrapper_key; extern JSClassRef seed_callback_class; extern SeedEngine* eng; extern JSObjectRef seed_obj_ref; extern JSContextGroupRef context_group; extern JSStringRef defaults_script; typedef struct _SeedScript { JSStringRef script; JSValueRef exception; JSStringRef source_url; gint line_number; } SeedScript; JSObjectRef seed_gobject_get_prototype_for_gtype(GType type); JSClassRef seed_gobject_get_class_for_gtype(JSContextRef ctx, GType type); void seed_gobject_define_property_from_function_info(JSContextRef ctx, GIFunctionInfo* info, JSObjectRef object, gboolean instance); void seed_create_function(JSContextRef ctx, gchar* name, gpointer func, JSObjectRef obj); void seed_repl_expose(JSContextRef ctx, ...); typedef JSObjectRef (*SeedModuleInitCallback)(SeedEngine* eng); void seed_prepare_global_context(JSContextRef ctx); SeedScript* seed_make_script(JSContextRef ctx, const gchar* js, const gchar* source_url, gint line_number); SeedScript* seed_script_new_from_file(JSContextRef ctx, gchar* file); JSValueRef seed_script_exception(SeedScript* s); JSValueRef seed_evaluate(JSContextRef ctx, SeedScript* script, JSObjectRef this); void seed_script_destroy(SeedScript* s); JSValueRef seed_simple_evaluate(JSContextRef ctx, const gchar* script, JSValueRef* exception); GOptionGroup* seed_get_option_group(SeedEngine* engine); #endif seed-webkit2-4.0.0+20161014+6c77960+dfsg1/libseed/seed-exceptions.c000066400000000000000000000174701303774616400235110ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #include "seed-private.h" #include /** * seed_make_exception: * @ctx: A #SeedContext. * @exception: A reference to a #SeedException in which to store the exception. * @name: The #gchar* representing the exception name. * @message: The #gchar*, as a printf format string, representing the * details of the exception. * @VarArgs: A list of printf-style format arguments to substitute in @message. * * Creates a new JavaScript exception with the given attributes. * * The line number and file name of the exception created will be undefined. * */ void seed_make_exception(JSContextRef ctx, JSValueRef* exception, const gchar* name, const gchar* message, ...) { JSStringRef js_name = 0; JSStringRef js_message = 0; JSValueRef js_name_ref = 0, js_message_ref = 0; JSObjectRef exception_obj; gchar* mes; va_list args; if (!exception) return; va_start(args, message); if (name) { js_name = JSStringCreateWithUTF8CString(name); js_name_ref = JSValueMakeString(ctx, js_name); } if (message) { mes = g_strdup_vprintf(message, args); js_message = JSStringCreateWithUTF8CString(mes); js_message_ref = JSValueMakeString(ctx, js_message); g_free(mes); } // TODO: needs to create a global class named 'name', and this needs to // be an instance of it, for integration with normal JS! exception_obj = JSObjectMake(ctx, 0, NULL); seed_object_set_property(ctx, exception_obj, "message", js_message_ref); seed_object_set_property(ctx, exception_obj, "name", js_name_ref); *exception = exception_obj; JSStringRelease(js_name); JSStringRelease(js_message); va_end(args); } /** * seed_make_exception_from_gerror: * @ctx: A #SeedContext. * @exception: A reference to a #SeedException in which to store the exception. * @error: A #GError* from which to copy the properties of the exception. * * Generates @exception with the name and description of @error. * */ void seed_make_exception_from_gerror(JSContextRef ctx, JSValueRef* exception, GError* error) { const gchar* domain = g_quark_to_string(error->domain); GString* string = g_string_new(domain); guint i; gsize len = string->len; *(string->str) = g_unichar_toupper(*(string->str)); for (i = 0; i < len; i++) { if (*(string->str + i) == '-') { *(string->str + i + 1) = g_unichar_toupper(*(string->str + i + 1)); g_string_erase(string, i, 1); } else if (!g_strcmp0(string->str + i - 1, "Quark")) g_string_truncate(string, i - 1); } seed_make_exception(ctx, exception, string->str, error->message, NULL); g_string_free(string, TRUE); } /** * seed_exception_get_name: * @ctx: A #SeedContext. * @exception: A reference to a #SeedException. * * Retrieves the name of the given exception; this could be one of the * predefined exception names given above, or your own name, which should * be a single CamelCase word, preferably ending in something like "Error". * * Return value: A #gchar* representing the name of @exception. * */ gchar* seed_exception_get_name(JSContextRef ctx, JSValueRef e) { JSValueRef name; g_assert((e)); if (!JSValueIsObject(ctx, e)) return NULL; name = seed_object_get_property(ctx, (JSObjectRef) e, "name"); return seed_value_to_string(ctx, name, NULL); } /** * seed_exception_get_message: * @ctx: A #SeedContext. * @exception: A reference to a #SeedException. * * Retrieves the message of the given exception; this should be a * human-readable string describing the exception enough that a developer * could utilize the message in order to determine where to look to debug * the problem. * * Return value: A #gchar* representing the detailed message of @exception. * */ gchar* seed_exception_get_message(JSContextRef ctx, JSValueRef e) { JSValueRef name; g_assert((e)); if (!JSValueIsObject(ctx, e)) return 0; name = seed_object_get_property(ctx, (JSObjectRef) e, "message"); return seed_value_to_string(ctx, name, NULL); } /** * seed_exception_get_line: * @ctx: A #SeedContext. * @exception: A reference to a #SeedException. * * Retrieves the line number the given exception was thrown from; keep in mind * that exceptions created from C have an undefined line number. * * Return value: A #guint representing the line number from which @exception * was thrown. * */ guint seed_exception_get_line(JSContextRef ctx, JSValueRef e) { JSValueRef line; g_assert((e)); if (!JSValueIsObject(ctx, e)) return 0; line = seed_object_get_property(ctx, (JSObjectRef) e, "line"); return seed_value_to_uint(ctx, line, NULL); } /** * seed_exception_get_file: * @ctx: A #SeedContext. * @exception: A reference to a #SeedException. * * Retrieves the file name the given exception was thrown from; keep in mind * that exceptions created from C have an undefined file name. * * Return value: A #gchar* representing the name of the file from which * @exception was thrown. * */ gchar* seed_exception_get_file(JSContextRef ctx, JSValueRef e) { JSValueRef line; g_assert((e)); if (!JSValueIsObject(ctx, e)) return 0; line = seed_object_get_property(ctx, (JSObjectRef) e, "sourceURL"); return seed_value_to_string(ctx, line, 0); } /** * seed_exception_get_stack: * @ctx: A #SeedContext. * @exception: A reference to a #SeedException. * * Retrieves the backtrace stack (if available.. * * Return value: A #gchar* representing the name of the file from which * @exception was thrown. * */ gchar* seed_exception_get_stack(JSContextRef ctx, JSValueRef e) { JSValueRef stack; g_assert((e)); if (!JSValueIsObject(ctx, e)) return 0; stack = seed_object_get_property(ctx, (JSObjectRef) e, "stack"); return seed_value_to_string(ctx, stack, 0); } /** * seed_exception_to_string: * @ctx: A #SeedContext. * @exception: A reference to a #SeedException. * * Properly formats the name, detailed message, line number, and file name of * the given extension. This provides a consistent format for printed * exceptions, to reduce confusion. Please use it if you're exposing exception * data to the outside world. * * Return value: A #gchar* representing the @exception. * */ gchar* seed_exception_to_string(JSContextRef ctx, JSValueRef e) { guint line; gchar *mes, *name, *file, *ret, *stack; line = seed_exception_get_line(ctx, e); mes = seed_exception_get_message(ctx, e); file = seed_exception_get_file(ctx, e); name = seed_exception_get_name(ctx, e); stack = seed_exception_get_stack(ctx, e); ret = g_strdup_printf("Line %d in %s: %s %s\n\nStack:\n%s", line, file, name, mes, stack); g_free(mes); g_free(file); g_free(name); g_free(stack); return ret; } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/libseed/seed-exceptions.h000066400000000000000000000033071303774616400235100ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #ifndef _SEED_EXCEPTIONS_H #define _SEED_EXCEPTIONS_H #include "seed-private.h" void seed_make_exception(JSContextRef ctx, JSValueRef* exception, const gchar* name, const gchar* message, ...) G_GNUC_PRINTF(4, 5); void seed_make_exception_from_gerror(JSContextRef ctx, JSValueRef* exception, GError* e); gchar* seed_exception_get_name(JSContextRef ctx, JSValueRef e); gchar* seed_exception_get_message(JSContextRef ctx, JSValueRef e); guint seed_exception_get_line(JSContextRef ctx, JSValueRef e); gchar* seed_exception_get_file(JSContextRef ctx, JSValueRef e); gchar* seed_exception_get_stack(JSContextRef ctx, JSValueRef e); gchar* seed_exception_to_string(JSContextRef ctx, JSValueRef e); #endif seed-webkit2-4.0.0+20161014+6c77960+dfsg1/libseed/seed-gtype.c000066400000000000000000001047761303774616400224660ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #include "seed-private.h" #include typedef GObject* (*GObjectConstructCallback)(GType, guint, GObjectConstructParam*); JSClassRef seed_gtype_class; GIBaseInfo* objectclass_info = NULL; GIBaseInfo* paramspec_info = NULL; JSObjectRef seed_gtype_constructor; GQuark qgetter; GQuark qsetter; GQuark qiinit; GQuark qcinit; typedef struct _SeedGClassPrivates { JSObjectRef constructor; JSObjectRef func; JSObjectRef definition; } SeedGClassPrivates; static JSValueRef seed_property_method_invoked(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, gsize argumentCount, const JSValueRef arguments[], JSValueRef* exception) { GParamSpec* spec; GObjectClass* class; guint property_count; JSValueRef newcount, oldcount; if (argumentCount != 1) { seed_make_exception(ctx, exception, "ArgumentError", "Property installation expected 1 argument" " got %zd \n", argumentCount); return JSValueMakeNull(ctx); } if (JSValueIsNull(ctx, arguments[0]) || // Might need to check if JSValueIsObject? Who knows with WebKit. !JSValueIsObjectOfClass(ctx, arguments[0], seed_struct_class)) { seed_make_exception(ctx, exception, "ArgumentError", "Property installation expected a " "GParamSpec as argument"); return JSValueMakeNull(ctx); } spec = (GParamSpec*) seed_pointer_get_pointer(ctx, arguments[0]); oldcount = seed_object_get_property(ctx, thisObject, "property_count"); property_count = seed_value_to_int(ctx, oldcount, exception); class = seed_pointer_get_pointer(ctx, thisObject); g_object_class_install_property(class, property_count, spec); newcount = seed_value_from_int(ctx, property_count + 1, exception); seed_object_set_property(ctx, thisObject, "property_count", newcount); return oldcount; } static JSValueRef seed_gsignal_method_invoked(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, gsize argumentCount, const JSValueRef arguments[], JSValueRef* exception) { // TODO: class_closure, and accumlator. Not useful until we have structs. JSValueRef jsname, jstype, jsflags, jsreturn_type, jsparams; GType itype, return_type; guint n_params = 0; GType* param_types = 0; gchar* name; guint signal_id; GSignalFlags flags; /* Sanity check */ if (argumentCount != 1) { seed_make_exception(ctx, exception, "ArgumentError", "Signal constructor expected 1 argument" " got %zd \n", argumentCount); return (JSObjectRef) JSValueMakeNull(ctx); } if (JSValueIsNull(ctx, arguments[0]) || !JSValueIsObject(ctx, arguments[0])) { seed_make_exception(ctx, exception, "ArgumentError", "Signal constructor expected object" " as first argument"); return (JSObjectRef) JSValueMakeNull(ctx); } /* Signal name */ jsname = seed_object_get_property(ctx, (JSObjectRef) arguments[0], "name"); /* seed_value_to_string can handle non strings, however the kind * of strings we want as a signal name are rather small, so make sure * we have an actual string */ if (JSValueIsNull(ctx, jsname) || !JSValueIsString(ctx, jsname)) { seed_make_exception(ctx, exception, "ArgumentError", "Signal definition needs name property"); return (JSObjectRef) JSValueMakeNull(ctx); } name = seed_value_to_string(ctx, jsname, exception); /* Type to install on. Comes from class. */ jstype = seed_object_get_property(ctx, thisObject, "type"); itype = seed_value_to_int(ctx, jstype, exception); SEED_NOTE(GTYPE, "Installing signal with name: %s on type: %s", name, g_type_name(itype)); /* Signal flags */ jsflags = seed_object_get_property(ctx, (JSObjectRef) arguments[0], "flags"); if (JSValueIsNull(ctx, jsflags) || !JSValueIsNumber(ctx, jsflags)) flags = G_SIGNAL_RUN_LAST; else flags = seed_value_to_long(ctx, jsflags, exception); /* Return type */ jsreturn_type = seed_object_get_property(ctx, (JSObjectRef) arguments[0], "return_type"); if (JSValueIsNull(ctx, jsreturn_type) || !JSValueIsNumber(ctx, jsreturn_type)) return_type = G_TYPE_NONE; else return_type = seed_value_to_int(ctx, jsreturn_type, exception); /* Number of params and types */ jsparams = seed_object_get_property(ctx, (JSObjectRef) arguments[0], "parameters"); if (!JSValueIsNull(ctx, jsparams) && JSValueIsObject(ctx, jsparams)) { n_params = seed_value_to_int( ctx, seed_object_get_property(ctx, (JSObjectRef) jsparams, "length"), exception); if (n_params > 0) { guint i; JSValueRef ptype; param_types = g_new0(GType, n_params); for (i = 0; i < n_params; i++) { ptype = JSObjectGetPropertyAtIndex(ctx, (JSObjectRef) jsparams, i, exception); param_types[i] = seed_value_to_int(ctx, ptype, exception); } } } signal_id = g_signal_newv(name, itype, flags, 0, 0, 0, gi_cclosure_marshal_generic, return_type, n_params, param_types); g_free(name); g_free(param_types); return (JSValueRef) seed_value_from_uint(ctx, signal_id, exception); } static void seed_gtype_builtin_set_property(GObject* object, guint property_id, const GValue* value, GParamSpec* spec) { JSContextRef ctx = JSGlobalContextCreateInGroup(context_group, 0); gchar* name = g_strjoin(NULL, "_", spec->name, NULL); JSObjectRef jsobj = (JSObjectRef) seed_value_from_object(ctx, object, 0); seed_prepare_global_context(ctx); seed_object_set_property(ctx, jsobj, name, seed_value_from_gvalue(ctx, (GValue*) value, 0)); g_free(name); JSGlobalContextRelease((JSGlobalContextRef) ctx); } static void seed_gtype_builtin_get_property(GObject* object, guint property_id, GValue* value, GParamSpec* spec) { // TODO: Exceptions JSContextRef ctx = JSGlobalContextCreateInGroup(context_group, 0); gchar* name = g_strjoin(NULL, "_", spec->name, NULL); JSObjectRef jsobj = (JSObjectRef) seed_value_from_object(ctx, object, 0); JSValueRef jsval = seed_object_get_property(ctx, jsobj, name); seed_prepare_global_context(ctx); seed_value_to_gvalue(ctx, jsval, spec->value_type, value, 0); g_free(name); JSGlobalContextRelease((JSGlobalContextRef) ctx); } static void seed_gtype_set_property(GObject* object, guint property_id, const GValue* value, GParamSpec* spec) { gpointer data = g_param_spec_get_qdata(spec, qsetter); if (!data) { seed_gtype_builtin_set_property(object, property_id, value, spec); return; } } static void seed_gtype_get_property(GObject* object, guint property_id, GValue* value, GParamSpec* spec) { gpointer data = g_param_spec_get_qdata(spec, qgetter); if (!data) { seed_gtype_builtin_get_property(object, property_id, value, spec); return; } } static GIBaseInfo* seed_get_class_info_for_type(GType type) { GIBaseInfo* object_info; // Note to self: Investigate the entire premise of this function. while ((type = g_type_parent(type))) { GIBaseInfo* ret; object_info = g_irepository_find_by_gtype(NULL, type); if (object_info) { ret = g_object_info_get_class_struct((GIObjectInfo*) object_info); g_base_info_unref(object_info); return ret; } } return NULL; } static void seed_attach_methods_to_class_object(JSContextRef ctx, JSObjectRef object, JSValueRef* exception) { seed_create_function(ctx, "c_install_property", &seed_property_method_invoked, object); seed_create_function(ctx, "install_signal", &seed_gsignal_method_invoked, object); } static void seed_gtype_call_construct(GType type, GObject* object) { JSContextRef ctx; JSObjectRef func, this_object; JSValueRef exception = NULL, args[1]; gchar* mes; func = g_type_get_qdata(type, qiinit); if (func) { ctx = JSGlobalContextCreateInGroup(context_group, 0); seed_prepare_global_context(ctx); SEED_NOTE(GTYPE, "Handling constructor for: %p with type: %s", object, g_type_name(type)); this_object = (JSObjectRef) seed_value_from_object(ctx, object, NULL); args[0] = this_object; JSObjectCallAsFunction(ctx, func, this_object, 1, args, &exception); if (exception) { mes = seed_exception_to_string(ctx, exception); g_warning("Exception in instance construction. %s \n", mes); g_free(mes); } JSGlobalContextRelease((JSGlobalContextRef) ctx); } } static GObject* seed_gtype_construct(GType type, guint n_construct_params, GObjectConstructParam* construct_params) { GObject* object; GType parent; GObjectClass* parent_class; parent = g_type_parent(type); parent_class = g_type_class_ref(parent); if (parent_class->constructor == seed_gtype_construct) { GType t = parent; parent = g_type_parent(parent); g_type_class_unref(parent_class); parent_class = g_type_class_ref(parent); object = parent_class->constructor(type, n_construct_params, construct_params); seed_gtype_call_construct(t, object); g_type_class_unref(parent_class); } else object = parent_class->constructor(type, n_construct_params, construct_params); seed_gtype_call_construct(type, object); g_type_class_unref(parent_class); return object; } static void seed_gtype_install_signals(JSContextRef ctx, JSObjectRef definition, GType type, JSValueRef* exception) { JSObjectRef signals, signal_def; JSValueRef jslength; guint i, j, length; GType return_type; GType* param_types = NULL; guint n_params = 0; GSignalFlags flags; JSValueRef jsname, jsflags, jsreturn_type, jsparams; gchar* name; signals = (JSObjectRef) seed_object_get_property(ctx, definition, "signals"); if (JSValueIsNull(ctx, signals) || !JSValueIsObject(ctx, signals)) return; jslength = seed_object_get_property(ctx, signals, "length"); if (JSValueIsNull(ctx, jslength)) return; length = seed_value_to_uint(ctx, jslength, exception); for (i = 0; i < length; i++) { signal_def = (JSObjectRef) JSObjectGetPropertyAtIndex(ctx, (JSObjectRef) signals, i, exception); if (JSValueIsNull(ctx, signal_def) || !JSValueIsObject(ctx, signal_def)) continue; // TODO: Error checking jsname = seed_object_get_property(ctx, signal_def, "name"); name = seed_value_to_string(ctx, jsname, exception); SEED_NOTE(GTYPE, "Installing signal with name: %s on type: %s", name, g_type_name(type)); jsflags = seed_object_get_property(ctx, (JSObjectRef) signal_def, "flags"); if (JSValueIsNull(ctx, jsflags) || !JSValueIsNumber(ctx, jsflags)) flags = G_SIGNAL_RUN_LAST; else flags = seed_value_to_long(ctx, jsflags, exception); jsreturn_type = seed_object_get_property(ctx, signal_def, "return_type"); if (JSValueIsNull(ctx, jsreturn_type) || !JSValueIsNumber(ctx, jsreturn_type)) return_type = G_TYPE_NONE; else return_type = seed_value_to_long(ctx, jsreturn_type, exception); jsparams = seed_object_get_property(ctx, signal_def, "parameters"); // reset params.. param_types = NULL; n_params = 0; if (!JSValueIsNull(ctx, jsparams) && JSValueIsObject(ctx, jsparams)) { n_params = seed_value_to_int( ctx, seed_object_get_property(ctx, (JSObjectRef) jsparams, "length"), exception); if (n_params > 0) { param_types = g_alloca(sizeof(GType) * n_params); for (j = 0; j < n_params; j++) { JSValueRef ptype = JSObjectGetPropertyAtIndex(ctx, (JSObjectRef) jsparams, j, exception); param_types[j] = (GType) seed_value_to_long(ctx, ptype, exception); } } } g_signal_newv(name, type, flags, 0, 0, 0, gi_cclosure_marshal_generic, return_type, n_params, param_types); g_free(name); } } static unsigned int seed_gtype_install_properties(JSContextRef ctx, JSObjectRef definition, GType type, GObjectClass* g_class, JSValueRef* exception) { JSObjectRef properties, property_def; JSValueRef jslength; guint i, length; GType property_type, object_type; GParamFlags flags; JSValueRef jsname, jsflags, jsproperty_type, jsdefault_value, jsobject_type; JSValueRef jsnick, jsblurb, jsmin_value, jsmax_value; gchar *name, *nick, *blurb; GParamSpec* pspec; guint property_count = 0; properties = (JSObjectRef) seed_object_get_property(ctx, definition, "properties"); if (JSValueIsNull(ctx, properties) || !JSValueIsObject(ctx, properties)) return 0; jslength = seed_object_get_property(ctx, properties, "length"); if (JSValueIsNull(ctx, jslength)) return 0; length = seed_value_to_uint(ctx, jslength, exception); for (i = 0; i < length; i++) { property_def = (JSObjectRef) JSObjectGetPropertyAtIndex(ctx, (JSObjectRef) properties, i, NULL); if (JSValueIsNull(ctx, property_def) || !JSValueIsObject(ctx, property_def)) continue; jsname = seed_object_get_property(ctx, property_def, "name"); if (!JSValueIsString(ctx, jsname)) { seed_make_exception(ctx, exception, "PropertyInstallationError", "Property requires name attribute"); return property_count; } name = seed_value_to_string(ctx, jsname, exception); // Check for "nick" property; set to name if nonexistent jsnick = seed_object_get_property(ctx, property_def, "nick"); if (!JSValueIsString(ctx, jsnick)) nick = name; else nick = seed_value_to_string(ctx, jsnick, exception); // Check for "blurb" property; set to name if nonexistent jsblurb = seed_object_get_property(ctx, property_def, "blurb"); if (!JSValueIsString(ctx, jsblurb)) blurb = name; else blurb = seed_value_to_string(ctx, jsblurb, exception); SEED_NOTE(GTYPE, "Installing property with name: %s on type: %s", name, g_type_name(type)); // Flags default to read/write, non-construct jsflags = seed_object_get_property(ctx, (JSObjectRef) property_def, "flags"); if (JSValueIsNull(ctx, jsflags) || !JSValueIsNumber(ctx, jsflags)) flags = G_PARAM_READABLE | G_PARAM_WRITABLE; else flags = seed_value_to_long(ctx, jsflags, exception); jsproperty_type = seed_object_get_property(ctx, property_def, "type"); if (JSValueIsNull(ctx, jsproperty_type) || !JSValueIsNumber(ctx, jsproperty_type)) property_type = G_TYPE_NONE; else property_type = seed_value_to_long(ctx, jsproperty_type, exception); jsdefault_value = seed_object_get_property(ctx, property_def, "default_value"); if (JSValueIsNull(ctx, jsdefault_value) || JSValueIsUndefined(ctx, jsdefault_value)) { if (property_type == G_TYPE_OBJECT) continue; seed_make_exception( ctx, exception, "PropertyInstallationError", "Property of type %s requires default_value attribute", g_type_name(property_type)); return property_count; } jsmin_value = seed_object_get_property(ctx, property_def, "minimum_value"); jsmax_value = seed_object_get_property(ctx, property_def, "maximum_value"); // Make sure min/max properties are defined, based on type if (property_type == G_TYPE_CHAR || property_type == G_TYPE_UCHAR || property_type == G_TYPE_INT || property_type == G_TYPE_UINT || property_type == G_TYPE_INT64 || property_type == G_TYPE_UINT64 || property_type == G_TYPE_FLOAT || property_type == G_TYPE_DOUBLE) { if (JSValueIsNull(ctx, jsmin_value) || !JSValueIsNumber(ctx, jsmin_value)) { seed_make_exception( ctx, exception, "PropertyInstallationError", "Property of type %s requires minimum_value attribute", g_type_name(property_type)); return property_count; } if (JSValueIsNull(ctx, jsmax_value) || !JSValueIsNumber(ctx, jsmax_value)) { seed_make_exception( ctx, exception, "PropertyInstallationError", "Property of type %s requires maximum_value attribute", g_type_name(property_type)); return property_count; } } switch (property_type) { case G_TYPE_BOOLEAN: pspec = g_param_spec_boolean( name, nick, blurb, seed_value_to_boolean(ctx, jsdefault_value, exception), flags); break; case G_TYPE_CHAR: pspec = g_param_spec_char( name, nick, blurb, seed_value_to_char(ctx, jsmin_value, exception), seed_value_to_char(ctx, jsmax_value, exception), seed_value_to_char(ctx, jsdefault_value, exception), flags); break; case G_TYPE_UCHAR: pspec = g_param_spec_uchar( name, nick, blurb, seed_value_to_uchar(ctx, jsmin_value, exception), seed_value_to_uchar(ctx, jsmax_value, exception), seed_value_to_uchar(ctx, jsdefault_value, exception), flags); break; case G_TYPE_INT: pspec = g_param_spec_int( name, nick, blurb, seed_value_to_int(ctx, jsmin_value, exception), seed_value_to_int(ctx, jsmax_value, exception), seed_value_to_int(ctx, jsdefault_value, exception), flags); break; case G_TYPE_UINT: pspec = g_param_spec_uint( name, nick, blurb, seed_value_to_uint(ctx, jsmin_value, exception), seed_value_to_uint(ctx, jsmax_value, exception), seed_value_to_uint(ctx, jsdefault_value, exception), flags); break; case G_TYPE_LONG: pspec = g_param_spec_long( name, nick, blurb, seed_value_to_long(ctx, jsmin_value, exception), seed_value_to_long(ctx, jsmax_value, exception), seed_value_to_long(ctx, jsdefault_value, exception), flags); break; case G_TYPE_ULONG: pspec = g_param_spec_ulong( name, nick, blurb, seed_value_to_ulong(ctx, jsmin_value, exception), seed_value_to_ulong(ctx, jsmax_value, exception), seed_value_to_ulong(ctx, jsdefault_value, exception), flags); break; case G_TYPE_INT64: pspec = g_param_spec_int64( name, nick, blurb, seed_value_to_int64(ctx, jsmin_value, exception), seed_value_to_int64(ctx, jsmax_value, exception), seed_value_to_int64(ctx, jsdefault_value, exception), flags); break; case G_TYPE_UINT64: pspec = g_param_spec_uint64( name, nick, blurb, seed_value_to_uint64(ctx, jsmin_value, exception), seed_value_to_uint64(ctx, jsmax_value, exception), seed_value_to_uint64(ctx, jsdefault_value, exception), flags); break; case G_TYPE_FLOAT: pspec = g_param_spec_float( name, nick, blurb, seed_value_to_float(ctx, jsmin_value, exception), seed_value_to_float(ctx, jsmax_value, exception), seed_value_to_float(ctx, jsdefault_value, exception), flags); break; case G_TYPE_DOUBLE: pspec = g_param_spec_double( name, nick, blurb, seed_value_to_double(ctx, jsmin_value, exception), seed_value_to_double(ctx, jsmax_value, exception), seed_value_to_double(ctx, jsdefault_value, exception), flags); break; // TODO: support enums/flags/params case G_TYPE_STRING: // TODO: leaky? pspec = g_param_spec_string( name, nick, blurb, seed_value_to_string(ctx, jsdefault_value, exception), flags); break; case G_TYPE_OBJECT: jsobject_type = seed_object_get_property(ctx, property_def, "object_type"); if (JSValueIsNull(ctx, jsobject_type) || !JSValueIsNumber(ctx, jsobject_type)) object_type = G_TYPE_NONE; else object_type = seed_value_to_long(ctx, jsobject_type, exception); if (object_type == G_TYPE_NONE) { seed_make_exception( ctx, exception, "PropertyInstallationError", "Property of type %s requires object_type attribute", g_type_name(property_type)); return property_count; } pspec = g_param_spec_object(name, nick, blurb, object_type, flags); break; case G_TYPE_BOXED: // Boxed types TODO: this is almost certainly // wrong pspec = g_param_spec_boxed(name, nick, blurb, type, flags); break; default: case G_TYPE_NONE: seed_make_exception(ctx, exception, "PropertyInstallationError", "Property requires type attribute"); return property_count; break; } g_object_class_install_property(g_class, ++property_count, pspec); if (nick != name) g_free(nick); if (blurb != name) g_free(blurb); g_free(name); } return property_count; } static void seed_gtype_class_init(gpointer g_class, gpointer class_data) { SeedGClassPrivates* priv; GIBaseInfo* class_info; JSContextRef ctx; JSValueRef jsargs[2]; GType type; JSValueRef exception = NULL; int initial_prop_count = 1; GQuark class_init_exception_q = g_quark_from_static_string("type-class-init-exception"); priv = (SeedGClassPrivates*) class_data; ((GObjectClass*) g_class)->get_property = seed_gtype_get_property; ((GObjectClass*) g_class)->set_property = seed_gtype_set_property; ((GObjectClass*) g_class)->constructor = seed_gtype_construct; ctx = JSGlobalContextCreateInGroup(context_group, 0); type = (GType) JSObjectGetPrivate(priv->constructor); seed_gtype_install_signals(ctx, priv->definition, type, &exception); initial_prop_count = seed_gtype_install_properties(ctx, priv->definition, type, (GObjectClass*) g_class, &exception); if (!priv->func) { JSGlobalContextRelease((JSGlobalContextRef) ctx); if (exception) { g_type_set_qdata(type, class_init_exception_q, (gpointer) exception); } return; } seed_prepare_global_context(ctx); class_info = seed_get_class_info_for_type(type); jsargs[0] = seed_make_struct(ctx, g_class, class_info); jsargs[1] = seed_gobject_get_prototype_for_gtype(type); seed_attach_methods_to_class_object(ctx, (JSObjectRef) jsargs[0], &exception); g_base_info_unref((GIBaseInfo*) class_info); SEED_NOTE(GTYPE, "Marshalling class init for type: %s", g_type_name(type)); seed_object_set_property(ctx, (JSObjectRef) jsargs[0], "type", seed_value_from_int(ctx, type, 0)); seed_object_set_property(ctx, (JSObjectRef) jsargs[0], "property_count", seed_value_from_int(ctx, initial_prop_count + 1, 0)); JSObjectCallAsFunction(ctx, priv->func, 0, 2, jsargs, &exception); if (exception) { g_type_set_qdata(type, class_init_exception_q, (gpointer) exception); } JSGlobalContextRelease((JSGlobalContextRef) ctx); } static JSObjectRef seed_gtype_constructor_invoked(JSContextRef ctx, JSObjectRef constructor, gsize argumentCount, const JSValueRef arguments[], JSValueRef* exception) { JSValueRef class_init, instance_init, name, parent_ref; GType parent_type, new_type; gchar* new_name; GTypeInfo type_info = { 0, (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) NULL, (GClassFinalizeFunc) NULL, NULL, 0, 0, NULL }; GTypeQuery query; JSObjectRef constructor_ref; SeedGClassPrivates* priv; if (argumentCount != 1) { seed_make_exception(ctx, exception, "ArgumentError", "GType constructor expected 1 " "argument, got %zd \n", argumentCount); return (JSObjectRef) JSValueMakeNull(ctx); } if (!JSValueIsObject(ctx, arguments[0])) { seed_make_exception(ctx, exception, "ArgumentError", "GType constructor expected a" "class definition object. Got a nonobject"); return (JSObjectRef) JSValueMakeNull(ctx); } parent_ref = seed_object_get_property(ctx, (JSObjectRef) arguments[0], "parent"); class_init = seed_object_get_property(ctx, (JSObjectRef) arguments[0], "class_init"); instance_init = seed_object_get_property(ctx, (JSObjectRef) arguments[0], "init"); name = seed_object_get_property(ctx, (JSObjectRef) arguments[0], "name"); new_name = seed_value_to_string(ctx, name, exception); if (!JSValueIsNumber(ctx, parent_ref)) { seed_make_exception(ctx, exception, "TypeError", "GType constructor expected GType for parent"); return NULL; } // TODO: GType is of variable length, so this is an incorrect fix parent_type = (GType) seed_value_to_long(ctx, parent_ref, exception); SEED_NOTE(GTYPE, "Registering new GType with name: %s as child of %s.", new_name, g_type_name(parent_type)); g_type_query(parent_type, &query); type_info.class_size = query.class_size; type_info.instance_size = query.instance_size; type_info.class_init = seed_gtype_class_init; priv = g_slice_alloc(sizeof(SeedGClassPrivates)); if (!JSValueIsNull(ctx, class_init) && JSValueIsObject(ctx, class_init) && JSObjectIsFunction(ctx, (JSObjectRef) class_init)) { priv->func = (gpointer) class_init; JSValueProtect(ctx, class_init); } constructor_ref = JSObjectMake(ctx, gobject_constructor_class, (gpointer) 0); JSValueProtect(ctx, constructor_ref); priv->constructor = constructor_ref; JSValueProtect(ctx, arguments[0]); priv->definition = (JSObjectRef) arguments[0]; type_info.class_data = priv; new_type = g_type_register_static(parent_type, new_name, &type_info, 0); seed_gobject_get_class_for_gtype(ctx, new_type); JSObjectSetPrivate(constructor_ref, (gpointer) new_type); seed_object_set_property(ctx, constructor_ref, "type", seed_value_from_int(ctx, new_type, exception)); if (!JSValueIsNull(ctx, instance_init) && JSValueIsObject(ctx, instance_init) && JSObjectIsFunction(ctx, (JSObjectRef) instance_init)) { g_type_set_qdata(new_type, qiinit, (gpointer) instance_init); JSValueProtect(ctx, instance_init); } g_free(new_name); return constructor_ref; } static JSValueRef seed_param_getter_invoked(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, gsize argumentCount, const JSValueRef arguments[], JSValueRef* exception) { GParamSpec* pspec = seed_pointer_get_pointer(ctx, thisObject); if (argumentCount != 1) { seed_make_exception(ctx, exception, "ArgumentError", "ParamSpec.get expected " "1 argument, got %zd", argumentCount); return JSValueMakeNull(ctx); } else if (JSValueIsNull(ctx, arguments[0]) || !JSValueIsObject(ctx, arguments[0]) || !JSObjectIsFunction(ctx, (JSObjectRef) arguments[0])) { // Maybe should accept C functions seed_make_exception(ctx, exception, "ArgumentError", "ParamSpec.get expected a function"); return JSValueMakeNull(ctx); } g_param_spec_set_qdata(pspec, qgetter, (gpointer) arguments[0]); return seed_value_from_boolean(ctx, TRUE, exception); } static JSValueRef seed_param_setter_invoked(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, gsize argumentCount, const JSValueRef arguments[], JSValueRef* exception) { GParamSpec* pspec = seed_pointer_get_pointer(ctx, thisObject); if (argumentCount != 1) { seed_make_exception(ctx, exception, "ArgumentError", "ParamSpec.set expected " "1 argument, got %zd", argumentCount); return JSValueMakeNull(ctx); } else if (JSValueIsNull(ctx, arguments[0]) || !JSValueIsObject(ctx, arguments[0]) || !JSObjectIsFunction(ctx, (JSObjectRef) arguments[0])) { // Maybe should accept C functions seed_make_exception(ctx, exception, "ArgumentError", "ParamSpec.set expected a function"); return JSValueMakeNull(ctx); } g_param_spec_set_qdata(pspec, qsetter, (gpointer) arguments[0]); return seed_value_from_boolean(ctx, TRUE, exception); } void seed_define_gtype_functions(JSContextRef ctx) { JSObjectRef proto; objectclass_info = g_irepository_find_by_name(NULL, "GObject", "ObjectClass"); proto = seed_struct_prototype(ctx, objectclass_info); /* // paramspec is remove in newer versions of introspeciton - removing // until we can work out how to replace this. paramspec_info = g_irepository_find_by_name (NULL, "GObject", "ParamSpec"); proto = seed_struct_prototype (ctx, paramspec_info); */ seed_create_function(ctx, "get", &seed_param_getter_invoked, proto); seed_create_function(ctx, "set", &seed_param_setter_invoked, proto); } void seed_gtype_init(SeedEngine* local_eng) { JSClassDefinition gtype_def = kJSClassDefinitionEmpty; gtype_def.callAsConstructor = seed_gtype_constructor_invoked; seed_gtype_class = JSClassCreate(>ype_def); JSClassRetain(seed_gtype_class); seed_gtype_constructor = JSObjectMake(local_eng->context, seed_gtype_class, 0); seed_object_set_property(local_eng->context, local_eng->global, "GType", seed_gtype_constructor); qiinit = g_quark_from_static_string("js-instance-init"); seed_define_gtype_functions(local_eng->context); } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/libseed/seed-gtype.h000066400000000000000000000017751303774616400224660ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #ifndef _SEED_GTYPE_H #define _SEED_GTYPE_H #include "seed-private.h" void seed_gtype_init(SeedEngine* eng); extern JSObjectRef seed_gtype_constructor; #endif seed-webkit2-4.0.0+20161014+6c77960+dfsg1/libseed/seed-importer.c000066400000000000000000001230701303774616400231630ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #include #include #include #include #include #include "seed-private.h" JSClassRef importer_class; JSObjectRef importer; JSClassRef gi_importer_class; JSObjectRef gi_importer; JSObjectRef gi_importer_versions; JSObjectRef importer_search_path; JSClassRef importer_dir_class; GHashTable* gi_imports; GHashTable* file_imports; /* * Some high level documentation of the importer object. * > imports * - An imports object is declared at the top level of every context * > gi * - The imports object has a special property named gi * - gi.NameSpace represents the namespace object for a specific * girepository namespace. * - The first attempt to access gi.Foo creates the object, all * subsequent attempts access the SAME object. * > versions * - the gi.versions object can be used to set versions of gi imports * - gi.versions.NameSpace being set to "0.8" will cause NameSpace to * require 0.8 * > searchPath * - Should be an array, containing a list of paths to be searched for * importing javascript files and native modules. * - Default is set in Seed.js * - If set to an invalid value, this will not become evident until the * next time the imports object is used, at which point it will throw an * exception * > Accessing any other property (call it prop) will proceed as follows * - Look in the search path for a file prop.* * - If we find a file prop.*, see if it is a regular file or directory * - If it is a directory, return a directory object that behaves as does * the toplevel imports object, with the searchPath being exclusively * that directory * - If it is a file and ends in G_MODULE_SUFFIX, attempt to load it as a * native module and return the module object. * - If it is a file and does not end in G_MODULE_SUFFIX, evaluate it as a * JavaScript file in a NEW global context, and return the global object * for that context. */ gboolean seed_file_test(const gchar* path, GFileTest test) { // XXX: This is a nasty hack. what we should do is probably // to check for GResource children in a given path and // then return TRUE if any children exists for that path gboolean exists = FALSE; gboolean isdir = FALSE; if (g_str_has_prefix(path, "/org/seed")) { if (g_strcmp0(path, "/org/seed") == 0 || g_strcmp0(path, "/org/seed/extensions") == 0 || g_strcmp0(path, "/org/seed/extensions/gjs") == 0) { isdir = TRUE; exists = TRUE; } else if (g_resources_get_info(path, G_RESOURCE_LOOKUP_FLAGS_NONE, NULL, NULL, NULL)) { isdir = FALSE; exists = TRUE; } // Return only if file is in GResource. // Otherwise fallback to g_file_test if (exists) { if (test & G_FILE_TEST_EXISTS) return TRUE; if (test & G_FILE_TEST_IS_REGULAR) if (!isdir) return !isdir; if (test & G_FILE_TEST_IS_DIR) if (isdir) return isdir; } } return g_file_test(path, test); } /* * Handle definition of toplevel functions in a namespace. * i.e. Gtk.main. */ static gboolean seed_gi_importer_is_init(GIFunctionInfo* info) { if (g_strcmp0(g_base_info_get_name((GIBaseInfo*) info), "init")) { return FALSE; } if (g_callable_info_get_n_args((GICallableInfo*) info) != 2) return FALSE; return TRUE; } static void seed_gi_importer_handle_function(JSContextRef ctx, JSObjectRef namespace_ref, GIFunctionInfo* info, JSValueRef* exception) { if (!seed_gi_importer_is_init(info)) seed_gobject_define_property_from_function_info(ctx, (GIFunctionInfo*) info, namespace_ref, FALSE); else { JSObjectRef init_method; init_method = JSObjectMake(ctx, gobject_init_method_class, g_base_info_ref((GIBaseInfo*) info)); seed_object_set_property(ctx, namespace_ref, "init", init_method); } } /* * Handle definition of enums in a namespace. * Each enum class gets an object containing * a value for each member, all in uppercase * i.e. Gtk.WindowType.NORMAL */ static void seed_gi_importer_handle_enum(JSContextRef ctx, JSObjectRef namespace_ref, GIEnumInfo* info, JSValueRef* exception) { JSObjectRef enum_class; guint num_vals, i, j; gsize name_len; gint value; // TODO: investigate what's up with the glong/gint mystery here gchar* name; GIValueInfo* val; enum_class = JSObjectMake(ctx, 0, 0); num_vals = g_enum_info_get_n_values(info); seed_object_set_property(ctx, namespace_ref, g_base_info_get_name((GIBaseInfo*) info), enum_class); for (i = 0; i < num_vals; i++) { val = g_enum_info_get_value((GIEnumInfo*) info, i); value = g_value_info_get_value(val); name = g_strdup(g_base_info_get_name((GIBaseInfo*) val)); name_len = strlen(name); JSValueRef value_ref; value_ref = JSValueMakeNumber(ctx, value); JSValueProtect(ctx, (JSValueRef) value_ref); for (j = 0; j < name_len; j++) { if (name[j] == '-') name[j] = '_'; name[j] = g_ascii_toupper(name[j]); } seed_object_set_property(ctx, enum_class, name, value_ref); g_free(name); g_base_info_unref((GIBaseInfo*) val); } } /* * Handle setting up the prototype and constructor for a GObject type * Namespace.Type will be the constructor and Namespace.Type.prototype is * the prototype object. Namespace.Type.type will be the GType. */ static void seed_gi_importer_handle_object(JSContextRef ctx, JSObjectRef namespace_ref, GIObjectInfo* info, JSValueRef* exception) { GType type; JSClassRef class_ref; type = g_registered_type_info_get_g_type((GIRegisteredTypeInfo*) info); if (type != 0) { GIFunctionInfo* finfo; GIFunctionInfoFlags flags; JSObjectRef constructor_ref; guint i, n_methods; class_ref = seed_gobject_get_class_for_gtype(ctx, type); constructor_ref = JSObjectMake(ctx, gobject_constructor_class, (gpointer) type); seed_object_set_property(ctx, constructor_ref, "type", seed_value_from_long(ctx, type, exception)); n_methods = g_object_info_get_n_methods(info); for (i = 0; i < n_methods; i++) { finfo = g_object_info_get_method(info, i); flags = g_function_info_get_flags(finfo); if (flags & GI_FUNCTION_IS_CONSTRUCTOR) { JSObjectRef constructor = JSObjectMake(ctx, gobject_named_constructor_class, finfo); const gchar* fname = g_base_info_get_name((GIBaseInfo*) finfo); if (g_strrstr(fname, "new_") == fname) { // To be compatible with gjs, we need to have a method with // new_, too. seed_object_set_property(ctx, constructor_ref, fname, constructor); fname += 4; } else if (!g_strcmp0(fname, "new")) { // To be compatible with gjs, we need to have new as // function, too. seed_object_set_property(ctx, constructor_ref, fname, constructor); fname = "c_new"; } seed_object_set_property(ctx, constructor_ref, fname, constructor); } else if (!(flags & GI_FUNCTION_IS_METHOD)) { seed_gobject_define_property_from_function_info(ctx, finfo, constructor_ref, FALSE); } else { g_base_info_unref((GIBaseInfo*) finfo); } } seed_object_set_property(ctx, namespace_ref, g_base_info_get_name((GIBaseInfo*) info), constructor_ref); seed_object_set_property(ctx, constructor_ref, "prototype", seed_gobject_get_prototype_for_gtype(type)); } } static void seed_gi_importer_handle_iface(JSContextRef ctx, JSObjectRef namespace_ref, GIObjectInfo* info, JSValueRef* exception) { GType type; type = g_registered_type_info_get_g_type((GIRegisteredTypeInfo*) info); if (type != 0) { GIFunctionInfo* finfo; GIFunctionInfoFlags flags; JSObjectRef constructor_ref; guint i, n_methods; constructor_ref = JSObjectMake(ctx, gobject_constructor_class, (gpointer) type); seed_object_set_property(ctx, constructor_ref, "type", seed_value_from_long(ctx, type, exception)); n_methods = g_interface_info_get_n_methods(info); for (i = 0; i < n_methods; i++) { finfo = g_interface_info_get_method(info, i); flags = g_function_info_get_flags(finfo); if (!(flags & GI_FUNCTION_IS_METHOD)) { seed_gobject_define_property_from_function_info(ctx, finfo, constructor_ref, FALSE); } else { g_base_info_unref((GIBaseInfo*) finfo); } } seed_object_set_property(ctx, namespace_ref, g_base_info_get_name((GIBaseInfo*) info), constructor_ref); seed_object_set_property(ctx, constructor_ref, "prototype", seed_gobject_get_prototype_for_gtype(type)); } } /* * Set up prototype and constructor for structs. Same semantics as objects * except * for the type. */ static void seed_gi_importer_handle_struct(JSContextRef ctx, JSObjectRef namespace_ref, GIStructInfo* info, JSValueRef* exception) { JSObjectRef struct_ref; JSObjectRef proto; gint i, n_methods; GIFunctionInfo* finfo; struct_ref = JSObjectMake(ctx, seed_struct_constructor_class, info); g_base_info_ref(info); n_methods = g_struct_info_get_n_methods(info); for (i = 0; i < n_methods; i++) { GIFunctionInfoFlags flags; finfo = g_struct_info_get_method(info, i); flags = g_function_info_get_flags(finfo); if (flags & GI_FUNCTION_IS_CONSTRUCTOR) { JSObjectRef constructor = JSObjectMake(ctx, gobject_named_constructor_class, finfo); const gchar* fname = g_base_info_get_name((GIBaseInfo*) finfo); if (g_strrstr(fname, "new_") == fname) { // To be compatible with gjs, we need to have a method with // new_, too. seed_object_set_property(ctx, struct_ref, fname, constructor); fname += 4; } else if (!g_strcmp0(fname, "new")) { // To be compatible with gjs, we need to have new as function, // too. seed_object_set_property(ctx, struct_ref, fname, constructor); fname = "c_new"; } seed_object_set_property(ctx, struct_ref, fname, constructor); } else if (flags & GI_FUNCTION_IS_METHOD) g_base_info_unref((GIBaseInfo*) finfo); else seed_gobject_define_property_from_function_info(ctx, finfo, struct_ref, FALSE); } proto = seed_struct_prototype(ctx, (GIBaseInfo*) info); seed_object_set_property(ctx, struct_ref, "prototype", proto); seed_object_set_property(ctx, namespace_ref, g_base_info_get_name((GIBaseInfo*) info), struct_ref); } static void seed_gi_importer_handle_union(JSContextRef ctx, JSObjectRef namespace_ref, GIUnionInfo* info, JSValueRef* exception) { JSObjectRef union_ref; JSObjectRef proto; guint i, n_methods; GIFunctionInfo* finfo; union_ref = JSObjectMake(ctx, seed_struct_constructor_class, info); g_base_info_ref(info); n_methods = g_union_info_get_n_methods(info); for (i = 0; i < n_methods; i++) { GIFunctionInfoFlags flags; finfo = g_union_info_get_method(info, i); flags = g_function_info_get_flags(finfo); if (flags & GI_FUNCTION_IS_METHOD) g_base_info_unref((GIBaseInfo*) finfo); else seed_gobject_define_property_from_function_info(ctx, finfo, union_ref, FALSE); } proto = seed_union_prototype(ctx, (GIBaseInfo*) info); seed_object_set_property(ctx, union_ref, "prototype", proto); seed_object_set_property(ctx, namespace_ref, g_base_info_get_name((GIBaseInfo*) info), union_ref); } static void seed_gi_importer_handle_callback(JSContextRef ctx, JSObjectRef namespace_ref, GICallbackInfo* info, JSValueRef* exception) { JSObjectRef callback_ref = JSObjectMake(ctx, seed_callback_class, info); seed_object_set_property(ctx, namespace_ref, g_base_info_get_name((GIBaseInfo*) info), (JSValueRef) callback_ref); } /* * Define constants toplevel. Uses the casing as in the typelib */ static void seed_gi_importer_handle_constant(JSContextRef ctx, JSObjectRef namespace_ref, GIConstantInfo* info, JSValueRef* exception) { GArgument argument; GITypeInfo* constant_type = g_constant_info_get_type(info); JSValueRef constant_value; g_constant_info_get_value(info, &argument); constant_value = seed_value_from_gi_argument(ctx, &argument, constant_type, exception); seed_object_set_property(ctx, namespace_ref, g_base_info_get_name((GIBaseInfo*) info), constant_value); g_base_info_unref((GIBaseInfo*) constant_type); g_constant_info_free_value(info, &argument); } static gchar* seed_gi_importer_get_version(JSContextRef ctx, gchar* namespace, JSValueRef* exception) { JSValueRef version_ref; gchar* version = NULL; version_ref = seed_object_get_property(ctx, gi_importer_versions, namespace); if (!JSValueIsUndefined(ctx, version_ref)) version = seed_value_to_string(ctx, version_ref, exception); return version; } static JSObjectRef lookup_init_override(JSContextRef ctx, JSObjectRef module) { JSValueRef ret = NULL; ret = seed_object_get_property(ctx, module, "_init"); if (JSValueIsObject(ctx, ret)) return JSValueToObject(ctx, ret, NULL); return NULL; } JSObjectRef seed_gi_importer_do_namespace(JSContextRef ctx, gchar* namespace, JSValueRef* exception) { GIBaseInfo* info; JSObjectRef namespace_ref; GError* e = NULL; guint n, i; gchar* version = NULL; gchar* jsextension; JSStringRef extension_script; if (gi_imports == NULL) gi_imports = g_hash_table_new(g_str_hash, g_str_equal); if ((namespace_ref = g_hash_table_lookup(gi_imports, namespace))) { SEED_NOTE(IMPORTER, "Using existing namespace ref (%p) for %s", namespace_ref, namespace); return namespace_ref; } if (gi_importer_versions != NULL) version = seed_gi_importer_get_version(ctx, namespace, exception); if (!g_irepository_require(NULL, namespace, version, 0, &e)) { seed_make_exception_from_gerror(ctx, exception, e); g_error_free(e); g_free(version); return NULL; } if (version != NULL) g_free(version); n = g_irepository_get_n_infos(NULL, namespace); namespace_ref = JSObjectMake(ctx, NULL, NULL); SEED_NOTE(IMPORTER, "Constructing namespace ref (%p) for %s", namespace_ref, namespace); JSValueProtect(ctx, namespace_ref); for (i = 0; i < n; i++) { GIInfoType info_type; info = g_irepository_get_info(NULL, namespace, i); info_type = g_base_info_get_type(info); switch (info_type) { case GI_INFO_TYPE_FUNCTION: seed_gi_importer_handle_function(ctx, namespace_ref, (GIFunctionInfo*) info, exception); break; case GI_INFO_TYPE_ENUM: case GI_INFO_TYPE_FLAGS: seed_gi_importer_handle_enum(ctx, namespace_ref, (GIEnumInfo*) info, exception); break; case GI_INFO_TYPE_OBJECT: seed_gi_importer_handle_object(ctx, namespace_ref, (GIObjectInfo*) info, exception); break; case GI_INFO_TYPE_INTERFACE: seed_gi_importer_handle_iface(ctx, namespace_ref, (GIObjectInfo*) info, exception); break; case GI_INFO_TYPE_STRUCT: seed_gi_importer_handle_struct(ctx, namespace_ref, (GIStructInfo*) info, exception); break; case GI_INFO_TYPE_UNION: seed_gi_importer_handle_union(ctx, namespace_ref, (GIUnionInfo*) info, exception); break; case GI_INFO_TYPE_CALLBACK: seed_gi_importer_handle_callback(ctx, namespace_ref, (GICallbackInfo*) info, exception); break; case GI_INFO_TYPE_CONSTANT: seed_gi_importer_handle_constant(ctx, namespace_ref, (GIConstantInfo*) info, exception); break; default: SEED_NOTE(IMPORTER, "Unhandled type %s for %s", g_info_type_to_string(info_type), g_base_info_get_name(info)); break; } g_base_info_unref(info); } g_hash_table_insert(gi_imports, g_strdup(namespace), namespace_ref); jsextension = g_strdup_printf("imports.extensions.%s", namespace); extension_script = JSStringCreateWithUTF8CString(jsextension); JSValueRef extension = JSEvaluateScript(ctx, extension_script, NULL, NULL, 0, exception); JSStringRelease(extension_script); g_free(jsextension); if (JSValueIsObject(ctx, extension)) { JSObjectRef init = NULL; init = lookup_init_override(ctx, JSValueToObject(ctx, extension, NULL)); if (init && JSObjectIsFunction(ctx, init)) { JSValueRef loc_exception = NULL; SEED_NOTE(IMPORTER, "Calling %s_init():", namespace); JSObjectCallAsFunction(ctx, init, namespace_ref, 0, NULL, &loc_exception); if (loc_exception) { gchar *ext_text = seed_exception_to_string(ctx, loc_exception); g_critical("Exception when calling _init for %s: %s", namespace, ext_text); g_free(ext_text); } } } return namespace_ref; } static JSValueRef seed_gi_importer_get_property(JSContextRef ctx, JSObjectRef object, JSStringRef property_name, JSValueRef* exception) { JSObjectRef ret; guint len; gchar* prop; len = JSStringGetMaximumUTF8CStringSize(property_name); prop = g_alloca(len * sizeof(gchar)); JSStringGetUTF8CString(property_name, prop, len); SEED_NOTE(IMPORTER, "seed_gi_importer_get_property with %s", prop); if (!g_strcmp0(prop, "versions")) return gi_importer_versions; // Nasty hack else if (!g_strcmp0(prop, "toString")) return 0; if (!g_strcmp0(prop, "valueOf")) // HACK return NULL; ret = seed_gi_importer_do_namespace(ctx, prop, exception); SEED_NOTE(IMPORTER, "Result (%p) from attempting to import %s: %s", ret, prop, seed_value_to_string(ctx, ret, exception)); return ret; } gboolean seed_importer_get_file_contents(const gchar* filename, gchar** contents, gsize* length, GError** error) { GBytes* bytes = g_resources_lookup_data(filename, G_RESOURCE_LOOKUP_FLAGS_NONE, NULL); if (bytes) { *contents = g_strdup(g_bytes_get_data(bytes, length)); g_bytes_unref(bytes); return true; } return g_file_get_contents(filename, contents, length, error); } static JSObjectRef seed_make_importer_dir(JSContextRef ctx, gchar* path) { gchar* init; JSObjectRef dir; dir = JSObjectMake(ctx, importer_dir_class, path); init = g_build_filename(path, "__init__.js", NULL); if (seed_file_test(init, G_FILE_TEST_IS_REGULAR)) { SeedScript* s; SEED_NOTE(IMPORTER, "Found __init__.js (%s)", path); s = seed_script_new_from_file(ctx, init); seed_evaluate(ctx, s, dir); seed_script_destroy(s); } g_free(init); return dir; } static void seed_importer_free_search_path(GSList* path) { GSList* walk = path; while (walk) { g_free(walk->data); walk = walk->next; } g_slist_free(path); } GSList* seed_importer_get_search_path(JSContextRef ctx, JSValueRef* exception) { GSList* path = NULL; gchar* entry; JSValueRef search_path_ref, length_ref; guint length, i; search_path_ref = seed_object_get_property(ctx, importer, "searchPath"); if (!JSValueIsObject(ctx, search_path_ref)) { seed_make_exception(ctx, exception, "ArgumentError", "Importer searchPath object is not an array"); return NULL; } length_ref = seed_object_get_property(ctx, (JSObjectRef) search_path_ref, "length"); length = seed_value_to_uint(ctx, length_ref, exception); for (i = 0; i < length; i++) { JSValueRef entry_ref; entry_ref = JSObjectGetPropertyAtIndex(ctx, (JSObjectRef) search_path_ref, i, exception); entry = seed_value_to_string(ctx, entry_ref, exception); if (seed_file_test(entry, G_FILE_TEST_EXISTS) == TRUE) path = g_slist_append(path, entry); else { g_free(entry); } } return path; } /* forward reference */ static JSObjectRef seed_importer_handle_file(JSContextRef ctx, const gchar* dir, const gchar* file, const gchar* module_name, JSValueRef* exception); static JSObjectRef seed_importer_handle_native_module(JSContextRef ctx, const gchar* dir, const gchar* prop, JSValueRef* exception) { GModule* module; JSObjectRef module_obj; SeedModuleInitCallback init; gchar* file_path = g_strconcat(dir, "/libseed_", prop, ".", G_MODULE_SUFFIX, NULL); SEED_NOTE(IMPORTER, "Trying native module: %s", file_path); if ((module_obj = g_hash_table_lookup(file_imports, file_path))) { SEED_NOTE(IMPORTER, "Using existing global"); g_free(file_path); return module_obj; } module = g_module_open(file_path, 0); if (!module) { // Could be a better exception seed_make_exception(ctx, exception, "ModuleError", "Error loading native module at %s: %s", file_path, g_module_error()); g_free(file_path); return NULL; } g_module_symbol(module, "seed_module_init", (gpointer*) &init); module_obj = (*init)(eng); g_hash_table_insert(file_imports, file_path, module_obj); SEED_NOTE(IMPORTER, "Loaded native module"); // protect module_obj since the GC won't find the module in our file_imports // cache JSValueProtect(ctx, module_obj); file_path = g_strconcat("libseed_", prop, ".js", NULL); seed_importer_handle_file(ctx, dir, file_path, prop, exception); g_free(file_path); return module_obj; } static gchar* seed_importer_canonicalize_path(gchar* path) { GFile* file; gchar* absolute_path; file = g_file_new_for_path(path); absolute_path = g_file_get_path(file); g_object_unref(file); return absolute_path; } static JSObjectRef seed_importer_handle_file(JSContextRef ctx, const gchar* dir, const gchar* file, const gchar* module_name, JSValueRef* exception) { JSContextRef nctx; JSValueRef js_file_dirname; JSObjectRef global, c_global; JSStringRef file_contents, file_name; gchar *contents, *walk, *file_path, *canonical, *absolute_path; char* normalized_path; file_path = g_build_filename(dir, file, NULL); canonical = seed_importer_canonicalize_path(file_path); SEED_NOTE(IMPORTER, "Trying to import file: %s", file_path); if ((global = g_hash_table_lookup(file_imports, canonical))) { SEED_NOTE(IMPORTER, "Using existing global"); g_free(file_path); g_free(canonical); return global; } if (!seed_file_test(file_path, G_FILE_TEST_IS_REGULAR)) { if (seed_file_test(file_path, G_FILE_TEST_IS_DIR)) { SEED_NOTE(IMPORTER, "File is directory"); return seed_make_importer_dir(ctx, file_path); } return NULL; } seed_importer_get_file_contents(file_path, &contents, 0, NULL); walk = contents; if (*walk == '#') { while (*walk != '\n') walk++; walk++; } walk = g_strdup(walk); g_free(contents); file_contents = JSStringCreateWithUTF8CString(walk); file_name = JSStringCreateWithUTF8CString(canonical); nctx = JSGlobalContextCreateInGroup(context_group, 0); seed_prepare_global_context(nctx); global = JSContextGetGlobalObject(nctx); c_global = JSContextGetGlobalObject(ctx); JSValueProtect(eng->context, global); absolute_path = g_path_get_dirname(file_path); if (!g_path_is_absolute(absolute_path)) { g_free(absolute_path); absolute_path = g_build_filename(g_get_current_dir(), g_path_get_dirname(file_path), NULL); } normalized_path = realpath(absolute_path, NULL); js_file_dirname = seed_value_from_string(ctx, normalized_path, NULL); seed_object_set_property(nctx, global, "__script_path__", js_file_dirname); g_hash_table_insert(file_imports, canonical, global); g_free(file_path); g_free(absolute_path); g_free(normalized_path); JSEvaluateScript(nctx, file_contents, NULL, file_name, 0, exception); // Does leak...but it's a debug statement. SEED_NOTE(IMPORTER, "Evaluated file, exception: %s", *exception ? seed_exception_to_string(ctx, *exception) : "(null)"); JSGlobalContextRelease((JSGlobalContextRef) nctx); JSStringRelease(file_contents); JSStringRelease(file_name); g_free(walk); return global; } static JSObjectRef seed_importer_try_load(JSContextRef ctx, const gchar* test_path, const gchar* script_path, const gchar* prop, const gchar* prop_as_js, const gchar* prop_as_lib, JSValueRef* exception) { gchar* file_path = NULL; JSObjectRef ret = NULL; // replace '.' with current script_path if not null if (script_path && !g_strcmp0(".", test_path)) test_path = script_path; // check if prop is a file or dir (imports['foo.js'] or imports.mydir) file_path = g_build_filename(test_path, prop, NULL); if (seed_file_test(file_path, G_FILE_TEST_IS_REGULAR | G_FILE_TEST_IS_DIR)) { ret = seed_importer_handle_file(ctx, test_path, prop, prop, exception); goto found; } g_free(file_path); // check if prop is file ending with '.js' file_path = g_build_filename(test_path, prop_as_js, NULL); if (seed_file_test(file_path, G_FILE_TEST_IS_REGULAR)) { ret = seed_importer_handle_file(ctx, test_path, prop_as_js, prop, exception); goto found; } g_free(file_path); // check if file is native module file_path = g_build_filename(test_path, prop_as_lib, NULL); if (seed_file_test(file_path, G_FILE_TEST_IS_REGULAR)) { ret = seed_importer_handle_native_module(ctx, test_path, prop, exception); goto found; } found: if (file_path) g_free(file_path); return ret; } static JSObjectRef seed_importer_search_dirs(JSContextRef ctx, GSList* path, gchar* prop, JSValueRef* exception) { GSList* walk; JSObjectRef ret, global; JSValueRef script_path_prop; gchar *prop_as_lib, *prop_as_js, *script_path; prop_as_lib = g_strconcat("libseed_", prop, ".", G_MODULE_SUFFIX, NULL); prop_as_js = g_strconcat(prop, ".js", NULL); // get the current script_path global = JSContextGetGlobalObject(ctx); script_path_prop = seed_object_get_property(ctx, global, "__script_path__"); if (script_path_prop == NULL || JSValueIsUndefined(ctx, script_path_prop)) script_path = NULL; else script_path = seed_value_to_string(ctx, script_path_prop, exception); ret = NULL; walk = path; while (walk) { gchar* test_path = g_strconcat(walk->data, "/gjs", NULL); ret = seed_importer_try_load(ctx, test_path, script_path, prop, prop_as_js, prop_as_lib, exception); g_free(test_path); walk = walk->next; if (ret) break; } if (!ret) { walk = path; while (walk) { gchar* test_path = walk->data; ret = seed_importer_try_load(ctx, test_path, script_path, prop, prop_as_js, prop_as_lib, exception); walk = walk->next; if (ret) break; } } g_free(prop_as_lib); g_free(prop_as_js); g_free(script_path); return ret; } static JSObjectRef seed_importer_search(JSContextRef ctx, gchar* prop, JSValueRef* exception) { JSObjectRef ret = NULL; GSList* path = seed_importer_get_search_path(ctx, exception); ret = seed_importer_search_dirs(ctx, path, prop, exception); seed_importer_free_search_path(path); return ret; } static JSValueRef seed_importer_get_property(JSContextRef ctx, JSObjectRef object, JSStringRef property_name, JSValueRef* exception) { JSValueRef ret; guint len; gchar* prop; len = JSStringGetMaximumUTF8CStringSize(property_name); prop = g_alloca(len * sizeof(gchar)); JSStringGetUTF8CString(property_name, prop, len); if (!g_strcmp0(prop, "gi")) return gi_importer; if (!g_strcmp0(prop, "searchPath")) return NULL; if (!g_strcmp0(prop, "toString")) // HACK return NULL; ret = seed_importer_search(ctx, prop, exception); return ret; } static JSValueRef seed_importer_dir_get_property(JSContextRef ctx, JSObjectRef object, JSStringRef property_name, JSValueRef* exception) { guint len; gchar* prop; GSList path; path.data = JSObjectGetPrivate(object); path.next = NULL; len = JSStringGetMaximumUTF8CStringSize(property_name); prop = g_alloca(len * sizeof(gchar)); JSStringGetUTF8CString(property_name, prop, len); /* These prevent print(imports.somefile) running "somefile/toString.js" Which is more than a little unexpected.. */ if (!g_strcmp0(prop, "toString")) return NULL; if (!g_strcmp0(prop, "valueOf")) return NULL; return seed_importer_search_dirs(ctx, &path, prop, exception); } static void seed_importer_dir_finalize(JSObjectRef dir) { gchar* dir_path = (gchar*) JSObjectGetPrivate(dir); g_free(dir_path); } void seed_importer_add_global(JSObjectRef global, gchar* name) { JSValueProtect(eng->context, global); g_hash_table_insert(file_imports, seed_importer_canonicalize_path(name), global); } static void seed_importer_dir_enumerate_properties( JSContextRef ctx, JSObjectRef object, JSPropertyNameAccumulatorRef propertyNames) { const gchar* entry; GDir* dir; GError* e = NULL; gchar* path = JSObjectGetPrivate(object); dir = g_dir_open(path, 0, &e); if (e) { SEED_NOTE( IMPORTER, "Error in g_dir_open in seed_importer_enumerate_dir_properties: %s", e->message); g_error_free(e); // Not much we can do here. return; } while ((entry = g_dir_read_name(dir))) { JSStringRef jname; jname = JSStringCreateWithUTF8CString(entry); JSPropertyNameAccumulatorAddName(propertyNames, jname); JSStringRelease(jname); } g_dir_close(dir); } JSObjectRef seed_importer_construct_dir(JSContextRef ctx, JSObjectRef constructor, gsize argumentCount, const JSValueRef arguments[], JSValueRef* exception) { gchar* path; if (argumentCount != 1) { seed_make_exception(ctx, exception, "ArgumentError", "Directory constructor expects 1 argument"); return (JSObjectRef) JSValueMakeUndefined(ctx); } path = seed_value_to_string(ctx, arguments[0], exception); if (!seed_file_test(path, G_FILE_TEST_IS_DIR)) { seed_make_exception(ctx, exception, "ArgumentError", "Path (%s) is not a directory", path); g_free(path); return (JSObjectRef) JSValueMakeUndefined(ctx); } return seed_make_importer_dir(ctx, path); } void seed_importer_set_search_path(JSContextRef ctx, gchar** search_path) { JSObjectRef imports, array; JSValueRef* array_elem; guint length = g_strv_length(search_path), i; array_elem = g_alloca(length * sizeof(array_elem)); imports = (JSObjectRef) seed_object_get_property(ctx, JSContextGetGlobalObject(ctx), "imports"); for (i = 0; i < length; i++) { array_elem[i] = seed_value_from_string(ctx, search_path[i], NULL); } array = JSObjectMakeArray(ctx, length, array_elem, NULL); seed_object_set_property(ctx, imports, "searchPath", array); } void seed_importer_add_search_path(JSContextRef ctx, gchar* search_path) { GSList *paths, *l; GPtrArray* tmp; tmp = g_ptr_array_new(); paths = seed_importer_get_search_path(ctx, NULL); for (l = paths; l != NULL; l = g_slist_next(l)) { g_ptr_array_add(tmp, l->data); } g_ptr_array_add(tmp, search_path); g_ptr_array_add(tmp, NULL); seed_importer_set_search_path(ctx, (gchar**) tmp->pdata); g_ptr_array_unref(tmp); seed_importer_free_search_path(paths); } JSClassDefinition importer_class_def = { 0, /* Version, always 0 */ 0, "importer", /* Class Name */ NULL, /* Parent Class */ NULL, /* Static Values */ NULL, /* Static Functions */ NULL, /* Initialize */ NULL, /* Finalize */ NULL, /* Has Property */ seed_importer_get_property, /* Get Property */ NULL, /* Set Property */ NULL, /* Delete Property */ NULL, /* Get Property Names */ NULL, /* Call As Function */ NULL, /* Call As Constructor */ NULL, /* Has Instance */ NULL /* Convert To Type */ }; JSClassDefinition gi_importer_class_def = { 0, /* Version, always 0 */ 0, "gi_importer", /* Class Name */ NULL, /* Parent Class */ NULL, /* Static Values */ NULL, /* Static Functions */ NULL, /* Initialize */ NULL, /* Finalize */ NULL, /* Has Property */ seed_gi_importer_get_property, /* Get Property */ NULL, /* Set Property */ NULL, /* Delete Property */ NULL, /* Get Property Names */ NULL, /* Call As Function */ NULL, /* Call As Constructor */ NULL, /* Has Instance */ NULL /* Convert To Type */ }; JSClassDefinition importer_dir_class_def = { 0, /* Version, always 0 */ 0, "importer_dir", /* Class Name */ NULL, /* Parent Class */ NULL, /* Static Values */ NULL, /* Static Functions */ NULL, /* Initialize */ seed_importer_dir_finalize, /* Finalize */ NULL, /* Has Property */ seed_importer_dir_get_property, /* Get Property */ NULL, /* Set Property */ NULL, /* Delete Property */ seed_importer_dir_enumerate_properties, /* Get Property Names */ NULL, /* Call As Function */ NULL, /* Call As Constructor */ NULL, /* Has Instance */ NULL /* Convert To Type */ }; extern GResource* libseed_get_resource(void); void seed_initialize_importer(JSContextRef ctx, JSObjectRef global) { JSObjectRef dir_constructor; JSObjectRef imports, array; importer_class = JSClassCreate(&importer_class_def); importer = JSObjectMake(ctx, importer_class, NULL); gi_importer_class = JSClassCreate(&gi_importer_class_def); gi_importer = JSObjectMake(ctx, gi_importer_class, NULL); gi_importer_versions = JSObjectMake(ctx, NULL, NULL); JSValueProtect(ctx, gi_importer); JSValueProtect(ctx, gi_importer_versions); importer_dir_class = JSClassCreate(&importer_dir_class_def); gi_imports = g_hash_table_new(g_str_hash, g_str_equal); file_imports = g_hash_table_new(g_str_hash, g_str_equal); /* Passing nonnull for class requires a webkit fix that most people wont * have yet. It also has minimal benefit */ // dir_constructor = JSObjectMakeConstructor (ctx, importer_dir_class, // seed_importer_construct_dir); dir_constructor = JSObjectMakeConstructor(ctx, NULL, seed_importer_construct_dir); seed_object_set_property(ctx, importer, "Directory", dir_constructor); seed_object_set_property(ctx, global, "imports", importer); imports = (JSObjectRef) seed_object_get_property(ctx, global, "imports"); array = JSObjectMakeArray(ctx, 0, NULL, NULL); seed_object_set_property(ctx, imports, "searchPath", array); } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/libseed/seed-importer.h000066400000000000000000000026731303774616400231750ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #ifndef _SEED_IMPORTER_H #define _SEED_IMPORTER_H #include "seed-private.h" extern JSObjectRef importer; void seed_initialize_importer(JSContextRef ctx, JSObjectRef global); JSObjectRef seed_gi_importer_do_namespace(JSContextRef ctx, gchar* namespace, JSValueRef* exception); gboolean seed_importer_get_file_contents(const gchar* filename, gchar** contents, gsize* length, GError** error); #endif seed-webkit2-4.0.0+20161014+6c77960+dfsg1/libseed/seed-module.h000066400000000000000000000071121303774616400226120ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #ifndef _SEED_MODULE_H_ #define _SEED_MODULE_H_ #include "../libseed/seed.h" // TODO: Move [example sqlite canvas Multiprocessing // os sandbox dbus libxml cairo] // towards utilization of this header. /** * CHECK_ARG_COUNT: * @name: The name of the function being called from, pretty-printed * @argnum: The number of arguments which should be passed into the function * * Check that the required number of arguments were passed into a * #SeedFunctionCallback. If this is not true, raise an exception and * return %NULL. This requires the callback to use "argument_count", * "ctx", and "exception" as the names of the various function arguments. * * @name should be of form "namespace.function_name" * * At the moment, there is no way to specify more than one acceptable * argument count. * */ #define CHECK_ARG_COUNT(name, argnum) \ if (argument_count != argnum) { \ seed_make_exception(ctx, exception, "ArgumentError", \ "wrong number of arguments; expected %s, got %zd", \ #argnum, argument_count); \ return seed_make_undefined(ctx); \ } /** * DEFINE_ENUM_MEMBER: * @holder: The object on which to define the enum member * @member: The enum member, as it is named in C * * Defines a property on @holder which is named the same as @member, and * is assigned the value that @member has in C. * * This macro works for defining properties from constants and * #defines as well. * */ #define DEFINE_ENUM_MEMBER(holder, member) \ seed_object_set_property(ctx, holder, #member, \ seed_value_from_long(ctx, member, NULL)) /** * DEFINE_ENUM_MEMBER_EXT: * @holder: The object on which to define the enum member * @name: The enum member, as it should be named in JavaScript * @val: The enum member, as it is named in C * * Defines a property on @holder which is named @name, and is assigned the * value that @member has in C. This allows for an override of the enum * member's name, most often to remove a common prefix. For example, to declare * a property named VERSION_MAJOR on the namespace from mfpr's version * constant MPFR_VERSION_MAJOR: * * * DEFINE_ENUM_MEMBER_EXT(ns, "VERSION_MAJOR", MPFR_VERSION_MAJOR); * * */ #define DEFINE_ENUM_MEMBER_EXT(holder, name, val) \ seed_object_set_property(ctx, holder, name, \ seed_value_from_long(ctx, val, NULL)) #endif seed-webkit2-4.0.0+20161014+6c77960+dfsg1/libseed/seed-path.h.in000066400000000000000000000001041303774616400226600ustar00rootroot00000000000000#define SEED_PREFIX_PATH "@prefix@""/share/seed@SEED_GTK_VERSION@/" seed-webkit2-4.0.0+20161014+6c77960+dfsg1/libseed/seed-private.h000066400000000000000000000031511303774616400227760ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #ifndef _SEED_PRIVATE_H #define _SEED_PRIVATE_H #include #include #include #include #include #include #include #include #include #include typedef struct _SeedEngine SeedEngine; struct _SeedEngine { JSGlobalContextRef context; JSObjectRef global; gchar** search_path; JSContextGroupRef group; gchar* program_name; gboolean importer_initialized; }; #include "seed-debug.h" #include "seed-engine.h" #include "seed-types.h" #include "seed-signals.h" #include "seed-builtins.h" #include "seed-structs.h" #include "seed-closure.h" #include "seed-gtype.h" #include "seed-exceptions.h" #include "seed-importer.h" #endif seed-webkit2-4.0.0+20161014+6c77960+dfsg1/libseed/seed-signals.c000066400000000000000000000350211303774616400227600ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* vim: set sw=2 ts=2 sts=2 et: */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #include "seed-private.h" typedef struct _signal_privates { GObject* object; gchar* signal_name; } signal_privates; JSClassRef signal_holder_class; static void seed_signal_finalize(JSObjectRef object) { signal_privates* sig_priv = JSObjectGetPrivate(object); g_free(sig_priv->signal_name); g_slice_free1(sizeof(signal_privates), sig_priv); } gulong seed_gobject_signal_connect(JSContextRef ctx, const gchar* signal_name, GObject* on_obj, JSObjectRef func, JSObjectRef this_obj, JSObjectRef user_data) { GSignalQuery query; GClosure* closure; if (g_str_has_prefix(signal_name, "notify::")) g_signal_query(g_signal_lookup("notify", G_OBJECT_TYPE(on_obj)), &query); else g_signal_query(g_signal_lookup(signal_name, G_OBJECT_TYPE(on_obj)), &query); #ifdef SEED_ENABLE_DEBUG { guint function_arity = seed_value_to_uint(ctx, seed_object_get_property(ctx, func, "length"), NULL); if (function_arity != query.n_params) { SEED_MARK(); SEED_NOTE( SIGNAL, "Connecting signal: %s. Function has arity %d, signal expects %d", query.signal_name, function_arity, query.n_params); SEED_MARK(); } } #endif closure = seed_closure_new_for_signal(ctx, func, user_data, "signal handler", query.signal_id); // This seems wrong... ((SeedClosure*) closure)->return_type = query.return_type; return g_signal_connect_closure(on_obj, signal_name, closure, FALSE); } JSValueRef seed_gobject_signal_connect_by_name(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { JSObjectRef user_data = NULL; gchar* signal_name; GObject* obj; gulong id; if (argumentCount < 2 || argumentCount > 3) { seed_make_exception(ctx, exception, "ArgumentError", "Signal connection expected" " 2 or 3 arguments. Got " "%zd", argumentCount); return JSValueMakeNull(ctx); } if (JSValueIsNull(ctx, arguments[1]) || !JSValueIsObject(ctx, arguments[1]) || !JSObjectIsFunction(ctx, (JSObjectRef) arguments[1])) { seed_make_exception(ctx, exception, "ArgumentError", "Signal connection by name " "requires a function" " as second argument"); return JSValueMakeNull(ctx); } if (argumentCount == 3) { user_data = (JSObjectRef) arguments[2]; } signal_name = seed_value_to_string(ctx, arguments[0], exception); obj = (GObject*) JSObjectGetPrivate(thisObject); id = seed_gobject_signal_connect(ctx, signal_name, obj, (JSObjectRef) arguments[1], NULL, user_data); g_free(signal_name); return seed_value_from_ulong(ctx, id, exception); } void seed_add_signals_to_object(JSContextRef ctx, JSObjectRef object_ref, GObject* obj) { g_assert(obj); JSObjectRef signals_ref; signals_ref = JSObjectMake(ctx, signal_holder_class, obj); seed_object_set_property(ctx, object_ref, "signal", signals_ref); } void seed_signal_marshal_func(GClosure* closure, GValue* return_value, guint n_param_values, const GValue* param_values, gpointer invocation_hint, gpointer marshal_data) { SeedClosure* seed_closure = (SeedClosure*) closure; JSValueRef *args, exception = 0; JSValueRef ret = 0; guint i; gchar* mes; GSignalQuery signal_query = { 0, }; if (marshal_data) { /* Inspired from gjs/gi/value.c:closure_marshal() */ /* we are used for a signal handler */ guint signal_id; signal_id = GPOINTER_TO_UINT(marshal_data); g_signal_query(signal_id, &signal_query); if (!signal_query.signal_id) g_error("Signal handler being called on invalid signal"); if (signal_query.n_params + 1 != n_param_values) g_error( "Signal handler being called with wrong number of parameters"); } JSContextRef ctx = JSGlobalContextCreateInGroup(context_group, 0); seed_prepare_global_context(ctx); SEED_NOTE(INVOCATION, "Signal Marshal: "); args = g_newa(JSValueRef, n_param_values + 1); for (i = 0; i < n_param_values; i++) { args[i] = seed_value_from_gvalue_for_signal(ctx, (GValue*) ¶m_values[i], 0, &signal_query, i); if (!args[i]) g_error("Error in signal marshal. " "Unable to convert argument of type: %s \n", g_type_name(param_values[i].g_type)); } if (seed_closure->user_data) args[i] = seed_closure->user_data; else args[i] = JSValueMakeNull(ctx); ret = JSObjectCallAsFunction(ctx, seed_closure->function, NULL, n_param_values + 1, args, &exception); if (exception) { seed_closure_warn_exception(closure, ctx, exception); exception = NULL; } if (ret && !JSValueIsNull(ctx, ret) && (seed_closure->return_type != G_TYPE_NONE)) { seed_value_to_gvalue(ctx, ret, seed_closure->return_type, return_value, &exception); } if (exception) { mes = seed_exception_to_string(ctx, exception); g_warning("Exception in signal handler return value. %s \n", mes); g_free(mes); } JSGlobalContextRelease((JSGlobalContextRef) ctx); JSGarbageCollect(ctx); } static JSValueRef seed_gobject_signal_emit(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { JSValueRef ret; GValue* params; GValue ret_value = { 0 }; GSignalQuery query; signal_privates* privates; guint i, signal_id; privates = JSObjectGetPrivate(thisObject); signal_id = g_signal_lookup(privates->signal_name, G_OBJECT_TYPE(privates->object)); g_signal_query(signal_id, &query); if (argumentCount != query.n_params) { seed_make_exception(ctx, exception, "ArgumentError", "Signal: %s for type %s expected %u " "arguments, got %zd", query.signal_name, g_type_name(query.itype), query.n_params, argumentCount); return JSValueMakeNull(ctx); } params = g_new0(GValue, argumentCount + 1); g_value_init(¶ms[0], G_TYPE_OBJECT); g_value_set_object(¶ms[0], privates->object); for (i = 0; i < argumentCount; i++) seed_value_to_gvalue(ctx, arguments[i], query.param_types[i], ¶ms[i + 1], exception); if (query.return_type != G_TYPE_NONE) g_value_init(&ret_value, query.return_type); g_signal_emitv(params, signal_id, 0, &ret_value); for (i = 0; i < argumentCount; i++) g_value_unset(¶ms[i]); g_free(params); ret = seed_value_from_gvalue(ctx, &ret_value, exception); if (query.return_type != G_TYPE_NONE) g_value_unset(&ret_value); return ret; } static JSValueRef seed_gobject_signal_disconnect(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { gulong id; if (argumentCount != 1) { seed_make_exception(ctx, exception, "ArgumentError", "Signal disconnection expects 1 argument" " got %zd", argumentCount); return JSValueMakeUndefined(ctx); } id = seed_value_to_ulong(ctx, arguments[0], exception); g_signal_handler_disconnect(JSObjectGetPrivate(thisObject), id); return JSValueMakeUndefined(ctx); } static JSValueRef seed_gobject_signal_connect_on_property(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { gulong id = 0; JSObjectRef this_obj; signal_privates* privates; privates = (signal_privates*) JSObjectGetPrivate(thisObject); if (!privates) g_error("Signal constructed with invalid parameters" "in namespace import \n"); this_obj = (JSObjectRef) seed_value_from_object(ctx, privates->object, exception); if ((argumentCount > 2) || (argumentCount == 0)) { seed_make_exception(ctx, exception, "ArgumentError", "Signal connection expected" " 1, or 2 arguments. Got " "%zd", argumentCount); return JSValueMakeNull(ctx); } if (JSValueIsNull(ctx, arguments[0]) || !JSValueIsObject(ctx, arguments[0]) || !JSObjectIsFunction(ctx, (JSObjectRef) arguments[0])) { seed_make_exception(ctx, exception, "ArgumentError", "Signal connection requires a function" " as first argument"); return JSValueMakeNull(ctx); } if (argumentCount == 1) { id = seed_gobject_signal_connect(ctx, privates->signal_name, privates->object, (JSObjectRef) arguments[0], this_obj, NULL); } else if (argumentCount == 2) { id = seed_gobject_signal_connect(ctx, privates->signal_name, privates->object, (JSObjectRef) arguments[0], this_obj, (JSObjectRef) arguments[1]); } return seed_value_from_ulong(ctx, id, exception); } JSStaticFunction signal_static_functions[] = { { "connect", seed_gobject_signal_connect_on_property, 0 }, { "emit", seed_gobject_signal_emit, 0 }, { 0, 0, 0 } }; JSStaticFunction signal_holder_static_functions[] = { { "connect", seed_gobject_signal_connect_by_name, 0 }, { "disconnect", seed_gobject_signal_disconnect, 0 }, { 0, 0, 0 } }; JSClassDefinition gobject_signal_def = { 0, /* Version, always 0 */ kJSClassAttributeNoAutomaticPrototype, "gobject_signal", /* Class Name */ NULL, /* Parent Class */ NULL, /* Static Values */ signal_static_functions, /* Static Functions */ NULL, seed_signal_finalize, /* Finalize */ NULL, /* Has Property */ NULL, /* Get Property */ NULL, /* Set Property */ NULL, /* Delete Property */ NULL, /* Get Property Names */ NULL, /* Call As Function */ NULL, /* Call As Constructor */ NULL, /* Has Instance */ NULL /* Convert To Type */ }; static JSValueRef seed_signal_holder_get_property(JSContextRef ctx, JSObjectRef object, JSStringRef property_name, JSValueRef* exception) { GObject* gobj = JSObjectGetPrivate(object); signal_privates* priv; guint length = JSStringGetMaximumUTF8CStringSize(property_name); gchar* signal_name = g_malloc(length * sizeof(gchar)); JSObjectRef signal_ref; JSStringGetUTF8CString(property_name, signal_name, length); if (!(g_strcmp0(signal_name, "connect") && g_strcmp0(signal_name, "disconnect"))) { g_free(signal_name); return NULL; } if (!g_str_has_prefix(signal_name, "notify::") && !g_signal_lookup(signal_name, G_OBJECT_TYPE(gobj))) { seed_make_exception(ctx, exception, "InvalidSignalName", "Failed to connect to %s. " "Invalid signal name.", signal_name); g_free(signal_name); return NULL; } priv = g_slice_alloc(sizeof(signal_privates)); priv->object = gobj; priv->signal_name = signal_name; signal_ref = JSObjectMake(ctx, gobject_signal_class, priv); return signal_ref; } JSClassDefinition* seed_get_signal_class(void) { JSClassDefinition signal_holder = kJSClassDefinitionEmpty; signal_holder.className = "gobject_signals"; signal_holder.getProperty = seed_signal_holder_get_property; signal_holder.staticFunctions = signal_holder_static_functions; signal_holder_class = JSClassCreate(&signal_holder); JSClassRetain(signal_holder_class); return &gobject_signal_def; } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/libseed/seed-signals.h000066400000000000000000000043321303774616400227660ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #ifndef _SEED_SIGNALS_H #define _SEED_SIGNALS_H #include "seed-private.h" void seed_signal_marshal_func(GClosure* closure, GValue* return_value, guint n_param_values, const GValue* param_values, gpointer invocation_hint, gpointer marshall_data); void seed_add_signals_to_object(JSContextRef ctx, JSObjectRef object_ref, GObject* obj); gulong seed_gobject_signal_connect(JSContextRef ctx, const gchar* signal_name, GObject* on_obj, JSObjectRef func, JSObjectRef this_obj, JSObjectRef user_data); JSValueRef seed_gobject_signal_connect_by_name(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception); JSClassDefinition* seed_get_signal_class(void); extern JSClassRef gobject_signal_class; #endif seed-webkit2-4.0.0+20161014+6c77960+dfsg1/libseed/seed-structs.c000066400000000000000000000570051303774616400230350ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #include "seed-private.h" JSClassRef seed_struct_class = 0; JSClassRef seed_union_class = 0; JSClassRef seed_pointer_class = 0; JSClassRef seed_boxed_class = 0; typedef struct _seed_struct_privates { gpointer pointer; GIBaseInfo* info; gboolean free_pointer; gboolean slice_alloc; gsize size; } seed_struct_privates; GHashTable* struct_prototype_hash = NULL; GHashTable* union_prototype_hash = NULL; static void seed_pointer_finalize(JSObjectRef object) { seed_struct_privates* priv = (seed_struct_privates*) JSObjectGetPrivate(object); SEED_NOTE(STRUCTS, "Finalizing seed_pointer object %p. with " "priv->free_pointer = %d with type: %s, size: %zu", priv->pointer, priv->free_pointer, priv->info ? g_base_info_get_name(priv->info) : "[generic]", priv->size); if (priv->free_pointer) { if (priv->slice_alloc) g_slice_free1(priv->size, priv->pointer); else g_free(priv->pointer); } if (priv->info) g_base_info_unref(priv->info); g_slice_free1(sizeof(seed_struct_privates), priv); } static void seed_boxed_finalize(JSObjectRef object) { seed_struct_privates* priv = (seed_struct_privates*) JSObjectGetPrivate(object); GType type; GIRegisteredTypeInfo* info = (GIRegisteredTypeInfo*) g_base_info_get_type(priv->info); SEED_NOTE(STRUCTS, "Finalizing boxed object of type %s \n", g_base_info_get_name(priv->info)); type = g_registered_type_info_get_g_type(info); g_base_info_unref((GIBaseInfo*) info); g_boxed_free(type, priv->pointer); } GIFieldInfo* seed_union_find_field(GIUnionInfo* info, gchar* field_name) { gint n, i; GIFieldInfo* field; n = g_union_info_get_n_fields(info); for (i = 0; i < n; i++) { const gchar* name; field = g_union_info_get_field(info, i); name = g_base_info_get_name((GIBaseInfo*) field); if (!g_strcmp0(name, field_name)) return field; else g_base_info_unref((GIBaseInfo*) field); } return NULL; } GIFieldInfo* seed_struct_find_field(GIStructInfo* info, gchar* field_name) { gint n, i; const gchar* name; GIFieldInfo* field; n = g_struct_info_get_n_fields(info); for (i = 0; i < n; i++) { field = g_struct_info_get_field(info, i); name = g_base_info_get_name((GIBaseInfo*) field); if (!g_strcmp0(name, field_name)) return field; else g_base_info_unref((GIBaseInfo*) field); } return NULL; } JSValueRef seed_field_get_value(JSContextRef ctx, gpointer object, GIFieldInfo* field, JSValueRef* exception) { GITypeInfo* field_type; GIBaseInfo* interface; GArgument field_value; JSValueRef ret = JSValueMakeNull(ctx); gint offset; field_type = g_field_info_get_type(field); if (!g_field_info_get_field(field, object, &field_value)) { GITypeTag tag; tag = g_type_info_get_tag(field_type); if (tag == GI_TYPE_TAG_INTERFACE) { interface = g_type_info_get_interface(field_type); offset = g_field_info_get_offset(field); g_base_info_unref((GIBaseInfo*) field_type); switch (g_base_info_get_type(interface)) { case GI_INFO_TYPE_STRUCT: ret = seed_make_struct(ctx, (object + offset), interface); break; case GI_INFO_TYPE_UNION: ret = seed_make_union(ctx, (object + offset), interface); break; case GI_INFO_TYPE_BOXED: ret = seed_make_boxed(ctx, (object + offset), interface); break; default: break; } g_base_info_unref(interface); return ret; } return JSValueMakeNull(ctx); } // Maybe need to release argument. ret = seed_value_from_gi_argument(ctx, &field_value, field_type, exception); if (field_type) g_base_info_unref((GIBaseInfo*) field_type); return ret; } static JSValueRef seed_union_get_property(JSContextRef context, JSObjectRef object, JSStringRef property_name, JSValueRef* exception) { gchar* cproperty_name; gsize length; seed_struct_privates* priv = JSObjectGetPrivate(object); GIFieldInfo* field = 0; JSValueRef ret; length = JSStringGetMaximumUTF8CStringSize(property_name); cproperty_name = g_alloca(length * sizeof(gchar)); JSStringGetUTF8CString(property_name, cproperty_name, length); SEED_NOTE(STRUCTS, "Getting property on union of type: %s " "with name %s \n", g_base_info_get_name(priv->info), cproperty_name); field = seed_union_find_field((GIUnionInfo*) priv->info, cproperty_name); if (!field) { return 0; } ret = seed_field_get_value(context, priv->pointer, field, exception); g_base_info_unref((GIBaseInfo*) field); return ret; } static bool seed_union_set_property(JSContextRef context, JSObjectRef object, JSStringRef property_name, JSValueRef value, JSValueRef* exception) { gsize length; GArgument field_value; GIFieldInfo* field; gchar* cproperty_name; GITypeInfo* field_type; seed_struct_privates* priv = (seed_struct_privates*) JSObjectGetPrivate(object); gboolean ret; length = JSStringGetMaximumUTF8CStringSize(property_name); cproperty_name = g_alloca(length * sizeof(gchar)); JSStringGetUTF8CString(property_name, cproperty_name, length); SEED_NOTE(STRUCTS, "Setting property on union of type: %s " "with name %s \n", g_base_info_get_name(priv->info), cproperty_name); field = seed_union_find_field((GIUnionInfo*) priv->info, cproperty_name); if (!field) { return FALSE; } field_type = g_field_info_get_type(field); seed_value_to_gi_argument(context, value, field_type, GI_TRANSFER_NOTHING, &field_value, exception); ret = g_field_info_set_field(field, priv->pointer, &field_value); if (!ret) g_warning("Setting property failed on union of type: %s " "with name %s \n", g_base_info_get_name(priv->info), cproperty_name); g_base_info_unref((GIBaseInfo*) field_type); g_base_info_unref((GIBaseInfo*) field); return TRUE; } static bool seed_struct_set_property(JSContextRef context, JSObjectRef object, JSStringRef property_name, JSValueRef value, JSValueRef* exception) { gsize length; GArgument field_value; GIFieldInfo* field; gchar* cproperty_name; GITypeInfo* field_type; seed_struct_privates* priv = (seed_struct_privates*) JSObjectGetPrivate(object); gboolean ret; length = JSStringGetMaximumUTF8CStringSize(property_name); cproperty_name = g_alloca(length * sizeof(gchar)); JSStringGetUTF8CString(property_name, cproperty_name, length); SEED_NOTE(STRUCTS, "Setting property on struct of type: %s " "with name %s \n", g_base_info_get_name(priv->info), cproperty_name); field = seed_struct_find_field((GIStructInfo*) priv->info, cproperty_name); if (!field) { return FALSE; } field_type = g_field_info_get_type(field); seed_value_to_gi_argument(context, value, field_type, GI_TRANSFER_NOTHING, &field_value, exception); ret = g_field_info_set_field(field, priv->pointer, &field_value); if (!ret) g_warning("Setting property failed on struct of type: %s " "with name %s \n", g_base_info_get_name(priv->info), cproperty_name); g_base_info_unref((GIBaseInfo*) field_type); g_base_info_unref((GIBaseInfo*) field); return TRUE; } static JSValueRef seed_struct_get_property(JSContextRef context, JSObjectRef object, JSStringRef property_name, JSValueRef* exception) { gchar* cproperty_name; gsize length; seed_struct_privates* priv = JSObjectGetPrivate(object); GIFieldInfo* field = NULL; JSValueRef ret; length = JSStringGetMaximumUTF8CStringSize(property_name); cproperty_name = g_alloca(length * sizeof(gchar)); JSStringGetUTF8CString(property_name, cproperty_name, length); SEED_NOTE(STRUCTS, "Getting property on struct of type: %s " "with name %s \n", g_base_info_get_name(priv->info), cproperty_name); // for a gvalue, it has a special property 'value' (read-only) GType gtype = g_registered_type_info_get_g_type((GIRegisteredTypeInfo*) priv->info); if (g_type_is_a(gtype, G_TYPE_VALUE) && !g_strcmp0(cproperty_name, "value")) { return seed_value_from_gvalue(context, (GValue*) priv->pointer, exception); } field = seed_struct_find_field((GIStructInfo*) priv->info, cproperty_name); if (!field) { return NULL; } ret = seed_field_get_value(context, priv->pointer, field, exception); g_base_info_unref((GIBaseInfo*) field); return ret; } static void seed_enumerate_structlike_properties(JSContextRef ctx, JSObjectRef object, JSPropertyNameAccumulatorRef propertyNames) { GIFieldInfo* field; gint i, n; guchar type = 0; seed_struct_privates* priv = (seed_struct_privates*) JSObjectGetPrivate(object); GIBaseInfo* info = priv->info; if (!info) return; if (JSValueIsObjectOfClass(ctx, object, seed_struct_class)) type = 1; else if (JSValueIsObjectOfClass(ctx, object, seed_union_class)) type = 2; else g_assert_not_reached(); (type == 1) ? (n = g_struct_info_get_n_fields((GIStructInfo*) info)) : (n = g_union_info_get_n_fields((GIUnionInfo*) info)); for (i = 0; i < n; i++) { JSStringRef jname; (type == 1) ? (field = g_struct_info_get_field((GIStructInfo*) info, i)) : (field = g_union_info_get_field((GIUnionInfo*) info, i)); jname = JSStringCreateWithUTF8CString( g_base_info_get_name((GIBaseInfo*) field)); g_base_info_unref((GIBaseInfo*) field); JSPropertyNameAccumulatorAddName(propertyNames, jname); JSStringRelease(jname); } } JSClassDefinition seed_pointer_def = { 0, /* Version, always 0 */ 0, "seed_pointer", /* Class Name */ NULL, /* Parent Class */ NULL, /* Static Values */ NULL, /* Static Functions */ NULL, seed_pointer_finalize, NULL, /* Has Property */ 0, NULL, /* Set Property */ NULL, /* Delete Property */ NULL, NULL, /* Call As Function */ NULL, /* Call As Constructor */ NULL, /* Has Instance */ NULL /* Convert To Type */ }; JSClassDefinition seed_struct_def = { 0, /* Version, always 0 */ kJSClassAttributeNoAutomaticPrototype, "seed_struct", /* Class Name */ NULL, /* Parent Class */ NULL, /* Static Values */ NULL, /* Static Functions */ NULL, NULL, NULL, /* Has Property */ seed_struct_get_property, seed_struct_set_property, /* Set Property */ NULL, /* Delete Property */ seed_enumerate_structlike_properties, /* Get Property Names */ NULL, /* Call As Function */ NULL, /* Call As Constructor */ NULL, /* Has Instance */ NULL /* Convert To Type */ }; JSClassDefinition seed_union_def = { 0, /* Version, always 0 */ kJSClassAttributeNoAutomaticPrototype, "seed_union", /* Class Name */ NULL, /* Parent Class */ NULL, /* Static Values */ NULL, /* Static Functions */ NULL, NULL, NULL, /* Has Property */ seed_union_get_property, seed_union_set_property, /* Set Property */ NULL, /* Delete Property */ seed_enumerate_structlike_properties, /* Get Property Names */ NULL, /* Call As Function */ NULL, /* Call As Constructor */ NULL, /* Has Instance */ NULL /* Convert To Type */ }; JSClassDefinition seed_boxed_def = { 0, /* Version, always 0 */ kJSClassAttributeNoAutomaticPrototype, "seed_boxed", /* Class Name */ NULL, /* Parent Class */ NULL, /* Static Values */ NULL, /* Static Functions */ NULL, seed_boxed_finalize, NULL, /* Has Property */ NULL, NULL, /* Set Property */ NULL, /* Delete Property */ NULL, /* Get Property Names */ NULL, /* Call As Function */ NULL, /* Call As Constructor */ NULL, /* Has Instance */ NULL /* Convert To Type */ }; gpointer seed_pointer_get_pointer(JSContextRef ctx, JSValueRef pointer) { if (JSValueIsObjectOfClass(ctx, pointer, seed_pointer_class)) { seed_struct_privates* priv = JSObjectGetPrivate((JSObjectRef) pointer); return priv->pointer; } return NULL; } void seed_pointer_set_free(JSContextRef ctx, JSValueRef pointer, gboolean free_pointer) { if (JSValueIsObjectOfClass(ctx, pointer, seed_pointer_class)) { seed_struct_privates* priv = JSObjectGetPrivate((JSObjectRef) pointer); priv->free_pointer = free_pointer; } } static void seed_pointer_set_slice(JSContextRef ctx, JSValueRef pointer, gboolean free_pointer, gsize size) { seed_struct_privates* priv = JSObjectGetPrivate((JSObjectRef) pointer); priv->slice_alloc = free_pointer; priv->size = size; } JSObjectRef seed_make_pointer(JSContextRef ctx, gpointer pointer) { seed_struct_privates* priv = g_slice_alloc(sizeof(seed_struct_privates)); priv->pointer = pointer; priv->info = 0; priv->free_pointer = FALSE; return JSObjectMake(ctx, seed_pointer_class, priv); } JSObjectRef seed_union_prototype(JSContextRef ctx, GIBaseInfo* info) { JSObjectRef proto; const gchar* namespace, *name; gchar* key; gint n_methods, i; GIFunctionInfo* finfo; name = g_base_info_get_name(info); namespace = g_base_info_get_namespace(info); key = g_strjoin(NULL, namespace, name, NULL); proto = (JSObjectRef) g_hash_table_lookup(union_prototype_hash, key); if (!proto) { proto = JSObjectMake(ctx, 0, 0); JSValueProtect(eng->context, proto); n_methods = g_union_info_get_n_methods((GIUnionInfo*) info); for (i = 0; i < n_methods; i++) { finfo = g_union_info_get_method((GIUnionInfo*) info, i); seed_gobject_define_property_from_function_info( ctx, (GIFunctionInfo*) finfo, proto, TRUE); g_base_info_unref((GIBaseInfo*) finfo); } g_hash_table_insert(union_prototype_hash, key, proto); } else { g_free(key); } return proto; } JSObjectRef seed_make_union(JSContextRef ctx, gpointer younion, GIBaseInfo* info) { JSObjectRef object; if (younion == NULL) { return (JSObjectRef) JSValueMakeNull(ctx); } seed_struct_privates* priv = g_slice_alloc(sizeof(seed_struct_privates)); priv->pointer = younion; priv->info = info ? g_base_info_ref(info) : 0; priv->free_pointer = FALSE; object = JSObjectMake(ctx, seed_union_class, priv); if (info) { JSObjectRef proto = seed_union_prototype(ctx, info); if (proto) JSObjectSetPrototype(ctx, object, proto); else g_assert_not_reached(); } return object; } JSObjectRef seed_make_boxed(JSContextRef ctx, gpointer boxed, GIBaseInfo* info) { JSObjectRef object; seed_struct_privates* priv = g_slice_alloc(sizeof(seed_struct_privates)); priv->info = info ? g_base_info_ref(info) : 0; priv->pointer = boxed; // Boxed finalize handler handles freeing. priv->free_pointer = FALSE; object = JSObjectMake(ctx, seed_boxed_class, priv); // FIXME: Instance methods? return object; } JSObjectRef seed_struct_prototype(JSContextRef ctx, GIBaseInfo* info) { JSObjectRef proto; const gchar* namespace, *name; gchar* key; gint n_methods, i; name = g_base_info_get_name(info); namespace = g_base_info_get_namespace(info); key = g_strjoin(NULL, namespace, name, NULL); proto = (JSObjectRef) g_hash_table_lookup(struct_prototype_hash, key); if (!proto) { proto = JSObjectMake(ctx, 0, 0); JSValueProtect(eng->context, proto); n_methods = g_struct_info_get_n_methods((GIStructInfo*) info); for (i = 0; i < n_methods; i++) { GIFunctionInfo* finfo; finfo = g_struct_info_get_method((GIStructInfo*) info, i); seed_gobject_define_property_from_function_info( ctx, (GIFunctionInfo*) finfo, proto, TRUE); g_base_info_unref((GIBaseInfo*) finfo); } g_hash_table_insert(struct_prototype_hash, key, proto); } else { g_free(key); } return proto; } JSObjectRef seed_make_struct(JSContextRef ctx, gpointer strukt, GIBaseInfo* info) { JSObjectRef object, proto; if (strukt == NULL) { return (JSObjectRef) JSValueMakeNull(ctx); } seed_struct_privates* priv = g_slice_alloc(sizeof(seed_struct_privates)); priv->info = info ? g_base_info_ref(info) : 0; priv->pointer = strukt; priv->free_pointer = FALSE; object = JSObjectMake(ctx, seed_struct_class, priv); // Examine cases where struct is being used without info. if (info) { proto = seed_struct_prototype(ctx, info); if (proto) JSObjectSetPrototype(ctx, object, proto); else g_assert_not_reached(); } return object; } void seed_structs_init(void) { seed_pointer_class = JSClassCreate(&seed_pointer_def); seed_struct_def.parentClass = seed_pointer_class; seed_struct_class = JSClassCreate(&seed_struct_def); seed_union_def.parentClass = seed_pointer_class; seed_union_class = JSClassCreate(&seed_union_def); seed_boxed_def.parentClass = seed_struct_class; seed_boxed_class = JSClassCreate(&seed_boxed_def); struct_prototype_hash = g_hash_table_new(g_str_hash, g_str_equal); union_prototype_hash = g_hash_table_new(g_str_hash, g_str_equal); } JSObjectRef seed_construct_struct_type_with_parameters(JSContextRef ctx, GIBaseInfo* info, JSObjectRef parameters, JSValueRef* exception) { gsize size = 0; gpointer object; GIInfoType type = g_base_info_get_type(info); JSObjectRef ret; gboolean set_ret; gint nparams, i = 0; gsize length; GIFieldInfo* field = 0; JSPropertyNameArrayRef jsprops; JSStringRef jsprop_name; JSValueRef jsprop_value; GArgument field_value; gchar* prop_name; GITypeInfo* field_type; if (type == GI_INFO_TYPE_STRUCT) { GType gtype = g_registered_type_info_get_g_type((GIRegisteredTypeInfo*) info); if (g_type_is_a(gtype, G_TYPE_VALUE)) { GValue* gval = g_slice_alloc0(sizeof(GValue)); if (!parameters) { seed_make_exception(ctx, exception, "ArgumentError", "Missing Type in GValue constructor"); return (JSObjectRef) JSValueMakeNull(ctx); } SEED_NOTE(CONSTRUCTION, "Created a GValue struct"); seed_value_to_gvalue(ctx, parameters, 0, gval, exception); ret = seed_make_struct(ctx, (gpointer) gval, info); return ret; } size = g_struct_info_get_size((GIStructInfo*) info); } else { size = g_union_info_get_size((GIUnionInfo*) info); } if (!size) { g_critical("Struct/union of type: %s has size 0 in introspection data. " "Please check GIR", g_base_info_get_name(info)); g_assert(size); } object = g_slice_alloc0(size); SEED_NOTE(CONSTRUCTION, "Constructing struct/union of type: %s. Size: %zu \n", g_base_info_get_name(info), size); if (type == GI_INFO_TYPE_STRUCT) ret = seed_make_struct(ctx, object, info); else ret = seed_make_union(ctx, object, info); seed_pointer_set_free(ctx, ret, TRUE); seed_pointer_set_slice(ctx, ret, TRUE, size); if (!parameters) return ret; jsprops = JSObjectCopyPropertyNames(ctx, (JSObjectRef) parameters); nparams = JSPropertyNameArrayGetCount(jsprops); while (i < nparams) { jsprop_name = JSPropertyNameArrayGetNameAtIndex(jsprops, i); length = JSStringGetMaximumUTF8CStringSize(jsprop_name); prop_name = g_alloca(length * sizeof(gchar)); JSStringGetUTF8CString(jsprop_name, prop_name, length); if (type == GI_INFO_TYPE_STRUCT) field = seed_struct_find_field((GIStructInfo*) info, prop_name); else field = seed_union_find_field((GIUnionInfo*) info, prop_name); if (!field) { seed_make_exception(ctx, exception, "PropertyError", "Invalid property for construction: %s", prop_name); JSPropertyNameArrayRelease(jsprops); return (JSObjectRef) JSValueMakeNull(ctx); } field_type = g_field_info_get_type(field); jsprop_value = JSObjectGetProperty(ctx, (JSObjectRef) parameters, jsprop_name, NULL); seed_value_to_gi_argument(ctx, jsprop_value, field_type, GI_TRANSFER_NOTHING, &field_value, exception); set_ret = g_field_info_set_field(field, object, &field_value); if (!set_ret) g_warning( "Constructor setting property failed on struct of type: %s " "with name %s \n", g_base_info_get_name(info), prop_name); g_base_info_unref((GIBaseInfo*) field_type); g_base_info_unref((GIBaseInfo*) field); i++; } JSPropertyNameArrayRelease(jsprops); return ret; } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/libseed/seed-structs.h000066400000000000000000000046371303774616400230450ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #ifndef _SEED_STRUCT_H #define _SEED_STRUCT_H extern JSClassRef seed_struct_class; extern JSClassRef seed_union_class; JSObjectRef seed_make_union(JSContextRef ctx, gpointer younion, GIBaseInfo* info); JSObjectRef seed_make_struct(JSContextRef ctx, gpointer strukt, GIBaseInfo* info); JSObjectRef seed_make_boxed(JSContextRef ctx, gpointer boxed, GIBaseInfo* info); JSObjectRef seed_make_pointer(JSContextRef ctx, gpointer pointer); JSValueRef seed_field_get_value(JSContextRef ctx, gpointer object, GIFieldInfo* field, JSValueRef* exception); gpointer seed_pointer_get_pointer(JSContextRef ctx, JSValueRef strukt); void seed_pointer_set_free(JSContextRef ctx, JSValueRef pointer, gboolean free_pointer); GIFieldInfo* seed_struct_find_field(GIStructInfo* info, gchar* field_name); GIFieldInfo* seed_union_find_field(GIUnionInfo* info, gchar* field_name); JSObjectRef seed_construct_struct_type_with_parameters(JSContextRef ctx, GIBaseInfo* info, JSObjectRef parameters, JSValueRef* exception); JSObjectRef seed_union_prototype(JSContextRef ctx, GIBaseInfo* info); JSObjectRef seed_struct_prototype(JSContextRef ctx, GIBaseInfo* info); void seed_structs_init(); #endif seed-webkit2-4.0.0+20161014+6c77960+dfsg1/libseed/seed-types.c000066400000000000000000002706201303774616400224720ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #include "seed-private.h" #include #include JSClassRef gobject_class; JSClassRef gobject_method_class; JSClassRef gobject_constructor_class; JSClassRef seed_callback_class; JSClassRef gobject_init_method_class; SeedEngine* eng; static gboolean seed_value_is_gobject(JSContextRef ctx, JSValueRef value) { if (!JSValueIsObject(ctx, value) || JSValueIsNull(ctx, value)) return FALSE; return JSValueIsObjectOfClass(ctx, value, gobject_class); } void seed_toggle_ref(gpointer data, GObject* object, gboolean is_last_ref) { JSValueRef wrapper; if (!g_object_get_qdata(object, js_ref_quark)) return; wrapper = (JSValueRef) data; if (is_last_ref) { JSValueUnprotect(eng->context, wrapper); } else { JSValueProtect(eng->context, wrapper); } } static void seed_gobject_destroyed(gpointer object) { JSValueUnprotect(eng->context, (JSValueRef) object); JSObjectSetPrivate((JSObjectRef) object, 0); } JSObjectRef seed_make_wrapper_for_type(JSContextRef ctx, GType type) { JSClassRef class; JSObjectRef ret; JSValueRef prototype; class = seed_gobject_get_class_for_gtype(ctx, type); while (!class && (type = g_type_parent(type))) class = seed_gobject_get_class_for_gtype(ctx, type); prototype = seed_gobject_get_prototype_for_gtype(type); ret = JSObjectMake(ctx, class, NULL); if (prototype) JSObjectSetPrototype(ctx, ret, prototype); else g_assert_not_reached(); return ret; } static JSValueRef seed_wrap_object(JSContextRef ctx, GObject* object) { JSValueRef user_data; JSObjectRef js_ref; GType type; type = G_OBJECT_TYPE(object); user_data = (JSValueRef) g_object_get_qdata(object, js_ref_quark); if (user_data) return user_data; if (pthread_getspecific(seed_next_gobject_wrapper_key)) js_ref = pthread_getspecific(seed_next_gobject_wrapper_key); else js_ref = seed_make_wrapper_for_type(ctx, type); JSObjectSetPrivate(js_ref, object); g_object_set_qdata_full(object, js_ref_quark, (gpointer) js_ref, seed_gobject_destroyed); JSValueProtect(eng->context, js_ref); g_object_add_toggle_ref(object, seed_toggle_ref, (gpointer) js_ref); seed_add_signals_to_object(ctx, js_ref, object); pthread_setspecific(seed_next_gobject_wrapper_key, NULL); return js_ref; } static gboolean seed_release_arg(GITransfer transfer, GITypeInfo* type_info, GITypeTag type_tag, GArgument* arg) { GType gtype; GITypeInfo* param_type; GIBaseInfo* interface_info; GValue* gval; switch (type_tag) { case GI_TYPE_TAG_UTF8: case GI_TYPE_TAG_FILENAME: g_free(arg->v_string); break; case GI_TYPE_TAG_ARRAY: if (arg->v_pointer) { param_type = g_type_info_get_param_type(type_info, 0); switch (g_type_info_get_tag(param_type)) { case GI_TYPE_TAG_UTF8: if (transfer == GI_TRANSFER_EVERYTHING) g_strfreev(arg->v_pointer); else if (transfer == GI_TRANSFER_CONTAINER) g_free(arg->v_pointer); break; case GI_TYPE_TAG_GTYPE: case GI_TYPE_TAG_FLOAT: case GI_TYPE_TAG_UINT8: case GI_TYPE_TAG_INT32: case GI_TYPE_TAG_UINT32: g_free(arg->v_pointer); break; case GI_TYPE_TAG_INTERFACE: break; default: g_assert_not_reached(); } g_base_info_unref((GIBaseInfo*) param_type); } break; case GI_TYPE_TAG_GHASH: { GITypeInfo* val_param_info; GHashTableIter iter; GArgument value; val_param_info = g_type_info_get_param_type(type_info, 1); g_assert(val_param_info != NULL); /* release the hashtable's values */ g_hash_table_iter_init(&iter, arg->v_pointer); while (g_hash_table_iter_next(&iter, NULL, &value.v_pointer)) { seed_release_arg(GI_TRANSFER_EVERYTHING, val_param_info, g_type_info_get_tag(val_param_info), &value); } /* release the hashtable's keys and the hashtable itself */ g_hash_table_destroy(arg->v_pointer); break; } case GI_TYPE_TAG_INTERFACE: { if (arg->v_pointer) { interface_info = g_type_info_get_interface(type_info); GIInfoType interface_type = g_base_info_get_type(interface_info); if (interface_type == GI_INFO_TYPE_CALLBACK) { /* FIXME: - callback returns are not handled yet */ g_base_info_unref(interface_info); break; } gtype = g_registered_type_info_get_g_type( (GIRegisteredTypeInfo*) interface_info); if (g_type_is_a(gtype, G_TYPE_OBJECT) || g_type_is_a(gtype, G_TYPE_INTERFACE)) { SEED_NOTE(MISC, "Unreffing object of type: %s in" "argument release. Reference count: %d\n", g_type_name( G_OBJECT_TYPE(G_OBJECT(arg->v_pointer))), G_OBJECT(arg->v_pointer)->ref_count); g_object_unref(G_OBJECT(arg->v_pointer)); } else if (g_type_is_a(gtype, G_TYPE_VALUE)) { gval = (GValue*) arg->v_pointer; // Free/unref the GValue's contents. g_value_unset(gval); // Free the GValue. g_slice_free1(sizeof(GValue), gval); } else if (g_type_is_a(gtype, G_TYPE_CLOSURE)) { g_closure_unref(arg->v_pointer); } g_base_info_unref(interface_info); } break; } default: break; } return TRUE; } gboolean seed_gi_release_arg(GITransfer transfer, GITypeInfo* type_info, GArgument* arg) { GITypeTag type_tag; if (transfer == GI_TRANSFER_NOTHING) return TRUE; type_tag = g_type_info_get_tag((GITypeInfo*) type_info); return seed_release_arg(transfer, type_info, type_tag, arg); } gboolean seed_gi_release_in_arg(GITransfer transfer, GITypeInfo* type_info, GArgument* arg) { GITypeTag type_tag; if (transfer == GI_TRANSFER_EVERYTHING) return TRUE; type_tag = g_type_info_get_tag((GITypeInfo*) type_info); switch (type_tag) { // TODO: FIXME: Leaaaks? case GI_TYPE_TAG_INTERFACE: { // TODO: FIXME: Need some safe way to look for GClosure. break; } case GI_TYPE_TAG_UTF8: case GI_TYPE_TAG_FILENAME: case GI_TYPE_TAG_ARRAY: case GI_TYPE_TAG_GHASH: return seed_release_arg(GI_TRANSFER_EVERYTHING, type_info, type_tag, arg); default: break; } return TRUE; } static JSValueRef seed_gi_make_jsarray(JSContextRef ctx, void* array, GITypeInfo* param_type, JSValueRef* exception) { GITypeTag element_type; JSValueRef* elements; guint length, i; gchar** str_array = (gchar**) array; JSValueRef ret = JSValueMakeNull(ctx); element_type = g_type_info_get_tag(param_type); if (element_type == GI_TYPE_TAG_UTF8) { length = g_strv_length(str_array); if (!length) return ret; elements = g_alloca(sizeof(JSValueRef) * length); for (i = 0; i < length; ++i) { elements[i] = seed_value_from_string(ctx, str_array[i], exception); } ret = (JSValueRef) JSObjectMakeArray(ctx, length, elements, exception); } if (element_type == GI_TYPE_TAG_GTYPE) { GType* ptr = (GType*) array; length = 0; while (ptr[length]) length++; elements = g_alloca(sizeof(JSValueRef) * length); for (i = 0; i < length; ++i) elements[i] = seed_value_from_long(ctx, ptr[i], exception); return (JSValueRef) JSObjectMakeArray(ctx, length, elements, exception); } return ret; } JSValueRef seed_array_from_zero_terminated_c_array(JSContextRef ctx, gpointer pointer, GITypeInfo* param_info, JSValueRef* exception) { JSValueRef ret; GITypeTag element_type; GArgument arg; guint i; element_type = g_type_info_get_tag(param_info); // Special case handling array(guint8), which happens to be a string // in most cases if (element_type == GI_TYPE_TAG_UINT8) { // TODO: this is pretty simple and probably incomplete. // GJS makes possible the return of an array, supporting // all types. We're only supporting strings ATM. ret = seed_value_from_string(ctx, pointer, exception); return ret; } ret = JSObjectMakeArray(ctx, 0, NULL, NULL); #define ITERATE(type) \ do { \ g##type* array = (g##type*) pointer; \ for (i = 0; array[i]; i++) { \ arg.v_##type = array[i]; \ JSValueRef val \ = seed_value_from_gi_argument(ctx, &arg, param_info, exception); \ seed_object_set_property_at_index(ctx, (JSObjectRef) ret, i, val, exception); \ } \ } while (0); switch (element_type) { /* We handle GI_TYPE_TAG_UINT8 above. */ case GI_TYPE_TAG_INT8: ITERATE(int8); break; case GI_TYPE_TAG_UINT16: ITERATE(uint16); break; case GI_TYPE_TAG_INT16: ITERATE(int16); break; case GI_TYPE_TAG_UINT32: ITERATE(uint32); break; case GI_TYPE_TAG_INT32: ITERATE(int32); break; case GI_TYPE_TAG_UINT64: ITERATE(uint64); break; case GI_TYPE_TAG_INT64: ITERATE(int64); break; case GI_TYPE_TAG_FLOAT: ITERATE(float); break; case GI_TYPE_TAG_DOUBLE: ITERATE(double); break; case GI_TYPE_TAG_GTYPE: case GI_TYPE_TAG_UTF8: case GI_TYPE_TAG_FILENAME: case GI_TYPE_TAG_ARRAY: case GI_TYPE_TAG_INTERFACE: case GI_TYPE_TAG_GLIST: case GI_TYPE_TAG_GSLIST: case GI_TYPE_TAG_GHASH: case GI_TYPE_TAG_ERROR: ITERATE(pointer); break; default: seed_make_exception(ctx, exception, "Argumenterror", "Unknown element-type %d", element_type); } #undef ITERATE return ret; } static gboolean seed_gi_make_array_from_string(JSContextRef ctx, JSStringRef js_string, GITypeInfo* param_type, guint length, void** array_p, guint* out_array_length, JSValueRef* exception) { GITypeTag element_type; element_type = g_type_info_get_tag(param_type); // This could be handled by the case where the value is an object, // however, getting length from a string crashs inside JSC. So, // we're now proper handling strings here gchar* buffer = g_malloc(length * sizeof(gchar)); guint real_size = JSStringGetUTF8CString(js_string, buffer, length); switch (element_type) { case GI_TYPE_TAG_INT8: case GI_TYPE_TAG_UINT8: { *array_p = buffer; // So, GJS doesn't computer the \0 at the end of line. // it does make sense, as converting a string to an array // we don't want the EOS. However, I couldn't find a way to do it // with // JSC, so I'm basically reducing one byte. if (out_array_length) *out_array_length = real_size - 1; break; } case GI_TYPE_TAG_INT16: case GI_TYPE_TAG_UINT16: // TODO: implement utf16 support default: { seed_make_exception(ctx, exception, "ArgumentError", "Cannot convert string to array of '%s'", g_type_tag_to_string(element_type)); return FALSE; } } return TRUE; } static gboolean seed_gi_make_array(JSContextRef ctx, JSValueRef array, guint length, GITypeInfo* param_type, void** array_p, JSValueRef* exception) { GITypeTag element_type; JSValueRef elem; guint i; element_type = g_type_info_get_tag(param_type); switch (element_type) { case GI_TYPE_TAG_UTF8: { gchar** strresult = g_new0(gchar*, length + 1); for (i = 0; i < length; i++) { elem = JSObjectGetPropertyAtIndex(ctx, (JSObjectRef) array, i, exception); strresult[i] = seed_value_to_string(ctx, elem, exception); } *array_p = strresult; } break; case GI_TYPE_TAG_GTYPE: { GType* typeresult; typeresult = g_new0(GType, length + 1); for (i = 0; i < length; i++) { elem = JSObjectGetPropertyAtIndex(ctx, (JSObjectRef) array, i, exception); typeresult[i] = seed_value_to_int(ctx, elem, exception); } *array_p = typeresult; } break; case GI_TYPE_TAG_FLOAT: { gfloat* floatresult; floatresult = g_new0(gfloat, length + 1); for (i = 0; i < length; i++) { elem = JSObjectGetPropertyAtIndex(ctx, (JSObjectRef) array, i, exception); floatresult[i] = seed_value_to_float(ctx, elem, exception); } *array_p = floatresult; } break; case GI_TYPE_TAG_DOUBLE: { gdouble* dblresult; dblresult = g_new0(gdouble, length + 1); for (i = 0; i < length; i++) { elem = JSObjectGetPropertyAtIndex(ctx, (JSObjectRef) array, i, exception); dblresult[i] = seed_value_to_double(ctx, elem, exception); } *array_p = dblresult; } break; #if GOBJECT_INTROSPECTION_VERSION < 0x000900 case GI_TYPE_TAG_INT: #endif case GI_TYPE_TAG_INT32: { gint* intresult; intresult = g_new0(gint, length + 1); for (i = 0; i < length; i++) { elem = JSObjectGetPropertyAtIndex(ctx, (JSObjectRef) array, i, exception); intresult[i] = seed_value_to_int(ctx, elem, exception); } *array_p = intresult; } break; case GI_TYPE_TAG_UINT8: { guint8* guint8result; guint8result = g_new0(guint8, length + 1); for (i = 0; i < length; i++) { elem = JSObjectGetPropertyAtIndex(ctx, (JSObjectRef) array, i, exception); guint8result[i] = seed_value_to_uchar(ctx, elem, exception); } *array_p = guint8result; } break; case GI_TYPE_TAG_INTERFACE: { GIBaseInfo* interface = g_type_info_get_interface(param_type); GIInfoType interface_type = g_base_info_get_type(interface); if (interface_type == GI_INFO_TYPE_OBJECT || interface_type == GI_INFO_TYPE_INTERFACE || interface_type == GI_INFO_TYPE_STRUCT) { GType type = g_registered_type_info_get_g_type( (GIRegisteredTypeInfo*) interface); if (g_type_is_a(type, G_TYPE_VALUE)) { GValue* gvalresult; // TODO:FIXME: Robb. Valgrind thinks there's a leak here, // at least while running Same Seed. gvalresult = g_new0(GValue, length + 1); for (i = 0; i < length; i++) { elem = JSObjectGetPropertyAtIndex(ctx, (JSObjectRef) array, i, exception); seed_value_to_gvalue(ctx, elem, (GType) 0, &gvalresult[i], exception); } *array_p = gvalresult; g_base_info_unref(interface); break; } } g_base_info_unref(interface); } case GI_TYPE_TAG_UINT32: { guint32* uintresult; uintresult = g_new0(guint32, length + 1); for (i = 0; i < length; i++) { elem = JSObjectGetPropertyAtIndex(ctx, (JSObjectRef) array, i, exception); uintresult[i] = seed_value_to_uint(ctx, elem, exception); } *array_p = uintresult; } break; default: seed_make_exception(ctx, exception, "ArgumentError", "Unhandled array element type"); return FALSE; } return TRUE; } gboolean seed_value_to_gi_argument_with_out_length(JSContextRef ctx, JSValueRef value, GITypeInfo* type_info, GITransfer transfer, GArgument* arg, guint* out_array_length, JSValueRef* exception) { GITypeTag gi_tag = g_type_info_get_tag(type_info); // FIXME: Some types are not "nullable", also need to check if argument // can be null before doing this. if (!value || JSValueIsNull(ctx, value)) { arg->v_pointer = 0; return 1; } switch (gi_tag) { case GI_TYPE_TAG_VOID: if (g_type_info_is_pointer(type_info)) { GObject* gobject; if (JSValueIsString(ctx, value)) { /* things like gio.outputstream.write use void pointers might need a few other types here.. not very well memory managed. - should be solved by bytearrays when introspection implements it. */ arg->v_string = seed_value_to_string(ctx, value, exception); break; } /* gtk_statusicon_position_menu / gtk_menu_popup use the * userdata for the Gobject */ gobject = seed_value_to_object(ctx, value, exception); if (!gobject) return FALSE; arg->v_pointer = gobject; } break; #if GOBJECT_INTROSPECTION_VERSION < 0x000900 case GI_TYPE_TAG_LONG: arg->v_long = seed_value_to_long(ctx, value, exception); break; case GI_TYPE_TAG_ULONG: arg->v_ulong = seed_value_to_ulong(ctx, value, exception); break; case GI_TYPE_TAG_INT: arg->v_int = seed_value_to_int(ctx, value, exception); break; case GI_TYPE_TAG_UINT: arg->v_uint = seed_value_to_uint(ctx, value, exception); break; case GI_TYPE_TAG_SIZE: arg->v_size = seed_value_to_size(ctx, value, exception); break; case GI_TYPE_TAG_SSIZE: arg->v_ssize = seed_value_to_ssize(ctx, value, exception); break; case GI_TYPE_TAG_TIME_T: arg->v_long = seed_value_to_time_t(ctx, value, exception); break; #endif case GI_TYPE_TAG_BOOLEAN: arg->v_boolean = seed_value_to_boolean(ctx, value, exception); break; case GI_TYPE_TAG_INT8: arg->v_int8 = seed_value_to_char(ctx, value, exception); break; case GI_TYPE_TAG_UINT8: arg->v_uint8 = seed_value_to_uchar(ctx, value, exception); break; case GI_TYPE_TAG_INT16: arg->v_int16 = seed_value_to_int(ctx, value, exception); break; case GI_TYPE_TAG_UINT16: arg->v_uint16 = seed_value_to_uint(ctx, value, exception); break; case GI_TYPE_TAG_INT32: arg->v_int32 = seed_value_to_int(ctx, value, exception); break; case GI_TYPE_TAG_UINT32: arg->v_uint32 = seed_value_to_uint(ctx, value, exception); break; case GI_TYPE_TAG_INT64: arg->v_int64 = seed_value_to_int64(ctx, value, exception); break; case GI_TYPE_TAG_UINT64: arg->v_uint64 = seed_value_to_uint64(ctx, value, exception); break; case GI_TYPE_TAG_FLOAT: arg->v_float = seed_value_to_float(ctx, value, exception); break; case GI_TYPE_TAG_DOUBLE: arg->v_double = seed_value_to_double(ctx, value, exception); break; case GI_TYPE_TAG_UTF8: arg->v_string = seed_value_to_string(ctx, value, exception); break; case GI_TYPE_TAG_FILENAME: arg->v_string = seed_value_to_filename(ctx, value, exception); break; case GI_TYPE_TAG_GTYPE: arg->v_int = seed_value_to_int(ctx, value, exception); break; case GI_TYPE_TAG_INTERFACE: { GIBaseInfo* interface; GIInfoType interface_type; GType required_gtype; GObject* gobject; interface = g_type_info_get_interface(type_info); interface_type = g_base_info_get_type(interface); arg->v_pointer = NULL; if (interface_type == GI_INFO_TYPE_OBJECT || interface_type == GI_INFO_TYPE_INTERFACE) { gobject = seed_value_to_object(ctx, value, exception); required_gtype = g_registered_type_info_get_g_type( (GIRegisteredTypeInfo*) interface); // FIXME: Not clear if the g_type_is_a check is desired here. // Possibly 'breaks things' when we don't have introspection // data for some things in an interface hierarchy. Hasn't // provided any problems so far. if (!gobject || !g_type_is_a(G_OBJECT_TYPE(gobject), required_gtype)) { g_base_info_unref(interface); return FALSE; } arg->v_pointer = gobject; // FIXME: This has to be done for other types too if (transfer == GI_TRANSFER_EVERYTHING) g_object_ref(gobject); g_base_info_unref(interface); break; } else if (interface_type == GI_INFO_TYPE_ENUM || interface_type == GI_INFO_TYPE_FLAGS) { // this might need fixing... arg->v_long = seed_value_to_long(ctx, value, exception); if (!(interface_type == GI_INFO_TYPE_FLAGS) && !seed_validate_enum((GIEnumInfo*) interface, arg->v_long)) { seed_make_exception(ctx, exception, "EnumRange", "Enum value: %ld is out of range", arg->v_long); g_base_info_unref(interface); return FALSE; } g_base_info_unref(interface); break; } else if (interface_type == GI_INFO_TYPE_STRUCT || interface_type == GI_INFO_TYPE_UNION) { if (JSValueIsObjectOfClass(ctx, value, seed_struct_class)) arg->v_pointer = seed_pointer_get_pointer(ctx, value); else if (JSValueIsObjectOfClass(ctx, value, seed_union_class)) arg->v_pointer = seed_pointer_get_pointer(ctx, value); else { GType type = g_registered_type_info_get_g_type( (GIRegisteredTypeInfo*) interface); if (!type) { g_base_info_unref(interface); return FALSE; } else if (type == G_TYPE_VALUE) { GValue* gval = g_slice_alloc0(sizeof(GValue)); seed_value_to_gvalue(ctx, value, (GType) NULL, gval, exception); arg->v_pointer = gval; g_base_info_unref(interface); break; } // Automatically convert between functions and // GClosures where expected. else if (g_type_is_a(type, G_TYPE_CLOSURE)) { if (JSObjectIsFunction(ctx, (JSObjectRef) value)) { arg->v_pointer = seed_closure_new(ctx, (JSObjectRef) value, NULL, NULL); } } else { JSObjectRef strukt = seed_construct_struct_type_with_parameters( ctx, interface, (JSObjectRef) value, exception); arg->v_pointer = seed_pointer_get_pointer(ctx, strukt); } } g_base_info_unref(interface); break; } else if (interface_type == GI_INFO_TYPE_CALLBACK) { if (JSValueIsNull(ctx, value)) { arg->v_pointer = NULL; g_base_info_unref(interface); break; } // Someone passes in a wrapper around a method where a // callback is expected, i.e Clutter.sine_inc_func, as an alpha // Have to dlsym the symbol to be able to do this. // NOTE: Some cases where dlsym(NULL, symbol) doesn't work // depending // On how libseed is loaded. else if (JSValueIsObjectOfClass(ctx, value, gobject_method_class)) { GIFunctionInfo* info = JSObjectGetPrivate((JSObjectRef) value); const gchar* symbol = g_function_info_get_symbol(info); gchar* error; void* fp; dlerror(); fp = (void*) dlsym(0, symbol); if ((error = dlerror()) != NULL) { g_critical("dlerror: %s \n", error); } else { arg->v_pointer = fp; g_base_info_unref(interface); break; } } // Somewhat deprecated from when it was necessary to manually // create closure objects... else if (JSValueIsObjectOfClass(ctx, value, seed_native_callback_class)) { SeedNativeClosure* privates = (SeedNativeClosure*) JSObjectGetPrivate( (JSObjectRef) value); arg->v_pointer = privates->closure; g_base_info_unref(interface); break; } // Automagically create closure around function passed in as // callback. else if (JSObjectIsFunction(ctx, (JSObjectRef) value)) { SeedNativeClosure* privates = seed_make_native_closure(ctx, (GICallableInfo*) interface, value); arg->v_pointer = privates->closure; g_base_info_unref(interface); break; } } } case GI_TYPE_TAG_ARRAY: { if (JSValueIsNull(ctx, value)) { arg->v_pointer = NULL; break; } else if (JSValueIsString(ctx, value)) { GITypeInfo* param_type; param_type = g_type_info_get_param_type(type_info, 0); JSStringRef js_string = JSValueToStringCopy(ctx, value, exception); size_t length = JSStringGetMaximumUTF8CStringSize(js_string); if (!seed_gi_make_array_from_string(ctx, js_string, param_type, length, &arg->v_pointer, out_array_length, exception)) { g_base_info_unref((GIBaseInfo*) param_type); JSStringRelease(js_string); return FALSE; } JSStringRelease(js_string); g_base_info_unref((GIBaseInfo*) param_type); break; } else if (!JSValueIsObject(ctx, value)) { // TODO: FIXME: Is this right? return FALSE; } else { GITypeInfo* param_type; // TODO: FIXME: Better array test like the cool one on reddit. guint length = seed_value_to_int( ctx, seed_object_get_property(ctx, (JSObjectRef) value, "length"), exception); if (!length) { arg->v_pointer = NULL; break; } param_type = g_type_info_get_param_type(type_info, 0); if (!seed_gi_make_array(ctx, value, length, param_type, &arg->v_pointer, exception)) { g_base_info_unref((GIBaseInfo*) param_type); return FALSE; } if (out_array_length != NULL) *out_array_length = length; g_base_info_unref((GIBaseInfo*) param_type); break; } } case GI_TYPE_TAG_GHASH: { GITypeInfo *key_param_info, *val_param_info; GHashTable* hash_table; JSPropertyNameArrayRef jsprops = 0; JSStringRef jsprop_name; JSValueRef jsprop_value; int i, nparams = 0; if (!JSValueIsObject(ctx, value)) { return FALSE; } if (JSValueIsNull(ctx, value)) { arg->v_pointer = NULL; break; } key_param_info = g_type_info_get_param_type(type_info, 0); g_assert(key_param_info != NULL); if (g_type_info_get_tag(key_param_info) != GI_TYPE_TAG_UTF8) { /* Functions requesting a hash table with non-string keys are * not supported */ return FALSE; } val_param_info = g_type_info_get_param_type(type_info, 1); g_assert(val_param_info != NULL); jsprops = JSObjectCopyPropertyNames(ctx, (JSObjectRef) value); nparams = JSPropertyNameArrayGetCount(jsprops); /* keys are strings and the destructor is g_free * values will be freed in seed_release_arg */ hash_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); for (i = 0; i < nparams; i++) { char* prop_name; int length; GArgument hash_arg; jsprop_name = JSPropertyNameArrayGetNameAtIndex(jsprops, i); length = JSStringGetMaximumUTF8CStringSize(jsprop_name); prop_name = g_malloc(length * sizeof(gchar)); JSStringGetUTF8CString(jsprop_name, prop_name, length); jsprop_value = JSObjectGetProperty(ctx, (JSObjectRef) value, jsprop_name, NULL); if (!seed_value_to_gi_argument(ctx, jsprop_value, val_param_info, GI_TRANSFER_NOTHING, &hash_arg, exception)) { g_hash_table_destroy(hash_table); g_base_info_unref((GIBaseInfo*) val_param_info); return FALSE; } g_hash_table_insert(hash_table, prop_name, hash_arg.v_pointer); } arg->v_pointer = hash_table; break; } default: return FALSE; } return TRUE; } gboolean seed_value_to_gi_argument(JSContextRef ctx, JSValueRef value, GITypeInfo* type_info, GITransfer transfer, GArgument* arg, JSValueRef* exception) { return seed_value_to_gi_argument_with_out_length(ctx, value, type_info, transfer, arg, NULL, exception); } JSValueRef seed_value_from_gi_argument(JSContextRef ctx, GArgument* arg, GITypeInfo* type_info, JSValueRef* exception) { return seed_value_from_gi_argument_full(ctx, arg, type_info, exception, 0, g_type_info_get_tag(type_info)); } JSValueRef seed_value_from_gi_argument_full(JSContextRef ctx, GArgument* arg, GITypeInfo* type_info, JSValueRef* exception, guint64 array_len, GITypeTag gi_tag) { // seed_value_from_gi_argument_with_length : g_type_tag_to_string(gi_tag) SEED_NOTE(INVOCATION, "seed_value_from_gi_argument_full: arg_type = %s ", g_type_tag_to_string(gi_tag)); switch (gi_tag) { #if GOBJECT_INTROSPECTION_VERSION < 0x000900 case GI_TYPE_TAG_LONG: return seed_value_from_long(ctx, arg->v_long, exception); case GI_TYPE_TAG_ULONG: return seed_value_from_ulong(ctx, arg->v_ulong, exception); case GI_TYPE_TAG_INT: return seed_value_from_int(ctx, arg->v_int32, exception); case GI_TYPE_TAG_UINT: return seed_value_from_uint(ctx, arg->v_uint32, exception); case GI_TYPE_TAG_SSIZE: return seed_value_from_ssize(ctx, arg->v_ssize, exception); case GI_TYPE_TAG_SIZE: return seed_value_from_size(ctx, arg->v_size, exception); case GI_TYPE_TAG_TIME_T: return seed_value_from_time_t(ctx, arg->v_long, exception); #endif case GI_TYPE_TAG_VOID: return JSValueMakeUndefined(ctx); case GI_TYPE_TAG_BOOLEAN: return seed_value_from_boolean(ctx, arg->v_boolean, exception); case GI_TYPE_TAG_INT8: return seed_value_from_char(ctx, arg->v_int8, exception); case GI_TYPE_TAG_UINT8: return seed_value_from_uchar(ctx, arg->v_uint8, exception); case GI_TYPE_TAG_INT16: return seed_value_from_int(ctx, arg->v_int16, exception); case GI_TYPE_TAG_UINT16: return seed_value_from_uint(ctx, arg->v_uint16, exception); case GI_TYPE_TAG_INT32: return seed_value_from_int(ctx, arg->v_int32, exception); case GI_TYPE_TAG_UINT32: return seed_value_from_uint(ctx, arg->v_uint32, exception); case GI_TYPE_TAG_INT64: return seed_value_from_int64(ctx, arg->v_int64, exception); case GI_TYPE_TAG_UINT64: return seed_value_from_uint64(ctx, arg->v_uint64, exception); case GI_TYPE_TAG_FLOAT: return seed_value_from_float(ctx, arg->v_float, exception); case GI_TYPE_TAG_DOUBLE: return seed_value_from_double(ctx, arg->v_double, exception); case GI_TYPE_TAG_UTF8: return seed_value_from_string(ctx, arg->v_string, exception); case GI_TYPE_TAG_FILENAME: return seed_value_from_filename(ctx, arg->v_string, exception); case GI_TYPE_TAG_GTYPE: return seed_value_from_int(ctx, arg->v_int, exception); case GI_TYPE_TAG_ARRAY: { GIArrayType array_type; GITypeInfo* array_type_info; JSValueRef ret; if (arg->v_pointer == NULL) return JSValueMakeNull(ctx); array_type = g_type_info_get_array_type(type_info); array_type_info = g_type_info_get_param_type(type_info, 0); if (array_type == GI_ARRAY_TYPE_PTR_ARRAY) { JSObjectRef ret_ptr_array; GPtrArray* ptr = arg->v_pointer; GArgument larg; int length = 0; int i; length = ptr->len; ret_ptr_array = JSObjectMakeArray(ctx, 0, NULL, exception); for (i = 0; i < length; ++i) { JSValueRef ival; larg.v_pointer = g_ptr_array_index(ptr, i); ival = (JSValueRef) seed_value_from_gi_argument( ctx, &larg, array_type_info, exception); if (!ival) ival = JSValueMakeNull(ctx); JSObjectSetPropertyAtIndex(ctx, ret_ptr_array, i, ival, NULL); } g_base_info_unref((GIBaseInfo*) array_type_info); return ret_ptr_array; } else if (array_type == GI_ARRAY_TYPE_C) { if (g_type_info_is_zero_terminated(type_info)) { GITypeInfo* param_info; param_info = g_type_info_get_param_type(type_info, 0); g_assert(param_info != NULL); ret = seed_array_from_zero_terminated_c_array( ctx, arg->v_pointer, param_info, exception); g_base_info_unref((GIBaseInfo*) param_info); g_base_info_unref((GIBaseInfo*) array_type_info); return ret; } } // technically gir has arrays of bytes, eg. // // example : g_file_get_contents.. // we can treat this as a string.. - it's a bit flakey, we should // really use // Uint8Array - need to check the webkit API for this.. if (!g_type_info_is_zero_terminated(type_info) && array_type == GI_ARRAY_TYPE_C && GI_TYPE_TAG_UINT8 == g_type_info_get_tag(array_type_info) && array_len > 0) { // got a stringy array.. // we should check g_type_info_get_array_fixed_size // we are assuming that this is the array_len from the call.. g_base_info_unref((GIBaseInfo*) array_type_info); ret = seed_value_from_binary_string(ctx, arg->v_pointer, array_len, exception); // always free arg... what about when we do not own it...? // g_free(arg->v_pointer); return ret; } if (!g_type_info_is_zero_terminated(type_info)) { g_base_info_unref((GIBaseInfo*) array_type_info); break; } ret = seed_gi_make_jsarray(ctx, arg->v_pointer, array_type_info, exception); g_base_info_unref((GIBaseInfo*) array_type_info); return ret; } case GI_TYPE_TAG_INTERFACE: { GIBaseInfo* interface; GIInfoType interface_type; interface = g_type_info_get_interface(type_info); interface_type = g_base_info_get_type(interface); if (interface_type == GI_INFO_TYPE_OBJECT || interface_type == GI_INFO_TYPE_INTERFACE) { if (arg->v_pointer == 0) { g_base_info_unref(interface); return JSValueMakeNull(ctx); } g_base_info_unref(interface); return seed_value_from_object(ctx, arg->v_pointer, exception); } else if (interface_type == GI_INFO_TYPE_ENUM) { JSValueRef ret; GITypeTag etype = g_enum_info_get_storage_type(interface); // needs GITypeInfo - we are sending it GIBaseInfo ret = seed_value_from_gi_argument_full(ctx, arg, type_info, exception, 0, etype); g_base_info_unref(interface); return ret; } else if (interface_type == GI_INFO_TYPE_FLAGS) { g_base_info_unref(interface); return seed_value_from_long(ctx, arg->v_long, exception); } else if (interface_type == GI_INFO_TYPE_STRUCT) { // Trying to find out if this struct can be converted into // GValue // If it can be converted, just send the converted value back to // JS context instead // of the GValue itself. GType gtype = g_registered_type_info_get_g_type( (GIRegisteredTypeInfo*) interface); if (G_TYPE_IS_INSTANTIATABLE(gtype) || G_TYPE_IS_INTERFACE(gtype)) gtype = G_TYPE_FROM_INSTANCE(arg->v_pointer); SEED_NOTE(INVOCATION, "gtype of INTERFACE is %s", g_type_name(gtype)); if (g_type_is_a(gtype, G_TYPE_VALUE)) { JSValueRef ret; // We're using seed_value_from_gvalue_for_signal with NULL // signal handler // the current code will only handle basic types. if ((ret = seed_value_from_gvalue_for_signal( ctx, arg->v_pointer, exception, NULL, 0))) { g_base_info_unref(interface); return ret; } } JSValueRef strukt; strukt = seed_make_struct(ctx, arg->v_pointer, interface); g_base_info_unref(interface); return strukt; } else if (interface_type == GI_INFO_TYPE_CALLBACK) { /* FIXME: return values of type callback are not handled yet. */ g_base_info_unref(interface); return FALSE; } /* fall through - other types?? */ g_base_info_unref(interface); return FALSE; } case GI_TYPE_TAG_GLIST: { GITypeInfo* list_type; JSObjectRef ret; GArgument larg; gint i = 0; GList* list = arg->v_pointer; ret = JSObjectMakeArray(ctx, 0, NULL, exception); list_type = g_type_info_get_param_type(type_info, 0); for (; list != NULL; list = list->next) { JSValueRef ival; larg.v_pointer = list->data; ival = (JSValueRef) seed_value_from_gi_argument(ctx, &larg, list_type, exception); if (!ival) ival = JSValueMakeNull(ctx); JSObjectSetPropertyAtIndex(ctx, ret, i, ival, NULL); i++; } return ret; } case GI_TYPE_TAG_GSLIST: { GITypeInfo* list_type; JSObjectRef ret; JSValueRef ival; GArgument larg; guint i = 0; GSList* list = arg->v_pointer; ret = JSObjectMakeArray(ctx, 0, NULL, exception); list_type = g_type_info_get_param_type(type_info, 0); for (; list != NULL; list = list->next) { larg.v_pointer = list->data; ival = (JSValueRef) seed_value_from_gi_argument(ctx, &larg, list_type, exception); if (!ival) ival = JSValueMakeNull(ctx); JSObjectSetPropertyAtIndex(ctx, ret, i, ival, NULL); i++; } return ret; } case GI_TYPE_TAG_GHASH: { GITypeInfo* key_type; GITypeTag key_type_tag; GITypeInfo* value_type; JSObjectRef ret; GHashTable* hash_table; GHashTableIter iter; gpointer key, value; key_type = g_type_info_get_param_type(type_info, 0); key_type_tag = g_type_info_get_tag(key_type); if ((key_type_tag != GI_TYPE_TAG_UTF8) && (key_type_tag != GI_TYPE_TAG_FILENAME)) { seed_make_exception(ctx, exception, "ArgumentError", "Unable to make object from hash table " "indexed with values of type %s", g_type_tag_to_string(key_type_tag)); return JSValueMakeNull(ctx); } hash_table = arg->v_pointer; if (!hash_table) { seed_make_exception( ctx, exception, "ArgumentError", "Unable to make hash table indexed with values of type %s", g_type_tag_to_string(key_type_tag)); return JSValueMakeNull(ctx); } value_type = g_type_info_get_param_type(type_info, 1); ret = JSObjectMake(ctx, NULL, NULL); g_hash_table_iter_init(&iter, hash_table); while (g_hash_table_iter_next(&iter, &key, &value)) { JSStringRef js_key; GArgument value_arg; JSValueRef value_jsval; js_key = JSStringCreateWithUTF8CString((const char*) key); value_arg.v_string = value; value_jsval = seed_value_from_gi_argument_full(ctx, &value_arg, value_type, exception, 0, key_type_tag); JSObjectSetProperty(ctx, ret, js_key, value_jsval, 0, NULL); } return ret; } case GI_TYPE_TAG_ERROR: { JSValueRef ret; seed_make_exception_from_gerror(ctx, &ret, (GError*) arg->v_pointer); return ret; } default: return FALSE; } return 0; } JSValueRef seed_value_from_gvalue_for_signal(JSContextRef ctx, GValue* gval, JSValueRef* exception, GSignalQuery* signal_query, gint arg_n) { if (!G_IS_VALUE(gval)) { return false; } switch (G_VALUE_TYPE(gval)) { case G_TYPE_BOOLEAN: return seed_value_from_boolean(ctx, g_value_get_boolean(gval), exception); case G_TYPE_CHAR: return seed_value_from_char(ctx, g_value_get_schar(gval), exception); case G_TYPE_UCHAR: return seed_value_from_uchar(ctx, g_value_get_uchar(gval), exception); case G_TYPE_INT: return seed_value_from_int(ctx, g_value_get_int(gval), exception); case G_TYPE_UINT: return seed_value_from_uint(ctx, g_value_get_uint(gval), exception); case G_TYPE_LONG: return seed_value_from_long(ctx, g_value_get_long(gval), exception); case G_TYPE_ULONG: return seed_value_from_ulong(ctx, g_value_get_ulong(gval), exception); case G_TYPE_INT64: return seed_value_from_int64(ctx, g_value_get_int64(gval), exception); case G_TYPE_UINT64: return seed_value_from_uint64(ctx, g_value_get_uint64(gval), exception); case G_TYPE_FLOAT: return seed_value_from_float(ctx, g_value_get_float(gval), exception); case G_TYPE_DOUBLE: return seed_value_from_double(ctx, g_value_get_double(gval), exception); case G_TYPE_STRING: return seed_value_from_string(ctx, (gchar*) g_value_get_string(gval), exception); case G_TYPE_POINTER: if (signal_query) { JSValueRef res; GArgument arg; GIBaseInfo* obj; GISignalInfo* signal_info; GIArgInfo* arg_info; GITypeInfo type_info; obj = g_irepository_find_by_gtype(NULL, signal_query->itype); if (!obj) return NULL; signal_info = g_object_info_find_signal((GIObjectInfo*) obj, signal_query->signal_name); if (!signal_info) { g_base_info_unref((GIBaseInfo*) obj); return NULL; } arg_info = g_callable_info_get_arg(signal_info, arg_n - 1); g_arg_info_load_type(arg_info, &type_info); arg.v_pointer = g_value_get_pointer(gval); res = seed_value_from_gi_argument(ctx, &arg, &type_info, exception); g_base_info_unref((GIBaseInfo*) arg_info); g_base_info_unref((GIBaseInfo*) signal_info); g_base_info_unref((GIBaseInfo*) obj); return res; } else { return seed_make_pointer(ctx, g_value_get_pointer(gval)); } case G_TYPE_PARAM: // Might need to dup and make a boxed. return seed_make_pointer(ctx, g_value_get_param(gval)); } if (g_type_is_a(G_VALUE_TYPE(gval), G_TYPE_STRV)) { return seed_value_from_strv(ctx, (GStrv*) g_value_get_boxed(gval), exception); } if (g_type_is_a(G_VALUE_TYPE(gval), G_TYPE_ENUM) || g_type_is_a(G_VALUE_TYPE(gval), G_TYPE_FLAGS)) return seed_value_from_long(ctx, gval->data[0].v_long, exception); else if (g_type_is_a(G_VALUE_TYPE(gval), G_TYPE_ENUM)) return seed_value_from_long(ctx, gval->data[0].v_long, exception); else if (g_type_is_a(G_VALUE_TYPE(gval), G_TYPE_OBJECT)) { GObject* obj = g_value_get_object(gval); return seed_value_from_object(ctx, obj, exception); } else { GIBaseInfo* info; GIInfoType type; info = g_irepository_find_by_gtype(0, G_VALUE_TYPE(gval)); if (!info) return FALSE; type = g_base_info_get_type(info); if (type == GI_INFO_TYPE_UNION) { return seed_make_union(ctx, g_value_peek_pointer(gval), info); } else if (type == GI_INFO_TYPE_STRUCT) { return seed_make_struct(ctx, g_value_peek_pointer(gval), info); } else if (type == GI_INFO_TYPE_BOXED) { return seed_make_boxed(ctx, g_value_dup_boxed(gval), info); } } return NULL; } JSValueRef seed_value_from_gvalue(JSContextRef ctx, GValue* gval, JSValueRef* exception) { return seed_value_from_gvalue_for_signal(ctx, gval, exception, NULL, 0); } gboolean seed_value_to_gvalue(JSContextRef ctx, JSValueRef val, GType type, GValue* ret, JSValueRef* exception) { if (G_IS_VALUE(ret)) g_value_unset(ret); if (type == G_TYPE_STRV) { gchar** result; JSValueRef jslen; guint length, i; if (JSValueIsNull(ctx, val) || !JSValueIsObject(ctx, val)) return FALSE; jslen = seed_object_get_property(ctx, (JSObjectRef) val, "length"); length = seed_value_to_uint(ctx, jslen, exception); result = g_new0(gchar*, length + 1); for (i = 0; i < length; i++) { result[i] = seed_value_to_string( ctx, JSObjectGetPropertyAtIndex(ctx, (JSObjectRef) val, i, exception), exception); } result[i] = 0; g_value_init(ret, G_TYPE_STRV); g_value_take_boxed(ret, result); return TRUE; } else if (g_type_is_a(type, G_TYPE_ENUM) && JSValueIsNumber(ctx, val)) { g_value_init(ret, type); g_value_set_enum(ret, seed_value_to_long(ctx, val, exception)); return TRUE; } else if (g_type_is_a(type, G_TYPE_FLAGS) && JSValueIsNumber(ctx, val)) { g_value_init(ret, type); g_value_set_flags(ret, seed_value_to_long(ctx, val, exception)); return TRUE; } else if (g_type_is_a(type, G_TYPE_OBJECT) && (JSValueIsNull(ctx, val) || seed_value_is_gobject(ctx, val))) { GObject* o = seed_value_to_object(ctx, val, exception); if (o == NULL || g_type_is_a(G_OBJECT_TYPE(o), type)) { g_value_init(ret, type); g_value_set_object(ret, o); return TRUE; } } /* Boxed handling is broken. Will be fixed in struct overhall. */ else if (g_type_is_a(type, G_TYPE_BOXED)) { gpointer p = seed_pointer_get_pointer(ctx, val); if (p) { g_value_init(ret, type); g_value_set_boxed(ret, p); return TRUE; } else { if (JSValueIsObject(ctx, val)) { GIBaseInfo* info = g_irepository_find_by_gtype(0, type); JSObjectRef new_struct; if (!info) return FALSE; new_struct = seed_construct_struct_type_with_parameters( ctx, info, (JSObjectRef) val, exception); p = seed_pointer_get_pointer(ctx, new_struct); if (p) { g_value_init(ret, type); g_value_set_boxed(ret, p); g_base_info_unref(info); return TRUE; } g_base_info_unref(info); } } } else if (g_type_is_a(type, G_TYPE_VARIANT)) { gpointer p = seed_pointer_get_pointer(ctx, val); if (p) { g_value_init(ret, type); g_value_set_variant(ret, p); return TRUE; } else { g_critical("Couldn't not convert to GVariant. Probably something is not implemented"); } } switch (type) { case G_TYPE_BOOLEAN: { g_value_init(ret, G_TYPE_BOOLEAN); g_value_set_boolean(ret, seed_value_to_boolean(ctx, val, exception)); return TRUE; } case G_TYPE_INT: case G_TYPE_UINT: { g_value_init(ret, type); if (type == G_TYPE_INT) g_value_set_int(ret, seed_value_to_int(ctx, val, exception)); else g_value_set_uint(ret, seed_value_to_uint(ctx, val, exception)); return TRUE; } case G_TYPE_CHAR: { g_value_init(ret, G_TYPE_CHAR); g_value_set_schar(ret, seed_value_to_char(ctx, val, exception)); return TRUE; } case G_TYPE_UCHAR: { g_value_init(ret, G_TYPE_UCHAR); g_value_set_uchar(ret, seed_value_to_uchar(ctx, val, exception)); return TRUE; } case G_TYPE_LONG: case G_TYPE_ULONG: case G_TYPE_INT64: case G_TYPE_UINT64: case G_TYPE_FLOAT: case G_TYPE_DOUBLE: { switch (type) { case G_TYPE_LONG: g_value_init(ret, G_TYPE_LONG); g_value_set_long(ret, seed_value_to_long(ctx, val, exception)); break; case G_TYPE_ULONG: g_value_init(ret, G_TYPE_ULONG); g_value_set_ulong(ret, seed_value_to_ulong(ctx, val, exception)); break; case G_TYPE_INT64: g_value_init(ret, G_TYPE_INT64); g_value_set_int64(ret, seed_value_to_int64(ctx, val, exception)); break; case G_TYPE_UINT64: g_value_init(ret, G_TYPE_UINT64); g_value_set_uint64(ret, seed_value_to_uint64(ctx, val, exception)); break; case G_TYPE_FLOAT: g_value_init(ret, G_TYPE_FLOAT); g_value_set_float(ret, seed_value_to_float(ctx, val, exception)); break; case G_TYPE_DOUBLE: g_value_init(ret, G_TYPE_DOUBLE); g_value_set_double(ret, seed_value_to_double(ctx, val, exception)); break; } return TRUE; } case G_TYPE_STRING: { gchar* cval = seed_value_to_string(ctx, val, exception); g_value_init(ret, G_TYPE_STRING); g_value_take_string(ret, cval); return TRUE; } default: { // TODO: FIXME: This whole undefined type area // needs some heaaavy improvement. if (type == 0 && seed_value_is_gobject(ctx, val)) { GObject* o = seed_value_to_object(ctx, val, exception); g_value_init(ret, G_OBJECT_TYPE(o)); g_value_set_object(ret, o); return TRUE; } // Support [GObject.TYPE_INT, 3] // TODO: FIXME: Might crash. else if (type == 0 && JSValueIsObject(ctx, val)) { // TODO: FIXME: Better array test like the cool one on reddit. guint length = seed_value_to_int( ctx, seed_object_get_property(ctx, (JSObjectRef) val, "length"), exception); if (length) { type = seed_value_to_int( ctx, JSObjectGetPropertyAtIndex(ctx, (JSObjectRef) val, 0, exception), exception); val = JSObjectGetPropertyAtIndex(ctx, (JSObjectRef) val, 1, exception); if (type) // Prevents recursion. { return seed_value_to_gvalue(ctx, val, type, ret, exception); } // TODO: FIXME: Handle better? else g_assert_not_reached(); } } switch (JSValueGetType(ctx, val)) { case kJSTypeBoolean: { g_value_init(ret, G_TYPE_BOOLEAN); g_value_set_boolean(ret, seed_value_to_boolean(ctx, val, exception)); return TRUE; } case kJSTypeNumber: { g_value_init(ret, G_TYPE_DOUBLE); g_value_set_double(ret, seed_value_to_double(ctx, val, exception)); return TRUE; } case kJSTypeString: { gchar* cv = seed_value_to_string(ctx, val, exception); g_value_init(ret, G_TYPE_STRING); g_value_take_string(ret, cv); return TRUE; } default: break; } break; } } return FALSE; } /** * seed_object_get_property * @ctx: A #SeedContext * @object: A #SeedObject * @name: The property to get, should be a valid JavaScript identifier * * Returns: The value of the property or the undefined value */ JSValueRef seed_object_get_property(JSContextRef ctx, JSObjectRef val, const gchar* name) { JSStringRef jname = JSStringCreateWithUTF8CString(name); JSValueRef ret = JSObjectGetProperty(ctx, (JSObjectRef) val, jname, NULL); JSStringRelease(jname); return ret; } /** * seed_object_set_property * @ctx: A #SeedContext * @object: A #SeedObject * @name: The property to set, should be a valid JavaScript identifier * @value: The value to set the property to. * * Returns: %TRUE on success, %FALSE otherwise. */ gboolean seed_object_set_property(JSContextRef ctx, JSObjectRef object, const gchar* name, JSValueRef value) { JSStringRef jname = JSStringCreateWithUTF8CString(name); JSValueRef exception = NULL; if (value) { JSObjectSetProperty(ctx, (JSObjectRef) object, jname, value, 0, &exception); } JSStringRelease(jname); return TRUE; } /* TODO: Make some macros or something for making exceptions, code is littered with annoyingness right now */ /** * seed_value_to_boolean: * @ctx: A #SeedContext. * @val: The #SeedValue to convert. * @exception: A reference to a #SeedValue in which to store any exceptions. * Pass %NULL to ignore exceptions. * * Converts the given #SeedValue into a #gboolean. Keep in mind that this will * not convert a JavaScript number type, only a boolean. * * Return value: The #gboolean represented by @val. * */ gboolean seed_value_to_boolean(JSContextRef ctx, JSValueRef val, JSValueRef* exception) { if (!JSValueIsBoolean(ctx, val) && !JSValueIsNumber(ctx, val)) { if (!JSValueIsNull(ctx, val) && !JSValueIsUndefined(ctx, val)) { seed_make_exception(eng->context, exception, "ConversionError", "Can not convert Javascript value to boolean"); return FALSE; } return FALSE; } return JSValueToBoolean(ctx, val); } /** * seed_value_from_boolean: * @ctx: A #SeedContext. * @val: The #gboolean to represent. * @exception: A reference to a #SeedValue in which to store any exceptions. * Pass %NULL to ignore exceptions. * * Converts the given #gboolean into a #SeedValue. * * Return value: A #SeedValue which represents @val. * */ JSValueRef seed_value_from_boolean(JSContextRef ctx, gboolean val, JSValueRef* exception) { return JSValueMakeBoolean(ctx, val); } /** * seed_value_to_uint: * @ctx: A #SeedContext. * @val: The #SeedValue to convert. * @exception: A reference to a #SeedValue in which to store any exceptions. * Pass %NULL to ignore exceptions. * * Converts the given #SeedValue into a #guint. * * Return value: The #guint represented by @val. * */ guint seed_value_to_uint(JSContextRef ctx, JSValueRef val, JSValueRef* exception) { if (!JSValueIsNumber(ctx, val) && !JSValueIsBoolean(ctx, val)) { if (!JSValueIsNull(ctx, val)) { seed_make_exception(ctx, exception, "ConversionError", "Can not convert Javascript value to" " boolean"); } return 0; } return (guint) JSValueToNumber(ctx, val, NULL); } /** * seed_value_from_uint: * @ctx: A #SeedContext. * @val: The #guint to represent. * @exception: A reference to a #SeedValue in which to store any exceptions. * Pass %NULL to ignore exceptions. * * Converts the given #guint into a #SeedValue. * * Return value: A #SeedValue which represents @val. * */ JSValueRef seed_value_from_uint(JSContextRef ctx, guint val, JSValueRef* exception) { return JSValueMakeNumber(ctx, (gdouble) val); } /** * seed_value_to_int: * @ctx: A #SeedContext. * @val: The #SeedValue to convert. * @exception: A reference to a #SeedValue in which to store any exceptions. * Pass %NULL to ignore exceptions. * * Converts the given #SeedValue into a #gint. * * Return value: The #gint represented by @val. * */ gint seed_value_to_int(JSContextRef ctx, JSValueRef val, JSValueRef* exception) { if (!JSValueIsNumber(ctx, val) && !JSValueIsBoolean(ctx, val)) { if (!JSValueIsNull(ctx, val)) seed_make_exception(ctx, exception, "ConversionError", "Can not convert Javascript value to" " int"); return 0; } return (gint) JSValueToNumber(ctx, val, NULL); } /** * seed_value_from_int: * @ctx: A #SeedContext. * @val: The #gint to represent. * @exception: A reference to a #SeedValue in which to store any exceptions. * Pass %NULL to ignore exceptions. * * Converts the given #gint into a #SeedValue. * * Return value: A #SeedValue which represents @val. * */ JSValueRef seed_value_from_int(JSContextRef ctx, gint val, JSValueRef* exception) { return JSValueMakeNumber(ctx, (gdouble) val); } /** * seed_value_to_char: * @ctx: A #SeedContext. * @val: The #SeedValue to convert. * @exception: A reference to a #SeedValue in which to store any exceptions. * Pass %NULL to ignore exceptions. * * Converts the given #SeedValue into a #gchar. * * Return value: The #gchar represented by @val. * */ gchar seed_value_to_char(JSContextRef ctx, JSValueRef val, JSValueRef* exception) { gint cv; if (!JSValueIsNumber(ctx, val)) { if (!JSValueIsNull(ctx, val)) seed_make_exception(ctx, exception, "ConversionError", "Can not convert Javascript value to" " gchar"); return 0; } cv = JSValueToNumber(ctx, val, NULL); if (cv < G_MININT8 || cv > G_MAXINT8) { seed_make_exception(ctx, exception, "ConversionError", "Javascript number out of range of gchar"); return 0; } return (gchar) cv; } /** * seed_value_from_char: * @ctx: A #SeedContext. * @val: The #gchar to represent. * @exception: A reference to a #SeedValue in which to store any exceptions. * Pass %NULL to ignore exceptions. * * Converts the given #gchar into a #SeedValue. * * Return value: A #SeedValue which represents @val. * */ JSValueRef seed_value_from_char(JSContextRef ctx, gchar val, JSValueRef* exception) { return JSValueMakeNumber(ctx, (gdouble) val); } /** * seed_value_to_uchar: * @ctx: A #SeedContext. * @val: The #SeedValue to convert. * @exception: A reference to a #SeedValue in which to store any exceptions. * Pass %NULL to ignore exceptions. * * Converts the given #SeedValue into a #guchar. * * Return value: The #guchar represented by @val. * */ guchar seed_value_to_uchar(JSContextRef ctx, JSValueRef val, JSValueRef* exception) { guint cv; if (!JSValueIsNumber(ctx, val)) { if (!JSValueIsNull(ctx, val)) seed_make_exception(ctx, exception, "ConversionError", "Can not convert Javascript value to" " guchar"); return 0; } cv = JSValueToNumber(ctx, val, NULL); if (cv > G_MAXUINT8) { seed_make_exception(ctx, exception, "ConversionError", "Javascript number out of range of guchar"); return 0; } return (guchar) cv; } /** * seed_value_from_uchar: * @ctx: A #SeedContext. * @val: The #guchar to represent. * @exception: A reference to a #SeedValue in which to store any exceptions. * Pass %NULL to ignore exceptions. * * Converts the given #guchar into a #SeedValue. * * Return value: A #SeedValue which represents @val. * */ JSValueRef seed_value_from_uchar(JSContextRef ctx, guchar val, JSValueRef* exception) { return JSValueMakeNumber(ctx, (gdouble) val); } /** * seed_value_to_short: * @ctx: A #SeedContext. * @val: The #SeedValue to convert. * @exception: A reference to a #SeedValue in which to store any exceptions. * Pass %NULL to ignore exceptions. * * Converts the given #SeedValue into a #gshort. * * Return value: The #gshort represented by @val. * */ gshort seed_value_to_short(JSContextRef ctx, JSValueRef val, JSValueRef* exception) { if (!JSValueIsNumber(ctx, val) && !JSValueIsBoolean(ctx, val)) { if (!JSValueIsNull(ctx, val)) seed_make_exception(ctx, exception, "ConversionError", "Can not convert Javascript value to" " short"); return 0; } return (gshort) JSValueToNumber(ctx, val, NULL); } /** * seed_value_from_short: * @ctx: A #SeedContext. * @val: The #gshort to represent. * @exception: A reference to a #SeedValue in which to store any exceptions. * Pass %NULL to ignore exceptions. * * Converts the given #gshort into a #SeedValue. * * Return value: A #SeedValue which represents @val. * */ JSValueRef seed_value_from_short(JSContextRef ctx, gshort val, JSValueRef* exception) { return JSValueMakeNumber(ctx, (gdouble) val); } /** * seed_value_to_ushort: * @ctx: A #SeedContext. * @val: The #SeedValue to convert. * @exception: A reference to a #SeedValue in which to store any exceptions. * Pass %NULL to ignore exceptions. * * Converts the given #SeedValue into a #gushort. * * Return value: The #gushort represented by @val. * */ gushort seed_value_to_ushort(JSContextRef ctx, JSValueRef val, JSValueRef* exception) { if (!JSValueIsNumber(ctx, val) && !JSValueIsBoolean(ctx, val)) { if (!JSValueIsNull(ctx, val)) seed_make_exception(ctx, exception, "ConversionError", "Can not convert Javascript value to" " ushort"); return 0; } return (gushort) JSValueToNumber(ctx, val, NULL); } /** * seed_value_from_ushort: * @ctx: A #SeedContext. * @val: The #gushort to represent. * @exception: A reference to a #SeedValue in which to store any exceptions. * Pass %NULL to ignore exceptions. * * Converts the given #gushort into a #SeedValue. * * Return value: A #SeedValue which represents @val. * */ JSValueRef seed_value_from_ushort(JSContextRef ctx, gushort val, JSValueRef* exception) { return JSValueMakeNumber(ctx, (gdouble) val); } /** * seed_value_to_long: * @ctx: A #SeedContext. * @val: The #SeedValue to convert. * @exception: A reference to a #SeedValue in which to store any exceptions. * Pass %NULL to ignore exceptions. * * Converts the given #SeedValue into a #glong. * * Return value: The #glong represented by @val. * */ glong seed_value_to_long(JSContextRef ctx, JSValueRef val, JSValueRef* exception) { if (!JSValueIsNumber(ctx, val) && !JSValueIsBoolean(ctx, val)) { if (!JSValueIsNull(ctx, val)) seed_make_exception(ctx, exception, "ConversionError", "Can not convert Javascript value to" " long"); return 0; } return (glong) JSValueToNumber(ctx, val, NULL); } /** * seed_value_from_long: * @ctx: A #SeedContext. * @val: The #glong to represent. * @exception: A reference to a #SeedValue in which to store any exceptions. * Pass %NULL to ignore exceptions. * * Converts the given #glong into a #SeedValue. * * Return value: A #SeedValue which represents @val. * */ JSValueRef seed_value_from_long(JSContextRef ctx, glong val, JSValueRef* exception) { return JSValueMakeNumber(ctx, (gdouble) val); } /** * seed_value_to_ulong: * @ctx: A #SeedContext. * @val: The #SeedValue to convert. * @exception: A reference to a #SeedValue in which to store any exceptions. * Pass %NULL to ignore exceptions. * * Converts the given #SeedValue into a #gulong. * * Return value: The #gulong represented by @val. * */ gulong seed_value_to_ulong(JSContextRef ctx, JSValueRef val, JSValueRef* exception) { if (!JSValueIsNumber(ctx, val)) { if (!JSValueIsNull(ctx, val)) seed_make_exception(ctx, exception, "ConversionError", "Can not convert Javascript value to" " ulong"); return 0; } return (gulong) JSValueToNumber(ctx, val, NULL); } /** * seed_value_from_ulong: * @ctx: A #SeedContext. * @val: The #gulong to represent. * @exception: A reference to a #SeedValue in which to store any exceptions. * Pass %NULL to ignore exceptions. * * Converts the given #gulong into a #SeedValue. * * Return value: A #SeedValue which represents @val. * */ JSValueRef seed_value_from_ulong(JSContextRef ctx, gulong val, JSValueRef* exception) { return JSValueMakeNumber(ctx, (gdouble) val); } /** * seed_value_to_int64: * @ctx: A #SeedContext. * @val: The #SeedValue to convert. * @exception: A reference to a #SeedValue in which to store any exceptions. * Pass %NULL to ignore exceptions. * * Converts the given #SeedValue into a #gint64. * * Return value: The #gint64 represented by @val. * */ gint64 seed_value_to_int64(JSContextRef ctx, JSValueRef val, JSValueRef* exception) { if (!JSValueIsNumber(ctx, val) && !JSValueIsBoolean(ctx, val)) { if (!JSValueIsNull(ctx, val)) seed_make_exception(ctx, exception, "ConversionError", "Can not convert Javascript value to" " gint64"); return 0; } return (gint64) JSValueToNumber(ctx, val, NULL); } /** * seed_value_from_int64: * @ctx: A #SeedContext. * @val: The #gint64 to represent. * @exception: A reference to a #SeedValue in which to store any exceptions. * Pass %NULL to ignore exceptions. * * Converts the given #gint64 into a #SeedValue. * * Return value: A #SeedValue which represents @val. * */ JSValueRef seed_value_from_int64(JSContextRef ctx, gint64 val, JSValueRef* exception) { return JSValueMakeNumber(ctx, (gdouble) val); } /** * seed_value_to_uint64: * @ctx: A #SeedContext. * @val: The #SeedValue to convert. * @exception: A reference to a #SeedValue in which to store any exceptions. * Pass %NULL to ignore exceptions. * * Converts the given #SeedValue into a #guint64. * * Return value: The #guint64 represented by @val. * */ guint64 seed_value_to_uint64(JSContextRef ctx, JSValueRef val, JSValueRef* exception) { if (!JSValueIsNumber(ctx, val) && !JSValueIsBoolean(ctx, val)) { if (!JSValueIsNull(ctx, val)) seed_make_exception(ctx, exception, "ConversionError", "Can not convert Javascript value to" " guint64"); return 0; } return (guint64) JSValueToNumber(ctx, val, NULL); } /** * seed_value_from_uint64: * @ctx: A #SeedContext. * @val: The #guint64 to represent. * @exception: A reference to a #SeedValue in which to store any exceptions. * Pass %NULL to ignore exceptions. * * Converts the given #guint64 into a #SeedValue. * * Return value: A #SeedValue which represents @val. * */ JSValueRef seed_value_from_uint64(JSContextRef ctx, guint64 val, JSValueRef* exception) { return JSValueMakeNumber(ctx, (gdouble) val); } /** * seed_value_to_float: * @ctx: A #SeedContext. * @val: The #SeedValue to convert. * @exception: A reference to a #SeedValue in which to store any exceptions. * Pass %NULL to ignore exceptions. * * Converts the given #SeedValue into a #gfloat. * * Return value: The #gfloat represented by @val. * */ gfloat seed_value_to_float(JSContextRef ctx, JSValueRef val, JSValueRef* exception) { if (!JSValueIsNumber(ctx, val)) { if (!JSValueIsNull(ctx, val)) seed_make_exception(ctx, exception, "ConversionError", "Can not convert Javascript value to" " gfloat"); return 0; } return (gfloat) JSValueToNumber(ctx, val, NULL); } /** * seed_value_from_float: * @ctx: A #SeedContext. * @val: The #gfloat to represent. * @exception: A reference to a #SeedValue in which to store any exceptions. * Pass %NULL to ignore exceptions. * * Converts the given #gfloat into a #SeedValue. * * Return value: A #SeedValue which represents @val. * */ JSValueRef seed_value_from_float(JSContextRef ctx, gfloat val, JSValueRef* exception) { return JSValueMakeNumber(ctx, (gdouble) val); } /** * seed_value_to_double: * @ctx: A #SeedContext. * @val: The #SeedValue to convert. * @exception: A reference to a #SeedValue in which to store any exceptions. * Pass %NULL to ignore exceptions. * * Converts the given #SeedValue into a #gdouble. * * Return value: The #gdouble represented by @val. * */ gdouble seed_value_to_double(JSContextRef ctx, JSValueRef val, JSValueRef* exception) { if (!JSValueIsNumber(ctx, val)) { if (!JSValueIsNull(ctx, val)) seed_make_exception(ctx, exception, "ConversionError", "Can not convert Javascript value to" " double"); return 0; } return (gdouble) JSValueToNumber(ctx, val, NULL); } /** * seed_value_from_double: * @ctx: A #SeedContext. * @val: The #gdouble to represent. * @exception: A reference to a #SeedValue in which to store any exceptions. * Pass %NULL to ignore exceptions. * * Converts the given #gdouble into a #SeedValue. * * Return value: A #SeedValue which represents @val. * */ JSValueRef seed_value_from_double(JSContextRef ctx, gdouble val, JSValueRef* exception) { return JSValueMakeNumber(ctx, (gdouble) val); } /** * seed_value_to_size: * @ctx: A #SeedContext. * @val: The #SeedValue to convert. * @exception: A reference to a #SeedValue in which to store any exceptions. * Pass %NULL to ignore exceptions. * * Converts the given #SeedValue into a #gsize. * * Return value: The #gsize represented by @val. * */ gsize seed_value_to_size(JSContextRef ctx, JSValueRef val, JSValueRef* exception) { if (!JSValueIsNumber(ctx, val) && !JSValueIsBoolean(ctx, val)) { if (!JSValueIsNull(ctx, val)) seed_make_exception(ctx, exception, "ConversionError", "Can not convert Javascript value to" " gsize"); return 0; } return (gsize) JSValueToNumber(ctx, val, NULL); } /** * seed_value_from_size: * @ctx: A #SeedContext. * @val: The #gsize to represent. * @exception: A reference to a #SeedValue in which to store any exceptions. * Pass %NULL to ignore exceptions. * * Converts the given #gsize into a #SeedValue. * * Return value: A #SeedValue which represents @val. * */ JSValueRef seed_value_from_size(JSContextRef ctx, gsize val, JSValueRef* exception) { return JSValueMakeNumber(ctx, (gdouble) val); } /** * seed_value_to_ssize: * @ctx: A #SeedContext. * @val: The #SeedValue to convert. * @exception: A reference to a #SeedValue in which to store any exceptions. * Pass %NULL to ignore exceptions. * * Converts the given #SeedValue into a #gssize. * * Return value: The #gssize represented by @val. * */ gssize seed_value_to_ssize(JSContextRef ctx, JSValueRef val, JSValueRef* exception) { if (!JSValueIsNumber(ctx, val) && !JSValueIsBoolean(ctx, val)) { if (!JSValueIsNull(ctx, val)) seed_make_exception(ctx, exception, "ConversionError", "Can not convert Javascript value to" " gssize"); return 0; } return (gssize) JSValueToNumber(ctx, val, NULL); } /** * seed_value_from_ssize: * @ctx: A #SeedContext. * @val: The #gssize to represent. * @exception: A reference to a #SeedValue in which to store any exceptions. * Pass %NULL to ignore exceptions. * * Converts the given #gssize into a #SeedValue. * * Return value: A #SeedValue which represents @val. * */ JSValueRef seed_value_from_ssize(JSContextRef ctx, gssize val, JSValueRef* exception) { return JSValueMakeNumber(ctx, (gdouble) val); } /** * seed_value_to_string: * @ctx: A #SeedContext. * @val: The #SeedValue to convert. * @exception: A reference to a #SeedValue in which to store any exceptions. * Pass %NULL to ignore exceptions. * * Converts the given #SeedValue into a #gchar* string. Keep in mind that it's * up to the caller to free the string. * * If the #SeedValue represents JavaScript's undefined value, this returns * "[undefined]"; if it represents JavaScript's null value, this returns * "[null]". * * If the #SeedValue is a number or a boolean, it is printed as a double, with * the printf format string "%.15g". * * If the #SeedValue is an object, the string returned is that obtained by * calling .toString() on said object. * * Return value: The #gchar* represented by @val. * */ gchar* seed_value_to_string(JSContextRef ctx, JSValueRef val, JSValueRef* exception) { JSStringRef jsstr = NULL; JSValueRef func; gchar* buf = NULL; gint length; if (val == NULL) return NULL; else if (JSValueIsUndefined(ctx, val)) { buf = g_strdup("[undefined]"); } else if (JSValueIsNull(ctx, val)) { buf = g_strdup("[null]"); } else if (JSValueIsBoolean(ctx, val) || JSValueIsNumber(ctx, val)) { buf = g_strdup_printf("%.15g", JSValueToNumber(ctx, val, NULL)); } else { if (!JSValueIsString(ctx, val)) // In this case, // it's an object { func = seed_object_get_property(ctx, (JSObjectRef) val, "toString"); if (!JSValueIsNull(ctx, func) && JSValueIsObject(ctx, func) && JSObjectIsFunction(ctx, (JSObjectRef) func)) // str = ... we dump the return value!?! JSObjectCallAsFunction(ctx, (JSObjectRef) func, (JSObjectRef) val, 0, NULL, NULL); } jsstr = JSValueToStringCopy(ctx, val, NULL); length = JSStringGetMaximumUTF8CStringSize(jsstr); if (length > 0) { buf = g_malloc(length * sizeof(gchar)); JSStringGetUTF8CString(jsstr, buf, length); } if (jsstr) JSStringRelease(jsstr); } return buf; } /** * seed_value_from_string: * @ctx: A #SeedContext. * @val: The #gchar* to represent. * @exception: A reference to a #SeedValue in which to store any exceptions. * Pass %NULL to ignore exceptions. * * Converts the given #gchar* string into a #SeedValue. * * Return value: A #SeedValue which represents @val. * */ JSValueRef seed_value_from_string(JSContextRef ctx, const gchar* val, JSValueRef* exception) { if (val == NULL) return JSValueMakeNull(ctx); else { JSStringRef jsstr = JSStringCreateWithUTF8CString(val); JSValueRef valstr = JSValueMakeString(ctx, jsstr); JSStringRelease(jsstr); return valstr; } } /** * seed_value_from_binary_string: * @ctx: A #SeedContext. * @bytes: A string of bytes to represent as a string. * @n_bytes: The number of bytes from @bytes to convert. * @exception: A reference to a #SeedValue in which to store any exceptions. * Pass %NULL to ignore exceptions. * * Converts a string representation of the given binary string * into a #SeedValue. * * FIXME - should use BinaryArray really * * Return value: A #SeedValue which represents @bytes as a string. * */ JSValueRef seed_value_from_binary_string(JSContextRef ctx, const gchar* bytes, gint n_bytes, JSValueRef* exception) { JSStringRef jsstr; JSValueRef valstr; JSChar* jchar; gint i; SEED_NOTE(INVOCATION, "Creating binary string of length %d ", n_bytes); if (bytes == NULL) { return JSValueMakeNull(ctx); } jchar = g_new0(JSChar, n_bytes); for (i = 0; i < n_bytes; i++) { jchar[i] = bytes[i]; } // this may leak... jsstr = JSStringCreateWithCharacters((const JSChar*) jchar, n_bytes); valstr = JSValueMakeString(ctx, jsstr); g_free(jchar); JSStringRelease(jsstr); return valstr; } /** * seed_value_to_filename: * @ctx: A #SeedContext. * @val: The #SeedValue to convert. * @exception: A reference to a #SeedValue in which to store any exceptions. * Pass %NULL to ignore exceptions. * * Converts the given #SeedValue into a #gchar*, properly converting to the * character set used for filenames on the local machine. * * Return value: The #gchar* represented by @val, or %NULL if an exception * is raised during the conversion. * */ gchar* seed_value_to_filename(JSContextRef ctx, JSValueRef val, JSValueRef* exception) { GError* e = NULL; gchar* utf8 = seed_value_to_string(ctx, val, exception); gchar* filename; filename = g_filename_from_utf8(utf8, -1, NULL, NULL, &e); g_free(utf8); if (e) { seed_make_exception_from_gerror(ctx, exception, e); g_error_free(e); return NULL; } return filename; } /** * seed_value_from_filename: * @ctx: A #SeedContext. * @val: The #gchar* filename to represent. * @exception: A reference to a #SeedValue in which to store any exceptions. * Pass %NULL to ignore exceptions. * * Converts the given #gchar* filename into a #SeedValue, respecting the * character set used for filenames on the local machine. * * Return value: A #SeedValue which represents @val. * */ JSValueRef seed_value_from_filename(JSContextRef ctx, const gchar* val, JSValueRef* exception) { GError* e = NULL; gchar* utf8; if (val == NULL) return JSValueMakeNull(ctx); else { utf8 = g_filename_to_utf8(val, -1, NULL, NULL, &e); if (e) { seed_make_exception_from_gerror(ctx, exception, e); g_error_free(e); return JSValueMakeNull(ctx); } JSValueRef valstr = seed_value_from_string(ctx, utf8, exception); g_free(utf8); return valstr; } } /** * seed_value_to_object: * @ctx: A #SeedContext. * @val: The #SeedValue to unwrap. * @exception: A reference to a #SeedValue in which to store any exceptions. * Pass %NULL to ignore exceptions. * * Given a #SeedValue which is wrapping a #GObject, retrieve the wrapped * #GObject. * * Return value: The #GObject wrapped within @val, or %NULL if an exception * is raised during the conversion. * */ GObject* seed_value_to_object(JSContextRef ctx, JSValueRef val, JSValueRef* exception) { GObject* gobject; /* * Worth investigating if this is the best way to handle null. Some of * the existing code depends on null Objects not throwing an exception * however, needs testing at higher level if value can be null * (through GI) */ if (JSValueIsNull(ctx, val)) return NULL; if (!seed_value_is_gobject(ctx, val)) { seed_make_exception(ctx, exception, "ConversionError", "Attempt to convert from" " non GObject to GObject"); return NULL; } gobject = (GObject*) JSObjectGetPrivate((JSObjectRef) val); g_assert(G_IS_OBJECT(gobject)); return gobject; } /** * seed_value_from_object: * @ctx: A #SeedContext. * @val: The #GObject to wrap. * @exception: A reference to a #SeedValue in which to store any exceptions. * Pass %NULL to ignore exceptions. * * Wraps @val in a #SeedValue. * * Return value: A #SeedValue which wraps @val. * */ JSValueRef seed_value_from_object(JSContextRef ctx, GObject* val, JSValueRef* exception) { if (val == NULL) return JSValueMakeNull(ctx); else return seed_wrap_object(ctx, val); } gboolean seed_validate_enum(GIEnumInfo* info, long val) { gint n, i; GIValueInfo* value_info; gint value; // TODO: investigate glong/gint mismatch w/ g_value_info_get_value n = g_enum_info_get_n_values(info); for (i = 0; i < n; i++) { value_info = g_enum_info_get_value(info, i); value = g_value_info_get_value(value_info); g_base_info_unref((GIBaseInfo*) value_info); if (value == val) return TRUE; } return FALSE; } JSValueRef seed_value_from_time_t(JSContextRef ctx, time_t time, JSValueRef* exception) { JSValueRef args[1]; args[0] = seed_value_from_double(ctx, ((gdouble) time) * 1000, exception); return JSObjectMakeDate(ctx, 1, args, exception); } time_t seed_value_to_time_t(JSContextRef ctx, JSValueRef value, JSValueRef* exception) { JSValueRef get_time_method; JSValueRef jstime; gdouble time; if (JSValueIsNumber(ctx, value)) { return (unsigned long) seed_value_to_long(ctx, value, exception); } else if (JSValueIsObject(ctx, value)) { get_time_method = seed_object_get_property(ctx, (JSObjectRef) value, "getTime"); if (JSValueIsNull(ctx, get_time_method) || !JSValueIsObject(ctx, get_time_method)) { goto out; } jstime = JSObjectCallAsFunction(ctx, (JSObjectRef) get_time_method, (JSObjectRef) value, 0, NULL, exception); time = seed_value_to_double(ctx, jstime, exception); return (unsigned long) (time / 1000); } out: seed_make_exception(ctx, exception, "TypeError", "Unable to convert JavaScript value to time_t"); return 0; } /** * seed_value_from_strv: * @ctx: A #SeedContext. * @val: The #GStrv to wrap. * @exception: A reference to a #SeedValue in which to store any exceptions. * Pass %NULL to ignore exceptions. * * Wraps @val in a #SeedValue. * * Return value: A #SeedValue which wraps @val. * */ JSValueRef seed_value_from_strv(JSContextRef ctx, GStrv* val, JSValueRef* exception) { GArray* js_string_array = g_array_new(FALSE, FALSE, sizeof(gpointer)); for (; *val != NULL; val++) { JSValueRef js_string = seed_value_from_string(ctx, (char*) *val, exception); js_string_array = g_array_append_val(js_string_array, js_string); } JSValueRef res = JSObjectMakeArray(ctx, js_string_array->len, (JSValueRef*) js_string_array->data, exception); g_array_free(js_string_array, FALSE); return res; } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/libseed/seed-types.h000066400000000000000000000233251303774616400224750ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #ifndef _SEED_TYPES_H #define _SEED_TYPES_H #include "seed-private.h" extern GQuark js_ref_quark; JSValueRef seed_value_from_gvalue(JSContextRef ctx, GValue* gval, JSValueRef* exception); JSValueRef seed_value_from_gvalue_for_signal(JSContextRef ctx, GValue* gval, JSValueRef* exception, GSignalQuery* signal_query, gint arg_n); gboolean seed_value_to_gvalue(JSContextRef ctx, JSValueRef val, GType type, GValue* gval, JSValueRef* exception); JSValueRef seed_object_get_property(JSContextRef ctx, JSObjectRef val, const gchar* name); gboolean seed_object_set_property(JSContextRef ctx, JSObjectRef object, const gchar* name, JSValueRef value); void seed_object_set_property_at_index(JSContextRef ctx, JSObjectRef object, gint index, JSValueRef value, JSValueRef* exception); JSValueRef seed_object_get_property_at_index(JSContextRef ctx, JSObjectRef object, gint index, JSValueRef* exception); gboolean seed_value_to_gi_argument(JSContextRef ctx, JSValueRef value, GITypeInfo* type_info, GITransfer transfer, GArgument* arg, JSValueRef* exception); gboolean seed_value_to_gi_argument_with_out_length(JSContextRef ctx, JSValueRef value, GITypeInfo* type_info, GITransfer transfer, GArgument* arg, guint* out_array_length, JSValueRef* exception); JSValueRef seed_value_from_gi_argument(JSContextRef ctx, GArgument* arg, GITypeInfo* type_info, JSValueRef* exception); JSValueRef seed_value_from_gi_argument_full(JSContextRef ctx, GArgument* arg, GITypeInfo* type_info, JSValueRef* exception, guint64 array_len, GITypeTag gi_tag); gboolean seed_gi_release_arg(GITransfer transfer, GITypeInfo* type_info, GArgument* arg); gboolean seed_gi_release_in_arg(GITransfer transfer, GITypeInfo* type_info, GArgument* arg); gboolean seed_value_to_boolean(JSContextRef ctx, JSValueRef val, JSValueRef* exception); JSValueRef seed_value_from_boolean(JSContextRef ctx, gboolean val, JSValueRef* exception); guint seed_value_to_uint(JSContextRef ctx, JSValueRef val, JSValueRef* exception); JSValueRef seed_value_from_uint(JSContextRef ctx, guint val, JSValueRef* exception); gint seed_value_to_int(JSContextRef ctx, JSValueRef val, JSValueRef* exception); JSValueRef seed_value_from_int(JSContextRef ctx, gint val, JSValueRef* exception); gchar seed_value_to_char(JSContextRef ctx, JSValueRef val, JSValueRef* exception); JSValueRef seed_value_from_char(JSContextRef ctx, gchar val, JSValueRef* exception); guchar seed_value_to_uchar(JSContextRef ctx, JSValueRef val, JSValueRef* exception); JSValueRef seed_value_from_uchar(JSContextRef ctx, guchar val, JSValueRef* exception); glong seed_value_to_long(JSContextRef ctx, JSValueRef val, JSValueRef* exception); JSValueRef seed_value_from_long(JSContextRef ctx, glong val, JSValueRef* exception); gulong seed_value_to_ulong(JSContextRef ctx, JSValueRef val, JSValueRef* exception); JSValueRef seed_value_from_ulong(JSContextRef ctx, gulong val, JSValueRef* exception); gint64 seed_value_to_int64(JSContextRef ctx, JSValueRef val, JSValueRef* exception); JSValueRef seed_value_from_int64(JSContextRef ctx, gint64 val, JSValueRef* exception); guint64 seed_value_to_uint64(JSContextRef ctx, JSValueRef val, JSValueRef* exception); JSValueRef seed_value_from_uint64(JSContextRef ctx, guint64 val, JSValueRef* exception); gfloat seed_value_to_float(JSContextRef ctx, JSValueRef val, JSValueRef* exception); JSValueRef seed_value_from_float(JSContextRef ctx, gfloat val, JSValueRef* exception); gdouble seed_value_to_double(JSContextRef ctx, JSValueRef val, JSValueRef* exception); JSValueRef seed_value_from_double(JSContextRef ctx, gdouble val, JSValueRef* exception); gsize seed_value_to_size(JSContextRef ctx, JSValueRef val, JSValueRef* exception); JSValueRef seed_value_from_size(JSContextRef ctx, gsize val, JSValueRef* exception); gssize seed_value_to_ssize(JSContextRef ctx, JSValueRef val, JSValueRef* exception); JSValueRef seed_value_from_ssize(JSContextRef ctx, gssize val, JSValueRef* exception); gchar* seed_value_to_filename(JSContextRef ctx, JSValueRef val, JSValueRef* exception); JSValueRef seed_value_from_filename(JSContextRef ctx, const gchar* filename, JSValueRef* exception); gchar* seed_value_to_string(JSContextRef ctx, JSValueRef val, JSValueRef* exception); JSValueRef seed_value_from_string(JSContextRef ctx, const gchar* val, JSValueRef* exception); time_t seed_value_to_time_t(JSContextRef ctx, JSValueRef val, JSValueRef* exception); JSValueRef seed_value_from_time_t(JSContextRef ctx, time_t time, JSValueRef* exception); GObject* seed_value_to_object(JSContextRef ctx, JSValueRef val, JSValueRef* exception); JSValueRef seed_value_from_object(JSContextRef ctx, GObject* val, JSValueRef* exception); JSValueRef seed_value_from_strv(JSContextRef ctx, GStrv* val, JSValueRef* exception); void seed_toggle_ref(gpointer data, GObject* object, gboolean is_last_ref); gboolean seed_validate_enum(GIEnumInfo* info, long val); JSValueRef seed_value_from_binary_string(JSContextRef ctx, const gchar* bytes, gint n_bytes, JSValueRef* exception); JSObjectRef seed_make_wrapper_for_type(JSContextRef ctx, GType type); #endif seed-webkit2-4.0.0+20161014+6c77960+dfsg1/libseed/seed.h000066400000000000000000000507151303774616400213360ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #include #include #include #ifndef _SEED_H #define _SEED_H G_BEGIN_DECLS typedef gpointer SeedString; typedef gpointer SeedValue; typedef gpointer SeedObject; typedef gpointer SeedClass; typedef gpointer SeedException; typedef gpointer SeedContext; typedef gpointer SeedGlobalContext; typedef gpointer SeedContextGroup; typedef enum { SEED_TYPE_UNDEFINED, SEED_TYPE_NULL, SEED_TYPE_BOOLEAN, SEED_TYPE_NUMBER, SEED_TYPE_STRING, SEED_TYPE_OBJECT } SeedType; typedef enum { SEED_PROPERTY_ATTRIBUTE_NONE = 0, SEED_PROPERTY_ATTRIBUTE_READ_ONLY = 1 << 1, SEED_PROPERTY_ATTRIBUTE_DONT_ENUM = 1 << 2, SEED_PROPERTY_ATTRIBUTE_DONT_DELETE = 1 << 3 } SeedPropertyAttributes; typedef enum { SEED_CLASS_ATTRIBUTE_NONE = 0, SEED_CLASS_ATTRIBUTE_NO_SHARED_PROTOTYPE = 1 << 1 } SeedClassAttributes; typedef struct _SeedScript SeedScript; typedef struct _SeedEngine { SeedGlobalContext context; SeedValue global; gchar** search_path; SeedContextGroup group; gchar* program_name; gboolean importer_initialized; } SeedEngine; /* * seed-engine.c */ SeedEngine* seed_init(gint* argc, gchar*** argv); SeedEngine* seed_init_with_context(gint* argc, gchar*** argv, SeedGlobalContext context); SeedEngine* seed_init_with_context_group(gint* argc, gchar*** argv, SeedContextGroup group); SeedEngine* seed_init_with_context_and_group(gint* argc, gchar*** argv, SeedGlobalContext context, SeedContextGroup group); SeedEngine* seed_init_constrained(gint* argc, gchar*** argv); SeedEngine* seed_init_constrained_with_context_and_group( gint* argc, gchar*** argv, SeedGlobalContext context, SeedContextGroup group); void seed_init_builtins(SeedEngine* local_eng, gint* argc, gchar*** argv); void seed_engine_destroy(SeedEngine* eng); SeedValue seed_simple_evaluate(SeedContext ctx, gchar* source, SeedException* exception); SeedScript* seed_make_script(SeedContext ctx, const gchar* js, const gchar* source_url, gint line_number); SeedScript* seed_script_new_from_file(SeedContext ctx, gchar* file); SeedException seed_script_exception(SeedScript* s); void seed_script_destroy(SeedScript* s); void seed_make_exception(SeedContext ctx, SeedException exception, const gchar* name, const gchar* message, ...) G_GNUC_PRINTF(4, 5); gchar* seed_exception_get_name(SeedContext ctx, SeedException exception); gchar* seed_exception_get_message(SeedContext ctx, SeedException exception); guint seed_exception_get_line(SeedContext ctx, SeedException exception); gchar* seed_exception_get_file(SeedContext ctx, SeedException exception); gchar* seed_exception_get_stack(SeedContext ctx, SeedException exception); gchar* seed_exception_to_string(SeedContext ctx, SeedException exception); SeedValue seed_evaluate(SeedContext ctx, SeedScript* s, SeedObject this_object); void seed_engine_initialize_importer(SeedEngine *engine); SeedValue seed_engine_expose_gobject(SeedEngine* engine, gchar* js_name, GObject* object, gchar* gir_namespace, SeedException *exception); SeedValue seed_engine_expose_namespace(SeedEngine* engine, gchar* namespace_name, SeedException *exception); GOptionGroup* seed_get_option_group(void); /* * seed-api.c */ SeedGlobalContext seed_context_create(SeedContextGroup group, SeedClass global_class); SeedGlobalContext seed_context_ref(SeedGlobalContext ctx); void seed_context_unref(SeedGlobalContext ctx); void seed_context_collect(SeedGlobalContext ctx); SeedObject seed_context_get_global_object(SeedContext ctx); void seed_importer_add_global(SeedContext ctx, gchar* name); void seed_importer_set_search_path(SeedContext ctx, gchar** search_path); void seed_prepare_global_context(SeedContext ctx); void seed_importer_add_search_path(SeedContext ctx, gchar* search_path); SeedValue seed_make_null(SeedContext ctx); SeedValue seed_make_undefined(SeedContext ctx); SeedString seed_string_ref(SeedString string); void seed_string_unref(SeedString string); gsize seed_string_get_maximum_size(SeedString string); gsize seed_string_to_utf8_buffer(SeedString string, gchar* buffer, size_t buffer_size); gboolean seed_string_is_equal(SeedString a, SeedString b); gboolean seed_string_is_equal_utf8(SeedString a, const gchar* b); gboolean seed_value_is_null(SeedContext ctx, SeedValue value); gboolean seed_value_is_undefined(SeedContext ctx, SeedValue value); gboolean seed_value_is_object(SeedContext ctx, SeedValue value); gboolean seed_value_is_object_of_class(SeedContext ctx, SeedValue value, SeedClass klass); gboolean seed_value_is_function(SeedContext ctx, SeedObject value); gboolean seed_value_is_string(SeedContext ctx, SeedValue value); gboolean seed_value_is_number(SeedContext ctx, SeedValue value); void seed_value_unprotect(SeedContext ctx, SeedValue value); void seed_value_protect(SeedContext ctx, SeedValue value); gboolean seed_value_to_gvalue(SeedContext ctx, SeedValue val, GType type, GValue* gval, SeedException* exception); SeedValue seed_value_from_gvalue(SeedContext ctx, GValue* gval, SeedException* exception); gboolean seed_value_to_gi_argument(SeedContext ctx, SeedValue value, GITypeInfo* type_info, GITransfer transfer, GArgument* arg, SeedValue* exception); SeedValue seed_value_from_gi_argument(SeedContext ctx, GArgument* arg, GITypeInfo* type_info, SeedException* exception); gboolean seed_value_to_boolean(SeedContext ctx, SeedValue val, SeedException* exception); SeedValue seed_value_from_boolean(SeedContext ctx, gboolean val, SeedException* exception); guint seed_value_to_uint(SeedContext ctx, SeedValue val, SeedException* exception); SeedValue seed_value_from_uint(SeedContext ctx, guint val, SeedException* exception); gint seed_value_to_int(SeedContext ctx, SeedValue val, SeedException* exception); SeedValue seed_value_from_int(SeedContext ctx, gint val, SeedException* exception); gchar seed_value_to_char(SeedContext ctx, SeedValue val, SeedException* exception); SeedValue seed_value_from_char(SeedContext ctx, gchar val, SeedException* exception); guchar seed_value_to_uchar(SeedContext ctx, SeedValue val, SeedException* exception); SeedValue seed_value_from_uchar(SeedContext ctx, guchar val, SeedException* exception); glong seed_value_to_long(SeedContext ctx, SeedValue val, SeedException* exception); SeedValue seed_value_from_long(SeedContext ctx, glong val, SeedException* exception); gulong seed_value_to_ulong(SeedContext ctx, SeedValue val, SeedException* exception); SeedValue seed_value_from_ulong(SeedContext ctx, gulong val, SeedException* exception); gint64 seed_value_to_int64(SeedContext ctx, SeedValue val, SeedException* exception); SeedValue seed_value_from_int64(SeedContext ctx, gint64 val, SeedException* exception); guint64 seed_value_to_uint64(SeedContext ctx, SeedValue val, SeedException* exception); SeedValue seed_value_from_uint64(SeedContext ctx, guint64 val, SeedException* exception); gfloat seed_value_to_float(SeedContext ctx, SeedValue val, SeedException* exception); SeedValue seed_value_from_float(SeedContext ctx, gfloat val, SeedException* exception); gdouble seed_value_to_double(SeedContext ctx, SeedValue val, SeedException* exception); SeedValue seed_value_from_double(SeedContext ctx, gdouble val, SeedException* exception); gchar* seed_value_to_string(SeedContext ctx, SeedValue val, SeedException* exception); SeedValue seed_value_from_string(SeedContext ctx, const gchar* val, SeedException* exception); gchar* seed_value_to_filename(SeedContext ctx, SeedValue val, SeedValue* exception); SeedValue seed_value_from_filename(SeedContext ctx, SeedValue val, SeedValue* exception); SeedValue seed_value_from_binary_string(SeedContext ctx, const gchar* bytes, gint n_bytes, SeedException* exception); SeedType seed_value_get_type(SeedContext ctx, SeedValue value); gboolean seed_value_to_format(SeedContext ctx, const gchar* format, SeedValue* values, SeedValue* exception, ...); typedef SeedObject (*SeedModuleInitCallback)(SeedEngine* eng); gboolean seed_object_set_property(SeedContext ctx, SeedObject object, const gchar* name, SeedValue value); SeedValue seed_object_get_property(SeedContext ctx, SeedObject object, const gchar* name); void seed_object_set_property_at_index(SeedContext ctx, SeedObject object, gint index, SeedValue value, SeedException* exception); SeedValue seed_object_get_property_at_index(SeedContext ctx, SeedObject object, gint index, SeedException* exception); SeedValue seed_object_call(SeedContext ctx, SeedObject object, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception); GObject* seed_value_to_object(SeedContext ctx, SeedValue val, SeedException* exception); SeedValue seed_value_from_object(SeedContext ctx, GObject* val, SeedException* exception); SeedObject seed_make_object(SeedContext ctx, SeedClass klass, gpointer private_object); gpointer seed_object_get_private(SeedObject object); void seed_object_set_private(SeedObject object, gpointer value); gchar** seed_object_copy_property_names(SeedContext ctx, SeedObject object); gpointer seed_pointer_get_pointer(SeedContext ctx, SeedValue pointer); SeedObject seed_object_get_prototype(SeedContext ctx, SeedObject obj); gboolean seed_object_is_of_class(SeedContext ctx, SeedObject obj, SeedClass klass); SeedValue seed_make_pointer(SeedContext ctx, gpointer pointer); typedef SeedValue (*SeedFunctionCallback)(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception); void seed_create_function(SeedContext ctx, gchar* name, SeedFunctionCallback func, SeedObject obj); SeedObject seed_make_function(SeedContext ctx, SeedFunctionCallback func, const gchar* name); SeedObject seed_make_array(SeedContext ctx, const SeedValue elements, gsize num_elements, SeedException* exception); typedef void (*SeedObjectInitializeCallback)(SeedContext ctx, SeedObject object); /* Using any functions that require a context from *this callback has undefined results */ typedef void (*SeedObjectFinalizeCallback)(SeedObject object); typedef gboolean (*SeedObjectHasPropertyCallback)(SeedContext ctx, SeedObject object, SeedString string); typedef SeedValue (*SeedObjectGetPropertyCallback)(SeedContext ctx, SeedObject object, SeedString property_name, SeedException* e); typedef gboolean (*SeedObjectSetPropertyCallback)(SeedContext ctx, SeedObject object, SeedString property_name, SeedValue value, SeedException* e); typedef gboolean (*SeedObjectDeletePropertyCallback)(SeedContext ctx, SeedObject object, SeedString property_name, SeedException* e); /* TODO: Have to decide on accumulator API //typedef void (*SeedObjectGetPropertyNamesCallback) (SeedContext ctx, */ typedef void (*SeedObjectGetPropertyNamesCallback)(void); typedef SeedValue (*SeedObjectCallAsFunctionCallback)( SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception); typedef SeedValue (*SeedObjectCallAsConstructorCallback)( SeedContext ctx, SeedObject constructor, gsize argument_count, const SeedValue arguments[], SeedException* exception); typedef gboolean (*SeedObjectHasInstanceCallback)(SeedContext ctx, SeedObject constructor, SeedObject instance_p, SeedException* exception); typedef SeedValue (*SeedObjectConvertToTypeCallback)(SeedContext ctx, SeedObject object, SeedType type, SeedException* exception); typedef struct _seed_static_value { const gchar* const name; SeedObjectGetPropertyCallback get_property; SeedObjectSetPropertyCallback set_property; SeedPropertyAttributes attributes; } seed_static_value; typedef struct _seed_static_function { const gchar* const name; SeedObjectCallAsFunctionCallback callback; SeedPropertyAttributes attributes; } seed_static_function; typedef struct _seed_class_definition { int version; /* Always 0 */ SeedClassAttributes attributes; const gchar* class_name; SeedClass parent_class; const seed_static_value* static_values; const seed_static_function* static_functions; SeedObjectInitializeCallback initialize; SeedObjectFinalizeCallback finalize; SeedObjectHasPropertyCallback has_property; SeedObjectGetPropertyCallback get_property; SeedObjectSetPropertyCallback set_property; SeedObjectDeletePropertyCallback delete_property; SeedObjectGetPropertyNamesCallback get_property_names; SeedObjectCallAsFunctionCallback call_as_function; SeedObjectCallAsConstructorCallback call_as_constructor; SeedObjectHasInstanceCallback has_instance; SeedObjectConvertToTypeCallback convert_to_type; } seed_class_definition; #define seed_empty_class \ { \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ }; SeedClass seed_create_class(seed_class_definition* def); SeedObject seed_make_constructor( SeedContext ctx, SeedClass klass, SeedObjectCallAsConstructorCallback constructor); void seed_engine_set_search_path(SeedEngine* eng, const gchar* path); gchar** seed_engine_get_search_path(SeedEngine* eng); void seed_signal_connect(SeedContext ctx, GObject* object, const gchar* signal, const gchar* script); void seed_signal_connect_value(SeedContext ctx, GObject* object, const gchar* signal, SeedValue function, SeedValue user_data); GClosure* seed_closure_new(SeedContext ctx, SeedObject function, SeedObject user_data, const gchar* description); SeedObject seed_closure_get_callable(GClosure* c); SeedValue seed_closure_invoke(GClosure* closure, SeedValue* args, guint argc, SeedException* exception); SeedValue seed_closure_invoke_with_context(SeedContext ctx, GClosure* closure, SeedValue* args, guint argc, SeedException* exception); void seed_closure_warn_exception(GClosure* c, SeedContext ctx, SeedException exception); G_END_DECLS #endif seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/000077500000000000000000000000001303774616400202765ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/DynamicObject/000077500000000000000000000000001303774616400230115ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/DynamicObject/Makefile.am000066400000000000000000000010711303774616400250440ustar00rootroot00000000000000if BUILD_DYNAMICOBJECT_MODULE seedlibdir = ${libdir}/seed@SEED_GTK_VERSION@ seedlib_LTLIBRARIES = \ libseed_DynamicObject.la libseed_DynamicObject_la_SOURCES = \ seed-DynamicObject.c AM_CPPFLAGS = \ -I@top_srcdir@/libseed/ \ $(GOBJECT_INTROSPECTION_CFLAGS) \ $(SEED_DEBUG_CFLAGS) \ $(SEED_PROFILE_CFLAGS) libseed_DynamicObject_la_LDFLAGS = \ -module -avoid-version \ $(GOBJECT_INTROSPECTION_LDFLAGS) \ $(SEED_PROFILE_LIBS) libseed_DynamicObject_la_LIBADD = \ $(top_builddir)/libseed/libseed@SEED_GTK_VERSION@.la endif -include $(top_srcdir)/git.mk seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/DynamicObject/seed-DynamicObject.c000066400000000000000000000173701303774616400266160ustar00rootroot00000000000000/* DynamicObject Seed module this free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. Copyright (C) 2010 Jonatan Liljedahl -------------------------------------------------------------------------------- Compile with: gcc -shared -fPIC seed-DynamicObject.c -I/usr/local/include/seed \ `pkg-config --cflags --libs glib-2.0 gmodule-2.0 gobject-introspection-1.0`\ -o libseed_DynamicObject.so Usage: o = imports.DynamicObject.create({ getProperty: function(name) { return some_value; // or null to forward to normal props }, SetProperty: function(name, value) { do_something(name,value); return true; // or false to allow normal props to be set }, deleteProperty: function(name) { return true; // or false to forward to normal property deletion }, callAsFunction: function() { print("called with args: "+Array.prototype.slice.call(arguments)); }, callAsConstructor: function() { return {foo:123}; }, getPropertyNames: function(){} // not implemented yet... }); o.foobar = 42; // will call o.set_property('foobar',42) print(o.something); // will call o.get_property('something) // etc.. 'this' inside the callback is set to the calling contexts global object, not the dynamic object. You can also create the object first and set the callbacks later: o = imports.DynamicObject.create(); o.callAsFunction = function() { return o.something; } */ #include static SeedClass dynamic_object_class; static SeedValue seed_dynamic_object_create(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { SeedObject obj = seed_make_object(ctx, dynamic_object_class, NULL); if (argument_count > 0) seed_object_set_property(ctx, obj, "__proto__", arguments[0]); return (SeedValue) obj; } static SeedValue seed_dynamic_object_get_property(SeedContext ctx, SeedObject object, SeedString property_name, SeedException* exception) { guint len = seed_string_get_maximum_size(property_name); gchar* prop = g_alloca(len * sizeof(gchar)); seed_string_to_utf8_buffer(property_name, prop, len); // forward these to ordinary property lookup if (!g_strcmp0(prop, "toString")) return NULL; if (!g_strcmp0(prop, "valueOf")) return NULL; if (!g_strcmp0(prop, "getProperty")) return NULL; if (!g_strcmp0(prop, "setProperty")) return NULL; if (!g_strcmp0(prop, "deleteProperty")) return NULL; if (!g_strcmp0(prop, "callAsFunction")) return NULL; if (!g_strcmp0(prop, "callAsConstructor")) return NULL; SeedValue handler = seed_object_get_property(ctx, object, "getProperty"); if (seed_value_is_object(ctx, handler)) { SeedValue args[1] = { seed_value_from_string(ctx, prop, exception) }; SeedValue ret = (SeedValue) seed_object_call(ctx, (SeedObject) handler, NULL, 1, args, exception); return seed_value_is_null(ctx, ret) ? NULL : ret; } return NULL; } static gboolean seed_dynamic_object_set_property(SeedContext ctx, SeedObject object, SeedString property_name, SeedValue value, SeedException* exception) { guint len = seed_string_get_maximum_size(property_name); gchar* prop = g_alloca(len * sizeof(gchar)); seed_string_to_utf8_buffer(property_name, prop, len); SeedValue handler = seed_object_get_property(ctx, object, "setProperty"); if (seed_value_is_object(ctx, handler)) { SeedValue args[2] = { seed_value_from_string(ctx, prop, exception), value }; SeedValue ret = seed_object_call(ctx, (SeedObject) handler, NULL, 2, args, exception); return seed_value_to_boolean(ctx, ret, exception); } return FALSE; } static gboolean seed_dynamic_object_delete_property(SeedContext ctx, SeedObject object, SeedString property_name, SeedException* exception) { guint len = seed_string_get_maximum_size(property_name); gchar* prop = g_alloca(len * sizeof(gchar)); seed_string_to_utf8_buffer(property_name, prop, len); SeedValue handler = seed_object_get_property(ctx, object, "deleteProperty"); if (seed_value_is_object(ctx, handler)) { SeedValue args[1] = { seed_value_from_string(ctx, prop, exception) }; SeedValue ret = (SeedValue) seed_object_call(ctx, (SeedObject) handler, NULL, 1, args, exception); return seed_value_to_boolean(ctx, ret, exception); } return FALSE; } static SeedValue seed_dynamic_object_call_as_function(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { SeedValue handler = seed_object_get_property(ctx, function, "callAsFunction"); if (seed_value_is_object(ctx, handler)) { return (SeedValue) seed_object_call(ctx, (SeedObject) handler, NULL, argument_count, arguments, exception); } return NULL; } static SeedValue seed_dynamic_object_call_as_constructor(SeedContext ctx, SeedObject function, size_t argument_count, const SeedValue arguments[], SeedException* exception) { SeedValue handler = seed_object_get_property(ctx, function, "callAsConstructor"); if (seed_value_is_object(ctx, handler)) { return (SeedValue) seed_object_call(ctx, (SeedObject) handler, NULL, argument_count, arguments, exception); } return NULL; } // static void // seed_dynamic_object_get_property_names (SeedContext ctx, // SeedObject object, // /*wait for API*/ propertyNames) SeedObject seed_module_init(SeedEngine* eng) { SeedObject namespace_ref = seed_make_object(eng->context, NULL, NULL); seed_class_definition class_def = seed_empty_class; class_def.class_name = "DynamicObject"; class_def.get_property = seed_dynamic_object_get_property; class_def.set_property = seed_dynamic_object_set_property; class_def.delete_property = seed_dynamic_object_delete_property; class_def.call_as_function = seed_dynamic_object_call_as_function; class_def.call_as_constructor = seed_dynamic_object_call_as_constructor; dynamic_object_class = seed_create_class(&class_def); seed_create_function(eng->context, "create", (SeedFunctionCallback) seed_dynamic_object_create, namespace_ref); return namespace_ref; } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/Makefile.am000066400000000000000000000002641303774616400223340ustar00rootroot00000000000000SUBDIRS = example sqlite canvas multiprocessing readline os sandbox dbus libxml cairo gtkbuilder gettext mpfr ffi DynamicObject xorg SUBDIRS += gjs -include $(top_srcdir)/git.mk seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/cairo/000077500000000000000000000000001303774616400213735ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/cairo/Makefile.am000066400000000000000000000020301303774616400234220ustar00rootroot00000000000000if BUILD_CAIRO_MODULE EXTRA_DIST = seed-cairo-enums.h \ seed-cairo.h \ seed-cairo-image-surface.h \ seed-cairo-matrix.h \ seed-cairo-pattern.h \ seed-cairo-pdf-surface.h \ seed-cairo-surface.h seedlibdir = ${libdir}/seed@SEED_GTK_VERSION@ seedlib_LTLIBRARIES = \ libseed_cairo.la libseed_cairo_la_SOURCES = \ seed-cairo.c \ seed-cairo-surface.c \ seed-cairo-image-surface.c \ seed-cairo-pdf-surface.c \ seed-cairo-matrix.c \ seed-cairo-pattern.c \ seed-cairo-enums.c libseed_cairo_la_CFLAGS = \ -Wall \ $(GOBJECT_INTROSPECTION_CFLAGS) \ -I@top_srcdir@/libseed/ \ $(CAIRO_CFLAGS) \ $(GDK_CFLAGS) \ $(SEED_DEBUG_CFLAGS) \ $(SEED_PROFILE_CFLAGS) libseed_cairo_la_LDFLAGS = \ -module -avoid-version \ $(GOBJECT_INTROSPECTION_LDFLAGS) \ $(GDK_LDFLAGS) \ $(CAIRO_LDFLAGS) libseed_cairo_la_LIBADD = \ $(top_builddir)/libseed/libseed@SEED_GTK_VERSION@.la \ $(GDK_LIBS) \ $(CAIRO_LIBS) \ $(SEED_PROFILE_LIBS) endif -include $(top_srcdir)/git.mk seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/cairo/seed-cairo-enums.c000066400000000000000000000177021303774616400247060ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #include #include #include "seed-cairo.h" #define ENUM_MEMBER(holder, name, value) \ seed_object_set_property(ctx, holder, name, \ seed_value_from_long(ctx, value, NULL)) SeedValue seed_cairo_status_to_string(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { cairo_status_t status; if (argument_count != 1) { EXPECTED_EXCEPTION("status_to_string", "1 argument"); } status = seed_value_to_long(ctx, arguments[0], exception); return seed_value_from_string(ctx, cairo_status_to_string(status), exception); } void seed_define_cairo_enums(SeedContext ctx, SeedObject namespace_ref) { SeedObject content_holder, format_holder, antialias_holder, fillrule_holder, linecap_holder, linejoin_holder, operator_holder, status_holder; content_holder = seed_make_object(ctx, NULL, NULL); seed_object_set_property(ctx, namespace_ref, "Content", content_holder); ENUM_MEMBER(content_holder, "COLOR", CAIRO_CONTENT_COLOR); ENUM_MEMBER(content_holder, "ALPHA", CAIRO_CONTENT_ALPHA); ENUM_MEMBER(content_holder, "COLOR_ALPHA", CAIRO_CONTENT_COLOR_ALPHA); format_holder = seed_make_object(ctx, NULL, NULL); seed_object_set_property(ctx, namespace_ref, "Format", format_holder); ENUM_MEMBER(format_holder, "ARGB32", CAIRO_FORMAT_ARGB32); ENUM_MEMBER(format_holder, "RGB23", CAIRO_FORMAT_RGB24); ENUM_MEMBER(format_holder, "A8", CAIRO_FORMAT_A8); ENUM_MEMBER(format_holder, "A1", CAIRO_FORMAT_A1); antialias_holder = seed_make_object(ctx, NULL, NULL); seed_object_set_property(ctx, namespace_ref, "Antialias", antialias_holder); ENUM_MEMBER(antialias_holder, "DEFAULT", CAIRO_ANTIALIAS_DEFAULT); ENUM_MEMBER(antialias_holder, "NONE", CAIRO_ANTIALIAS_NONE); ENUM_MEMBER(antialias_holder, "GRAY", CAIRO_ANTIALIAS_GRAY); ENUM_MEMBER(antialias_holder, "SUBPIXEL", CAIRO_ANTIALIAS_SUBPIXEL); fillrule_holder = seed_make_object(ctx, NULL, NULL); seed_object_set_property(ctx, namespace_ref, "Fillrule", fillrule_holder); ENUM_MEMBER(fillrule_holder, "WINDING", CAIRO_FILL_RULE_WINDING); ENUM_MEMBER(fillrule_holder, "EVEN_ODD", CAIRO_FILL_RULE_EVEN_ODD); linecap_holder = seed_make_object(ctx, NULL, NULL); seed_object_set_property(ctx, namespace_ref, "Linecap", linecap_holder); ENUM_MEMBER(linecap_holder, "BUTT", CAIRO_LINE_CAP_BUTT); ENUM_MEMBER(linecap_holder, "ROUND", CAIRO_LINE_CAP_ROUND); ENUM_MEMBER(linecap_holder, "SQUARE", CAIRO_LINE_CAP_SQUARE); linejoin_holder = seed_make_object(ctx, NULL, NULL); seed_object_set_property(ctx, namespace_ref, "Linejoin", linejoin_holder); ENUM_MEMBER(linejoin_holder, "MITER", CAIRO_LINE_JOIN_MITER); ENUM_MEMBER(linejoin_holder, "ROUND", CAIRO_LINE_JOIN_ROUND); ENUM_MEMBER(linejoin_holder, "BEVEL", CAIRO_LINE_JOIN_BEVEL); operator_holder = seed_make_object(ctx, NULL, NULL); seed_object_set_property(ctx, namespace_ref, "Operator", operator_holder); ENUM_MEMBER(operator_holder, "CLEAR", CAIRO_OPERATOR_CLEAR); ENUM_MEMBER(operator_holder, "SOURCE", CAIRO_OPERATOR_SOURCE); ENUM_MEMBER(operator_holder, "OVER", CAIRO_OPERATOR_OVER); ENUM_MEMBER(operator_holder, "IN", CAIRO_OPERATOR_IN); ENUM_MEMBER(operator_holder, "OUT", CAIRO_OPERATOR_OUT); ENUM_MEMBER(operator_holder, "ATOP", CAIRO_OPERATOR_ATOP); ENUM_MEMBER(operator_holder, "DEST", CAIRO_OPERATOR_DEST); ENUM_MEMBER(operator_holder, "DEST_OVER", CAIRO_OPERATOR_DEST_OVER); ENUM_MEMBER(operator_holder, "DEST_IN", CAIRO_OPERATOR_DEST_IN); ENUM_MEMBER(operator_holder, "DEST_OUT", CAIRO_OPERATOR_DEST_OUT); ENUM_MEMBER(operator_holder, "DEST_ATOP", CAIRO_OPERATOR_DEST_ATOP); ENUM_MEMBER(operator_holder, "XOR", CAIRO_OPERATOR_XOR); ENUM_MEMBER(operator_holder, "ADD", CAIRO_OPERATOR_ADD); ENUM_MEMBER(operator_holder, "SATURATE", CAIRO_OPERATOR_SATURATE); status_holder = seed_make_object(ctx, NULL, NULL); seed_object_set_property(ctx, namespace_ref, "Status", status_holder); ENUM_MEMBER(status_holder, "SUCCESS", CAIRO_STATUS_SUCCESS); ENUM_MEMBER(status_holder, "NO_MEMORY", CAIRO_STATUS_NO_MEMORY); ENUM_MEMBER(status_holder, "INVALID_RESTORE", CAIRO_STATUS_INVALID_RESTORE); ENUM_MEMBER(status_holder, "INVALID_POP_GROUP", CAIRO_STATUS_INVALID_POP_GROUP); ENUM_MEMBER(status_holder, "NO_CURRENT_POINT", CAIRO_STATUS_NO_CURRENT_POINT); ENUM_MEMBER(status_holder, "INVALID_MATRIX", CAIRO_STATUS_INVALID_MATRIX); ENUM_MEMBER(status_holder, "INVALID_STATUS", CAIRO_STATUS_INVALID_STATUS); ENUM_MEMBER(status_holder, "NULL_POINTER", CAIRO_STATUS_NULL_POINTER); ENUM_MEMBER(status_holder, "INVALID_STRING", CAIRO_STATUS_INVALID_STRING); ENUM_MEMBER(status_holder, "INVALID_PATH_DATA", CAIRO_STATUS_INVALID_PATH_DATA); ENUM_MEMBER(status_holder, "READ_ERROR", CAIRO_STATUS_READ_ERROR); ENUM_MEMBER(status_holder, "WRITE_ERROR", CAIRO_STATUS_WRITE_ERROR); ENUM_MEMBER(status_holder, "SURFACE_FINISHED", CAIRO_STATUS_SURFACE_FINISHED); ENUM_MEMBER(status_holder, "SURFACE_TYPE_MISMATCH", CAIRO_STATUS_SURFACE_TYPE_MISMATCH); ENUM_MEMBER(status_holder, "PATTERN_TYPE_MISMATCH", CAIRO_STATUS_PATTERN_TYPE_MISMATCH); ENUM_MEMBER(status_holder, "INVALID_CONTENT", CAIRO_STATUS_INVALID_CONTENT); ENUM_MEMBER(status_holder, "INVALID_FORMAT", CAIRO_STATUS_INVALID_FORMAT); ENUM_MEMBER(status_holder, "INVALID_VISUAL", CAIRO_STATUS_INVALID_VISUAL); ENUM_MEMBER(status_holder, "FILE_NOT_FOUND", CAIRO_STATUS_FILE_NOT_FOUND); ENUM_MEMBER(status_holder, "INVALID_DASH", CAIRO_STATUS_INVALID_DASH); ENUM_MEMBER(status_holder, "INVALID_DSC_COMMENT", CAIRO_STATUS_INVALID_DSC_COMMENT); ENUM_MEMBER(status_holder, "INVALID_INDEX", CAIRO_STATUS_INVALID_INDEX); ENUM_MEMBER(status_holder, "CLIP_NOT_REPRESENTABLE", CAIRO_STATUS_CLIP_NOT_REPRESENTABLE); ENUM_MEMBER(status_holder, "TEMP_FILE_ERROR", CAIRO_STATUS_TEMP_FILE_ERROR); ENUM_MEMBER(status_holder, "INVALID_STRIDE", CAIRO_STATUS_INVALID_STRIDE); ENUM_MEMBER(status_holder, "FONT_TYPE_MISMATCH", CAIRO_STATUS_FONT_TYPE_MISMATCH); ENUM_MEMBER(status_holder, "USER_FONT_IMMUTABLE", CAIRO_STATUS_USER_FONT_IMMUTABLE); ENUM_MEMBER(status_holder, "USER_FONT_ERROR", CAIRO_STATUS_USER_FONT_ERROR); ENUM_MEMBER(status_holder, "NEGATIVE_COUNT", CAIRO_STATUS_NEGATIVE_COUNT); ENUM_MEMBER(status_holder, "INVALID_CLUSTERS", CAIRO_STATUS_INVALID_CLUSTERS); ENUM_MEMBER(status_holder, "INVALID_SLANT", CAIRO_STATUS_INVALID_SLANT); ENUM_MEMBER(status_holder, "INVALID_WEIGHT", CAIRO_STATUS_INVALID_WEIGHT); seed_create_function(ctx, "to_string", seed_cairo_status_to_string, status_holder); } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/cairo/seed-cairo-enums.h000066400000000000000000000002111303774616400246760ustar00rootroot00000000000000#ifndef _SEED_CAIRO_ENUMS_H #define _SEED_CAIRO_ENUMS_H void seed_define_cairo_enums(SeedContext ctx, SeedObject namespace_ref); #endif seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/cairo/seed-cairo-image-surface.c000066400000000000000000000167221303774616400262700ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #include #include #include "seed-cairo.h" #include "seed-cairo-surface.h" #define CAIRO_SURFACE_PRIV(obj) \ ((cairo_surface_t*) seed_object_get_private(obj)) #define CHECK_SURFACE(obj) \ ({ \ if (!seed_object_is_of_class(ctx, obj, \ seed_cairo_image_surface_class)) { \ seed_make_exception(ctx, exception, "ArgumentError", \ "Object is not a Cairo Surface"); \ return seed_make_undefined(ctx); \ } \ if (!seed_object_get_private(obj)) { \ seed_make_exception(ctx, exception, "ArgumentError", \ "Cairo surface has been destroyed"); \ return seed_make_undefined(ctx); \ } \ }) #define CHECK_THIS() \ if (!seed_object_get_private(this_object)) { \ seed_make_exception(ctx, exception, "ArgumentError", \ "Cairo surface has been destroyed"); \ return seed_make_undefined(ctx); \ } SeedClass seed_cairo_image_surface_class; SeedObject image_surface_constructor_ref; static SeedObject seed_object_from_cairo_image_surface(SeedContext ctx, cairo_surface_t* surf) { SeedObject jsobj; jsobj = cairo_surface_get_user_data(surf, seed_get_cairo_key()); if (jsobj) return jsobj; jsobj = seed_make_object(ctx, seed_cairo_image_surface_class, surf); cairo_surface_set_user_data(surf, seed_get_cairo_key(), jsobj, seed_cairo_destroy_func); return jsobj; } static SeedValue seed_cairo_image_surface_get_format(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedException* exception) { CHECK_THIS(); return seed_value_from_long(ctx, cairo_image_surface_get_format( seed_object_to_cairo_surface(ctx, this_object, exception)), exception); } static SeedValue seed_cairo_image_surface_get_width(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedException* exception) { CHECK_THIS(); return seed_value_from_int(ctx, cairo_image_surface_get_width( seed_object_to_cairo_surface(ctx, this_object, exception)), exception); } static SeedValue seed_cairo_image_surface_get_height(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedException* exception) { CHECK_THIS(); return seed_value_from_int(ctx, cairo_image_surface_get_height( seed_object_to_cairo_surface(ctx, this_object, exception)), exception); } static SeedValue seed_cairo_image_surface_get_stride(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedException* exception) { CHECK_THIS(); return seed_value_from_int(ctx, cairo_image_surface_get_stride( seed_object_to_cairo_surface(ctx, this_object, exception)), exception); } static SeedObject seed_cairo_construct_image_surface(SeedContext ctx, SeedObject constructor, size_t argument_count, const SeedValue arguments[], SeedException* exception) { cairo_surface_t* ret; gint width, height; cairo_format_t format; if (argument_count != 3) { EXPECTED_EXCEPTION("ImageSurface", "3 arguments"); } format = seed_value_to_long(ctx, arguments[0], exception); width = seed_value_to_int(ctx, arguments[1], exception); height = seed_value_to_int(ctx, arguments[2], exception); ret = cairo_image_surface_create(format, width, height); return seed_object_from_cairo_image_surface(ctx, ret); } seed_static_value image_surface_values[] = { { "format", seed_cairo_image_surface_get_format, 0, SEED_PROPERTY_ATTRIBUTE_READ_ONLY | SEED_PROPERTY_ATTRIBUTE_DONT_DELETE }, { "width", seed_cairo_image_surface_get_width, 0, SEED_PROPERTY_ATTRIBUTE_READ_ONLY | SEED_PROPERTY_ATTRIBUTE_DONT_DELETE }, { "height", seed_cairo_image_surface_get_height, 0, SEED_PROPERTY_ATTRIBUTE_READ_ONLY | SEED_PROPERTY_ATTRIBUTE_DONT_DELETE }, { "stride", seed_cairo_image_surface_get_stride, 0, SEED_PROPERTY_ATTRIBUTE_READ_ONLY | SEED_PROPERTY_ATTRIBUTE_DONT_DELETE }, { 0, 0, 0, 0 } }; void seed_define_cairo_image_surface(SeedContext ctx, SeedObject namespace_ref) { seed_class_definition image_def = seed_empty_class; // TODO: FIX seed_static_function webkit_fail = { 0, 0, 0 }; image_def.class_name = "ImageSurface"; image_def.static_values = image_surface_values; image_def.parent_class = seed_get_cairo_surface_class(); // FAIL image_def.static_functions = &webkit_fail; seed_cairo_image_surface_class = seed_create_class(&image_def); image_surface_constructor_ref = seed_make_constructor(ctx, NULL, // seed_cairo_image_surface_class, seed_cairo_construct_image_surface); seed_object_set_property(ctx, namespace_ref, "ImageSurface", image_surface_constructor_ref); } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/cairo/seed-cairo-image-surface.h000066400000000000000000000003121303774616400262610ustar00rootroot00000000000000#ifndef _SEED_CAIRO_IMAGE_SURFACE #define _SEED_CAIRO_IMAGE_SURFACE #include #include void seed_define_cairo_image_surface(SeedContext ctx, SeedObject namespace_ref); #endif seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/cairo/seed-cairo-matrix.c000066400000000000000000000256261303774616400250670ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #include #include #include "seed-cairo.h" SeedClass seed_matrix_class; SeedValue seed_value_from_cairo_matrix(SeedContext ctx, const cairo_matrix_t* matrix, SeedException* exception) { SeedValue elems[6]; elems[0] = seed_value_from_double(ctx, matrix->xx, exception); elems[1] = seed_value_from_double(ctx, matrix->yx, exception); elems[2] = seed_value_from_double(ctx, matrix->xy, exception); elems[3] = seed_value_from_double(ctx, matrix->yy, exception); elems[4] = seed_value_from_double(ctx, matrix->x0, exception); elems[5] = seed_value_from_double(ctx, matrix->y0, exception); return seed_make_array(ctx, elems, 6, exception); } gboolean seed_value_to_cairo_matrix(SeedContext ctx, SeedValue value, cairo_matrix_t* matrix, SeedException* exception) { if (!seed_value_is_object(ctx, value)) return FALSE; matrix->xx = seed_value_to_double( ctx, seed_object_get_property_at_index(ctx, (SeedObject) value, 0, exception), exception); matrix->yx = seed_value_to_double( ctx, seed_object_get_property_at_index(ctx, (SeedObject) value, 1, exception), exception); matrix->xy = seed_value_to_double( ctx, seed_object_get_property_at_index(ctx, (SeedObject) value, 2, exception), exception); matrix->yy = seed_value_to_double( ctx, seed_object_get_property_at_index(ctx, (SeedObject) value, 3, exception), exception); matrix->x0 = seed_value_to_double( ctx, seed_object_get_property_at_index(ctx, (SeedObject) value, 4, exception), exception); matrix->y0 = seed_value_to_double( ctx, seed_object_get_property_at_index(ctx, (SeedObject) value, 5, exception), exception); return TRUE; } // Should probably be a property? static SeedValue seed_cairo_matrix_init_identity(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { cairo_matrix_t m; cairo_matrix_init_identity(&m); return seed_value_from_cairo_matrix(ctx, &m, exception); } static SeedValue seed_cairo_matrix_init_translate(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { gdouble x, y; cairo_matrix_t m; if (argument_count != 2) { EXPECTED_EXCEPTION("init_translate", "2 arguments"); } x = seed_value_to_double(ctx, arguments[0], exception); y = seed_value_to_double(ctx, arguments[1], exception); cairo_matrix_init_translate(&m, x, y); return seed_value_from_cairo_matrix(ctx, &m, exception); } static SeedValue seed_cairo_matrix_translate(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { gdouble x, y; cairo_matrix_t m; if (argument_count != 3) { EXPECTED_EXCEPTION("translate", "3 arguments"); } if (!seed_value_to_cairo_matrix(ctx, arguments[0], &m, exception)) { seed_make_exception( ctx, exception, "ArgumentError", "translate needs an array [xx, yx, xy, yy, x0, y0]"); } x = seed_value_to_double(ctx, arguments[1], exception); y = seed_value_to_double(ctx, arguments[2], exception); cairo_matrix_translate(&m, x, y); return seed_value_from_cairo_matrix(ctx, &m, exception); } static SeedValue seed_cairo_matrix_init_scale(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { gdouble x, y; cairo_matrix_t m; if (argument_count != 2) { EXPECTED_EXCEPTION("init_scale", "2 arguments"); } x = seed_value_to_double(ctx, arguments[0], exception); y = seed_value_to_double(ctx, arguments[1], exception); cairo_matrix_init_scale(&m, x, y); return seed_value_from_cairo_matrix(ctx, &m, exception); } static SeedValue seed_cairo_matrix_scale(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { gdouble x, y; cairo_matrix_t m; if (argument_count != 3) { EXPECTED_EXCEPTION("scale", "3 arguments"); } if (!seed_value_to_cairo_matrix(ctx, arguments[0], &m, exception)) { seed_make_exception(ctx, exception, "ArgumentError", "scale needs an array [xx, yx, xy, yy, x0, y0]"); } x = seed_value_to_double(ctx, arguments[1], exception); y = seed_value_to_double(ctx, arguments[2], exception); cairo_matrix_scale(&m, x, y); return seed_value_from_cairo_matrix(ctx, &m, exception); } static SeedValue seed_cairo_matrix_init_rotate(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { gdouble angle; cairo_matrix_t m; if (argument_count != 1) { EXPECTED_EXCEPTION("init_rotate", "1 arguments"); } angle = seed_value_to_double(ctx, arguments[0], exception); cairo_matrix_init_rotate(&m, angle); return seed_value_from_cairo_matrix(ctx, &m, exception); } static SeedValue seed_cairo_matrix_rotate(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { gdouble angle; cairo_matrix_t m; if (argument_count != 2) { EXPECTED_EXCEPTION("rotate", "2 arguments"); } if (!seed_value_to_cairo_matrix(ctx, arguments[0], &m, exception)) { seed_make_exception(ctx, exception, "ArgumentError", "rotate needs an array [xx, yx, xy, yy, x0, y0]"); } angle = seed_value_to_double(ctx, arguments[1], exception); cairo_matrix_rotate(&m, angle); return seed_value_from_cairo_matrix(ctx, &m, exception); } static SeedValue seed_cairo_matrix_transform_distance(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { SeedValue ret[2]; gdouble x, y; cairo_matrix_t m; if (argument_count != 3) { EXPECTED_EXCEPTION("transform_distance", "3 arguments"); } if (!seed_value_to_cairo_matrix(ctx, arguments[0], &m, exception)) { seed_make_exception( ctx, exception, "ArgumentError", "transform_distance needs an array [xx, yx, xy, yy, x0, y0]"); } x = seed_value_to_double(ctx, arguments[1], exception); y = seed_value_to_double(ctx, arguments[2], exception); cairo_matrix_transform_distance(&m, &x, &y); ret[0] = seed_value_from_double(ctx, x, exception); ret[1] = seed_value_from_double(ctx, y, exception); return seed_make_array(ctx, ret, 2, exception); } static SeedValue seed_cairo_matrix_transform_point(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { SeedValue ret[2]; gdouble x, y; cairo_matrix_t m; if (argument_count != 3) { EXPECTED_EXCEPTION("transform_point", "3 arguments"); } if (!seed_value_to_cairo_matrix(ctx, arguments[0], &m, exception)) { seed_make_exception( ctx, exception, "ArgumentError", "transform_point needs an array [xx, yx, xy, yy, x0, y0]"); } x = seed_value_to_double(ctx, arguments[1], exception); y = seed_value_to_double(ctx, arguments[2], exception); cairo_matrix_transform_point(&m, &x, &y); ret[0] = seed_value_from_double(ctx, x, exception); ret[1] = seed_value_from_double(ctx, y, exception); return seed_make_array(ctx, ret, 2, exception); } seed_static_function matrix_funcs[] = { { "init_identity", seed_cairo_matrix_init_identity, 0 }, { "init_translate", seed_cairo_matrix_init_translate, 0 }, { "init_scale", seed_cairo_matrix_init_scale, 0 }, { "init_rotate", seed_cairo_matrix_init_rotate, 0 }, { "translate", seed_cairo_matrix_translate, 0 }, { "scale", seed_cairo_matrix_scale, 0 }, { "rotate", seed_cairo_matrix_rotate, 0 }, { "transform_point", seed_cairo_matrix_transform_point, 0 }, { "transform_distance", seed_cairo_matrix_transform_distance, 0 }, { 0, 0, 0 } }; void seed_define_cairo_matrix(SeedContext ctx, SeedObject namespace_ref) { seed_class_definition matrix_def = seed_empty_class; matrix_def.class_name = "Matrix"; matrix_def.static_functions = matrix_funcs; seed_matrix_class = seed_create_class(&matrix_def); seed_object_set_property(ctx, namespace_ref, "Matrix", seed_make_object(ctx, seed_matrix_class, NULL)); } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/cairo/seed-cairo-matrix.h000066400000000000000000000011221303774616400250550ustar00rootroot00000000000000#ifndef _SEED_MATRIX_H #define _SEED_MATRIX_H #include #include void seed_define_cairo_matrix(SeedContext ctx, SeedObject namespace_ref); gboolean seed_value_to_cairo_matrix(SeedContext ctx, SeedValue value, cairo_matrix_t* matrix, SeedException* exception); SeedValue seed_value_from_cairo_matrix(SeedContext ctx, const cairo_matrix_t* matrix, SeedException* exception); #endif seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/cairo/seed-cairo-pattern.c000066400000000000000000000214611303774616400252310ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #include #include #include "seed-cairo.h" #include "seed-cairo-matrix.h" #define CAIRO_PATTERN_PRIV(obj) \ ((cairo_pattern_t*) seed_object_get_private(obj)) #define CHECK_PATTERN(obj, res) \ ({ \ if (!seed_object_is_of_class(ctx, obj, seed_cairo_pattern_class)) { \ seed_make_exception(ctx, exception, "ArgumentError", \ "Object is not a Cairo Pattern"); \ return seed_make_##res(ctx); \ } \ if (!seed_object_get_private(obj)) { \ seed_make_exception(ctx, exception, "ArgumentError", \ "Cairo pattern has been destroyed"); \ return seed_make_##res(ctx); \ } \ }) #define CHECK_THIS() \ if (!seed_object_get_private(this_object)) { \ seed_make_exception(ctx, exception, "ArgumentError", \ "Cairo pattern has been destroyed"); \ return seed_make_undefined(ctx); \ } #define CHECK_THIS_BOOL(res) \ if (!seed_object_get_private(this_object)) { \ seed_make_exception(ctx, exception, "ArgumentError", \ "Cairo pattern has been destroyed"); \ return FALSE; \ } SeedClass seed_cairo_pattern_class; SeedClass seed_get_cairo_pattern_class() { return seed_cairo_pattern_class; } static void seed_cairo_pattern_finalize(SeedObject obj) { cairo_pattern_t* s = CAIRO_PATTERN_PRIV(obj); if (s) { cairo_pattern_set_user_data(s, seed_get_cairo_key(), NULL, NULL); cairo_pattern_destroy(s); } } cairo_pattern_t* seed_object_to_cairo_pattern(SeedContext ctx, SeedObject obj, SeedException* exception) { if (seed_object_is_of_class(ctx, obj, seed_cairo_pattern_class)) return CAIRO_PATTERN_PRIV(obj); seed_make_exception(ctx, exception, "ArgumentError", "Object is not a Cairo Pattern"); return NULL; } SeedObject seed_object_from_cairo_pattern(SeedContext ctx, cairo_pattern_t* pat) { SeedObject jsobj; jsobj = cairo_pattern_get_user_data(pat, seed_get_cairo_key()); if (jsobj) return jsobj; jsobj = seed_make_object(ctx, seed_cairo_pattern_class, pat); cairo_pattern_set_user_data(pat, seed_get_cairo_key(), jsobj, seed_cairo_destroy_func); return jsobj; } static SeedObject seed_cairo_construct_linear_gradient(SeedContext ctx, SeedObject constructor, size_t argument_count, const SeedValue arguments[], SeedException* exception) { gdouble x0, y0, x1, y1; if (argument_count != 4) { EXPECTED_EXCEPTION("LinearGradient constructor", "4 arguments"); } x0 = seed_value_to_double(ctx, arguments[0], exception); y0 = seed_value_to_double(ctx, arguments[1], exception); x1 = seed_value_to_double(ctx, arguments[2], exception); y1 = seed_value_to_double(ctx, arguments[3], exception); return seed_object_from_cairo_pattern(ctx, cairo_pattern_create_linear(x0, y0, x1, y1)); } static SeedObject seed_cairo_construct_radial_gradient(SeedContext ctx, SeedObject constructor, size_t argument_count, const SeedValue arguments[], SeedException* exception) { gdouble cx0, cy0, r0, cx1, cy1, r1; if (argument_count != 6) { EXPECTED_EXCEPTION("RadialGradient constructor", "6 arguments"); } cx0 = seed_value_to_double(ctx, arguments[0], exception); cy0 = seed_value_to_double(ctx, arguments[1], exception); r0 = seed_value_to_double(ctx, arguments[2], exception); cx1 = seed_value_to_double(ctx, arguments[3], exception); cy1 = seed_value_to_double(ctx, arguments[4], exception); r1 = seed_value_to_double(ctx, arguments[5], exception); return seed_object_from_cairo_pattern( ctx, cairo_pattern_create_radial(cx0, cy0, r0, cx1, cy1, r1)); } static SeedValue seed_cairo_pattern_add_color_stop_rgb(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { gdouble offset, r, g, b; cairo_pattern_t* pat; CHECK_THIS(); if (argument_count != 4) { EXPECTED_EXCEPTION("add_color_stop_rgb", "4 arguments"); } pat = seed_object_get_private(this_object); offset = seed_value_to_double(ctx, arguments[0], exception); r = seed_value_to_double(ctx, arguments[1], exception); g = seed_value_to_double(ctx, arguments[2], exception); b = seed_value_to_double(ctx, arguments[3], exception); cairo_pattern_add_color_stop_rgb(pat, offset, r, g, b); return seed_make_undefined(ctx); } static SeedValue seed_cairo_pattern_add_color_stop_rgba(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { gdouble offset, r, g, b, a; cairo_pattern_t* pat; CHECK_THIS(); if (argument_count != 5) { EXPECTED_EXCEPTION("add_color_stop_rgba", "5 arguments"); } pat = seed_object_get_private(this_object); offset = seed_value_to_double(ctx, arguments[0], exception); r = seed_value_to_double(ctx, arguments[1], exception); g = seed_value_to_double(ctx, arguments[2], exception); b = seed_value_to_double(ctx, arguments[3], exception); a = seed_value_to_double(ctx, arguments[4], exception); cairo_pattern_add_color_stop_rgba(pat, offset, r, g, b, a); return seed_make_undefined(ctx); } seed_static_function pattern_funcs[] = { { "add_color_stop_rgb", seed_cairo_pattern_add_color_stop_rgb, 0 }, { "add_color_stop_rgba", seed_cairo_pattern_add_color_stop_rgba, 0 }, { 0, 0, 0 } }; void seed_define_cairo_pattern(SeedContext ctx, SeedObject namespace_ref) { SeedObject linear_constructor, radial_constructor; seed_class_definition pattern_def = seed_empty_class; pattern_def.class_name = "Pattern"; pattern_def.finalize = seed_cairo_pattern_finalize; pattern_def.static_functions = pattern_funcs; seed_cairo_pattern_class = seed_create_class(&pattern_def); linear_constructor = seed_make_constructor(ctx, NULL, seed_cairo_construct_linear_gradient); seed_object_set_property(ctx, namespace_ref, "LinearGradient", linear_constructor); radial_constructor = seed_make_constructor(ctx, NULL, seed_cairo_construct_radial_gradient); seed_object_set_property(ctx, namespace_ref, "RadialGradient", radial_constructor); } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/cairo/seed-cairo-pattern.h000066400000000000000000000010531303774616400252310ustar00rootroot00000000000000#ifndef _SEED_CAIRO_PATTERN_H #define _SEED_CAIRO_PATTERN_H #include #include SeedClass seed_get_cairo_pattern_class(); cairo_pattern_t* seed_object_to_cairo_pattern(SeedContext ctx, SeedObject obj, SeedException* exception); SeedObject seed_object_from_cairo_pattern(SeedContext ctx, cairo_pattern_t* pat); void seed_define_cairo_pattern(SeedContext ctx, SeedObject namespace_ref); #endif seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/cairo/seed-cairo-pdf-surface.c000066400000000000000000000127751303774616400257630ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #include #include #include #include "seed-cairo.h" #include "seed-cairo-surface.h" #define CAIRO_SURFACE_PRIV(obj) \ ((cairo_surface_t*) seed_object_get_private(obj)) #define CHECK_SURFACE(obj) \ ({ \ if (!seed_object_is_of_class(ctx, obj, \ seed_cairo_pdf_surface_class)) { \ seed_make_exception(ctx, exception, "ArgumentError", \ "Object is not a Cairo Surface"); \ return seed_make_undefined(ctx); \ } \ if (!seed_object_get_private(obj)) { \ seed_make_exception(ctx, exception, "ArgumentError", \ "Cairo surface has been destroyed"); \ return seed_make_undefined(ctx); \ } \ }) #define CHECK_THIS() \ if (!seed_object_get_private(this_object)) { \ seed_make_exception(ctx, exception, "ArgumentError", \ "Cairo surface has been destroyed"); \ return seed_make_undefined(ctx); \ } SeedClass seed_cairo_pdf_surface_class; SeedObject pdf_surface_constructor_ref; static SeedObject seed_object_from_cairo_pdf_surface(SeedContext ctx, cairo_surface_t* surf) { SeedObject jsobj; jsobj = cairo_surface_get_user_data(surf, seed_get_cairo_key()); if (jsobj) return jsobj; jsobj = seed_make_object(ctx, seed_cairo_pdf_surface_class, surf); cairo_surface_set_user_data(surf, seed_get_cairo_key(), jsobj, seed_cairo_destroy_func); return jsobj; } static SeedValue seed_cairo_pdf_surface_set_size(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { cairo_surface_t* surf; gdouble x, y; CHECK_THIS(); if (argument_count != 2) { EXPECTED_EXCEPTION("set_size", "2 arguments"); } surf = seed_object_get_private(this_object); x = seed_value_to_double(ctx, arguments[0], exception); y = seed_value_to_double(ctx, arguments[1], exception); cairo_pdf_surface_set_size(surf, x, y); return seed_make_undefined(ctx); } static SeedObject seed_cairo_construct_pdf_surface(SeedContext ctx, SeedObject constructor, size_t argument_count, const SeedValue arguments[], SeedException* exception) { cairo_surface_t* ret; gchar* filename = NULL; gdouble width, height; if (argument_count != 3) { EXPECTED_EXCEPTION("PDFSurface", "3 arguments"); } if (!seed_value_is_null(ctx, arguments[0])) filename = seed_value_to_string(ctx, arguments[0], exception); width = seed_value_to_double(ctx, arguments[1], exception); height = seed_value_to_double(ctx, arguments[2], exception); ret = cairo_pdf_surface_create(filename, width, height); return seed_object_from_cairo_pdf_surface(ctx, ret); } seed_static_value pdf_surface_values[] = { { 0, 0, 0, 0 } }; seed_static_function pdf_surface_funcs[] = { { "set_size", seed_cairo_pdf_surface_set_size, 0 }, { 0, 0, 0 } }; void seed_define_cairo_pdf_surface(SeedContext ctx, SeedObject namespace_ref) { seed_class_definition pdf_def = seed_empty_class; pdf_def.class_name = "PDFSurface"; pdf_def.static_values = pdf_surface_values; pdf_def.parent_class = seed_get_cairo_surface_class(); pdf_def.static_functions = pdf_surface_funcs; seed_cairo_pdf_surface_class = seed_create_class(&pdf_def); pdf_surface_constructor_ref = seed_make_constructor(ctx, NULL, // seed_cairo_pdf_surface_class, seed_cairo_construct_pdf_surface); seed_object_set_property(ctx, namespace_ref, "PDFSurface", pdf_surface_constructor_ref); } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/cairo/seed-cairo-pdf-surface.h000066400000000000000000000003041303774616400257510ustar00rootroot00000000000000#ifndef _SEED_CAIRO_PDF_SURFACE #define _SEED_CAIRO_PDF_SURFACE #include #include void seed_define_cairo_pdf_surface(SeedContext ctx, SeedObject namespace_ref); #endif seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/cairo/seed-cairo-surface.c000066400000000000000000000413131303774616400252020ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #include #include #include "seed-cairo.h" #include "seed-cairo-image-surface.h" #include "seed-cairo-pdf-surface.h" #define CAIRO_SURFACE_PRIV(obj) \ ((cairo_surface_t*) seed_object_get_private(obj)) #define CHECK_SURFACE(obj, res) \ ({ \ if (!seed_object_is_of_class(ctx, obj, seed_cairo_surface_class)) { \ seed_make_exception(ctx, exception, "ArgumentError", \ "Object is not a Cairo Surface"); \ return seed_make_##res(ctx); \ } \ if (!seed_object_get_private(obj)) { \ seed_make_exception(ctx, exception, "ArgumentError", \ "Cairo surface has been destroyed"); \ return seed_make_##res(ctx); \ } \ }) #define CHECK_THIS() \ if (!seed_object_get_private(this_object)) { \ seed_make_exception(ctx, exception, "ArgumentError", \ "Cairo surface has been destroyed"); \ return seed_make_undefined(ctx); \ } #define CHECK_THIS_BOOL(res) \ if (!seed_object_get_private(this_object)) { \ seed_make_exception(ctx, exception, "ArgumentError", \ "Cairo surface has been destroyed"); \ return FALSE; \ } SeedClass seed_cairo_surface_class; SeedClass seed_get_cairo_surface_class() { return seed_cairo_surface_class; } static void seed_cairo_surface_finalize(SeedObject obj) { cairo_surface_t* s = CAIRO_SURFACE_PRIV(obj); if (s) { cairo_surface_set_user_data(s, seed_get_cairo_key(), NULL, NULL); cairo_surface_destroy(s); } } cairo_surface_t* seed_object_to_cairo_surface(SeedContext ctx, SeedObject obj, SeedException* exception) { if (seed_object_is_of_class(ctx, obj, seed_cairo_surface_class)) return CAIRO_SURFACE_PRIV(obj); seed_make_exception(ctx, exception, "ArgumentError", "Object is not a Cairo Surface"); return NULL; } SeedObject seed_object_from_cairo_surface(SeedContext ctx, cairo_surface_t* surf) { SeedObject jsobj; jsobj = cairo_surface_get_user_data(surf, seed_get_cairo_key()); if (jsobj) return jsobj; jsobj = seed_make_object(ctx, seed_cairo_surface_class, surf); cairo_surface_set_user_data(surf, seed_get_cairo_key(), jsobj, seed_cairo_destroy_func); return jsobj; } static SeedValue seed_cairo_surface_create_similar(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { gint width, height; cairo_surface_t *surface, *ret; cairo_content_t content; CHECK_THIS(); if (argument_count != 3) { EXPECTED_EXCEPTION("create_similar", "3 arguments"); } surface = seed_object_to_cairo_surface(ctx, this_object, exception); if (!surface) return seed_make_undefined(ctx); content = seed_value_to_long(ctx, arguments[0], exception); width = seed_value_to_int(ctx, arguments[1], exception); height = seed_value_to_int(ctx, arguments[2], exception); ret = cairo_surface_create_similar(surface, content, width, height); return seed_object_from_cairo_surface(ctx, ret); } static SeedValue seed_cairo_surface_status(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedException* exception) { CHECK_THIS(); return seed_value_from_long(ctx, cairo_surface_status( seed_object_to_cairo_surface(ctx, this_object, exception)), exception); } static SeedValue seed_cairo_surface_get_content(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedException* exception) { CHECK_THIS(); return seed_value_from_long(ctx, cairo_surface_get_content( seed_object_to_cairo_surface(ctx, this_object, exception)), exception); } static SeedValue seed_cairo_surface_finish(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { CHECK_THIS(); cairo_surface_finish( seed_object_to_cairo_surface(ctx, this_object, exception)); return seed_make_undefined(ctx); } static SeedValue seed_cairo_surface_flush(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { CHECK_THIS(); cairo_surface_flush( seed_object_to_cairo_surface(ctx, this_object, exception)); return seed_make_undefined(ctx); } static SeedValue seed_cairo_surface_mark_dirty_rectangle(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { cairo_surface_t* surf; guint x, y, width, height; CHECK_THIS(); if (argument_count != 4) { EXPECTED_EXCEPTION("mark_dirty_rectangle", "4 arguments"); } surf = seed_object_to_cairo_surface(ctx, this_object, exception); x = seed_value_to_int(ctx, arguments[0], exception); y = seed_value_to_int(ctx, arguments[1], exception); width = seed_value_to_int(ctx, arguments[2], exception); height = seed_value_to_int(ctx, arguments[3], exception); cairo_surface_mark_dirty_rectangle(surf, x, y, width, height); return seed_make_undefined(ctx); } static SeedValue seed_cairo_surface_mark_dirty(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { CHECK_THIS(); cairo_surface_mark_dirty( seed_object_to_cairo_surface(ctx, this_object, exception)); return seed_make_undefined(ctx); } static gboolean seed_cairo_surface_set_device_offset(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedValue value, SeedException* exception) { cairo_surface_t* surf; gdouble x, y; SeedValue jsx, jsy; CHECK_THIS_BOOL(); if (!seed_value_is_object(ctx, value)) { seed_make_exception( ctx, exception, "ArgumentError", "Cairo.Surface.device_offset must be an array [x,y]"); return FALSE; } jsx = seed_object_get_property_at_index(ctx, (SeedObject) value, 0, exception); jsy = seed_object_get_property_at_index(ctx, (SeedObject) value, 1, exception); surf = seed_object_to_cairo_surface(ctx, this_object, exception); x = seed_value_to_double(ctx, jsx, exception); y = seed_value_to_double(ctx, jsy, exception); cairo_surface_set_device_offset(surf, x, y); return TRUE; } static SeedValue seed_cairo_surface_get_device_offset(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedException* exception) { SeedValue offsets[2]; cairo_surface_t* surf; gdouble x, y; CHECK_THIS(); surf = seed_object_to_cairo_surface(ctx, this_object, exception); cairo_surface_get_device_offset(surf, &x, &y); offsets[0] = seed_value_from_double(ctx, x, exception); offsets[1] = seed_value_from_double(ctx, y, exception); return seed_make_array(ctx, offsets, 2, exception); } static gboolean seed_cairo_surface_set_fallback_resolution(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedValue value, SeedException* exception) { cairo_surface_t* surf; gdouble x, y; SeedValue jsx, jsy; CHECK_THIS_BOOL(); if (!seed_value_is_object(ctx, value)) { seed_make_exception( ctx, exception, "ArgumentError", "Cairo.Surface.fallback_resolution must be an array [x,y]"); return FALSE; } jsx = seed_object_get_property_at_index(ctx, (SeedObject) value, 0, exception); jsy = seed_object_get_property_at_index(ctx, (SeedObject) value, 1, exception); surf = seed_object_to_cairo_surface(ctx, this_object, exception); x = seed_value_to_double(ctx, jsx, exception); y = seed_value_to_double(ctx, jsy, exception); cairo_surface_set_fallback_resolution(surf, x, y); return TRUE; } static SeedValue seed_cairo_surface_get_fallback_resolution(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedException* exception) { SeedValue offsets[2]; cairo_surface_t* surf; gdouble x, y; CHECK_THIS(); surf = seed_object_to_cairo_surface(ctx, this_object, exception); cairo_surface_get_fallback_resolution(surf, &x, &y); offsets[0] = seed_value_from_double(ctx, x, exception); offsets[1] = seed_value_from_double(ctx, y, exception); return seed_make_array(ctx, offsets, 2, exception); } static SeedValue seed_cairo_surface_get_type(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedException* exception) { CHECK_THIS(); return seed_value_from_long(ctx, cairo_surface_get_type( seed_object_to_cairo_surface(ctx, this_object, exception)), exception); } static SeedValue seed_cairo_surface_copy_page(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { CHECK_THIS(); cairo_surface_copy_page( seed_object_to_cairo_surface(ctx, this_object, exception)); return seed_make_undefined(ctx); } static SeedValue seed_cairo_surface_show_page(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { CHECK_THIS(); cairo_surface_show_page( seed_object_to_cairo_surface(ctx, this_object, exception)); return seed_make_undefined(ctx); } static SeedValue seed_cairo_surface_has_show_text_glyphs(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { CHECK_THIS(); return seed_value_from_boolean( ctx, cairo_surface_has_show_text_glyphs( seed_object_to_cairo_surface(ctx, this_object, exception)), exception); } static SeedValue seed_cairo_surface_write_to_png(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { cairo_status_t ret; cairo_surface_t* surf; gchar* filename; CHECK_THIS(); if (argument_count != 1) { EXPECTED_EXCEPTION("write_to_png", "1 argument"); } surf = seed_object_get_private(this_object); filename = seed_value_to_string(ctx, arguments[0], exception); ret = cairo_surface_write_to_png(surf, filename); g_free(filename); return seed_value_from_long(ctx, ret, exception); } seed_static_function surface_funcs[] = { { "create_similar", seed_cairo_surface_create_similar, 0 }, { "finish", seed_cairo_surface_finish, 0 }, { "flush", seed_cairo_surface_flush, 0 }, // {"get_font_options", seed_cairo_surface_get_font_options, 0}, { "mark_dirty", seed_cairo_surface_mark_dirty, 0 }, { "mark_dirty_rectangle", seed_cairo_surface_mark_dirty_rectangle, 0 }, { "copy_page", seed_cairo_surface_copy_page, 0 }, { "show_page", seed_cairo_surface_show_page, 0 }, { "has_show_text_glyphs", seed_cairo_surface_has_show_text_glyphs, 0 }, { "write_to_png", seed_cairo_surface_write_to_png, 0 }, { 0, 0, 0 } }; seed_static_value surface_values[] = { { "type", seed_cairo_surface_get_type, 0, SEED_PROPERTY_ATTRIBUTE_READ_ONLY | SEED_PROPERTY_ATTRIBUTE_DONT_DELETE }, { "content", seed_cairo_surface_get_content, 0, SEED_PROPERTY_ATTRIBUTE_READ_ONLY | SEED_PROPERTY_ATTRIBUTE_DONT_DELETE }, { "status", seed_cairo_surface_status, 0, SEED_PROPERTY_ATTRIBUTE_READ_ONLY | SEED_PROPERTY_ATTRIBUTE_DONT_DELETE }, { "device_offset", seed_cairo_surface_get_device_offset, seed_cairo_surface_set_device_offset, SEED_PROPERTY_ATTRIBUTE_DONT_DELETE }, { "fallback_resolution", seed_cairo_surface_get_fallback_resolution, seed_cairo_surface_set_fallback_resolution, SEED_PROPERTY_ATTRIBUTE_DONT_DELETE }, { 0, 0, 0, 0 } }; void seed_define_cairo_surface(SeedContext ctx, SeedObject namespace_ref) { seed_class_definition surface_def = seed_empty_class; surface_def.class_name = "Surface"; surface_def.finalize = seed_cairo_surface_finalize; surface_def.static_functions = surface_funcs; surface_def.static_values = surface_values; seed_cairo_surface_class = seed_create_class(&surface_def); seed_define_cairo_image_surface(ctx, namespace_ref); seed_define_cairo_pdf_surface(ctx, namespace_ref); } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/cairo/seed-cairo-surface.h000066400000000000000000000007771303774616400252200ustar00rootroot00000000000000#ifndef _SEED_CAIRO_SURFACE_H #define _SEED_CAIRO_SURFACE_H SeedClass seed_get_cairo_surface_class(); void seed_define_cairo_surface(SeedContext ctx, SeedObject namespace_ref); cairo_surface_t* seed_object_to_cairo_surface(SeedContext ctx, SeedObject obj, SeedException* exception); SeedObject seed_object_from_cairo_surface(SeedContext ctx, cairo_surface_t* surf); #endif seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/cairo/seed-cairo.c000066400000000000000000001651631303774616400235660ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #include #include #include #include "seed-cairo.h" #include "seed-cairo-surface.h" #include "seed-cairo-image-surface.h" #include "seed-cairo-enums.h" #include "seed-cairo-matrix.h" #include "seed-cairo-pattern.h" SeedEngine* eng; #define CAIRO_CONTEXT_PRIV(obj) ((cairo_t*) seed_object_get_private(obj)) #define CHECK_CAIRO(obj) \ ({ \ if (!seed_object_is_of_class(ctx, obj, seed_cairo_class)) { \ seed_make_exception(ctx, exception, "ArgumentError", \ "Object is not a Cairo Context"); \ return seed_make_undefined(ctx); \ } \ if (!seed_object_get_private(obj)) { \ seed_make_exception(ctx, exception, "ArgumentError", \ "Cairo Context has been destroyed"); \ return seed_make_undefined(ctx); \ } \ }) #define CHECK_THIS() \ if (!seed_object_get_private(this_object)) { \ seed_make_exception(ctx, exception, "ArgumentError", \ "Cairo Context has been destroyed"); \ return seed_make_undefined(ctx); \ } #define CHECK_THIS_BOOL() \ if (!seed_object_get_private(this_object)) { \ seed_make_exception(ctx, exception, "ArgumentError", \ "Cairo Context has been destroyed"); \ return FALSE; \ } SeedClass seed_cairo_context_class; cairo_user_data_key_t* seed_get_cairo_key() { static cairo_user_data_key_t foobaz; return &foobaz; } void seed_cairo_destroy_func(void* obj) { SeedObject object = (SeedObject) obj; seed_object_set_private(object, NULL); } cairo_t* seed_object_to_cairo_context(SeedContext ctx, SeedObject obj, SeedException* exception) { if (seed_object_is_of_class(ctx, obj, seed_cairo_context_class)) return CAIRO_CONTEXT_PRIV(obj); seed_make_exception(ctx, exception, "ArgumentError", "Object is not a Cairo Context"); return NULL; } SeedObject seed_object_from_cairo_context(SeedContext ctx, cairo_t* cr) { SeedObject jsobj; jsobj = cairo_get_user_data(cr, seed_get_cairo_key()); if (jsobj) return jsobj; jsobj = seed_make_object(ctx, seed_cairo_context_class, cr); cairo_set_user_data(cr, seed_get_cairo_key(), jsobj, seed_cairo_destroy_func); return jsobj; } void seed_cairo_context_finalize(SeedObject obj) { cairo_t* cr = CAIRO_CONTEXT_PRIV(obj); if (cr) { cairo_set_user_data(cr, seed_get_cairo_key(), NULL, NULL); cairo_destroy(cr); } } static SeedObject seed_cairo_construct_context(SeedContext ctx, SeedObject constructor, size_t argument_count, const SeedValue arguments[], SeedException* exception) { cairo_surface_t* surf; if (argument_count != 1) { EXPECTED_EXCEPTION("Context", "1 argument"); } surf = seed_object_to_cairo_surface(ctx, arguments[0], exception); if (!surf) return seed_make_undefined(ctx); return seed_object_from_cairo_context(ctx, cairo_create(surf)); } static SeedObject seed_cairo_construct_context_from_window(SeedContext ctx, SeedObject constructor, size_t argument_count, const SeedValue arguments[], SeedException* exception) { GObject* obj; if (argument_count != 1) { EXPECTED_EXCEPTION("Context", "1 argument"); } obj = seed_value_to_object(ctx, arguments[0], exception); if (!GDK_IS_WINDOW(obj)) { seed_make_exception( ctx, exception, "ArgumentError", "Context.from_window requires a GdkWindow argument"); return seed_make_null(ctx); } return seed_object_from_cairo_context(ctx, gdk_cairo_create(GDK_WINDOW(obj))); } static SeedObject seed_cairo_construct_context_steal(SeedContext ctx, SeedObject constructor, size_t argument_count, const SeedValue arguments[], SeedException* exception) { if (argument_count != 1) { EXPECTED_EXCEPTION("Context", "1 argument"); } cairo_t* cr = seed_pointer_get_pointer(ctx, arguments[0]); if (!cr) { seed_make_exception(ctx, exception, "ArgumentError", "Context.steal requires a cairo context argument"); return seed_make_null(ctx); } return seed_object_from_cairo_context(ctx, cr); } static SeedValue seed_cairo_save(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { CHECK_THIS(); cairo_t* cr = seed_object_get_private(this_object); cairo_save(cr); return seed_make_undefined(ctx); } static SeedValue seed_cairo_restore(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { CHECK_THIS(); cairo_t* cr = seed_object_get_private(this_object); cairo_restore(cr); return seed_make_undefined(ctx); } static SeedValue seed_cairo_get_target(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedException* exception) { CHECK_THIS(); cairo_t* cr = seed_object_get_private(this_object); return seed_object_from_cairo_surface(ctx, cairo_get_target(cr)); } static SeedValue seed_cairo_push_group(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { CHECK_THIS(); cairo_t* cr = seed_object_get_private(this_object); cairo_push_group(cr); return seed_make_undefined(ctx); } static SeedValue seed_cairo_push_group_with_content(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { cairo_content_t content; cairo_t* cr; if (argument_count != 1) { EXPECTED_EXCEPTION("push_group_with_content", "1 argument"); } CHECK_THIS(); cr = seed_object_get_private(this_object); content = seed_value_to_long(ctx, arguments[0], exception); cairo_push_group_with_content(cr, content); return seed_make_undefined(ctx); } static SeedValue seed_cairo_pop_group_to_source(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { CHECK_THIS(); cairo_t* cr = seed_object_get_private(this_object); cairo_pop_group_to_source(cr); return seed_make_undefined(ctx); } static SeedValue seed_cairo_get_group_target(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { CHECK_THIS(); cairo_t* cr = seed_object_get_private(this_object); return seed_object_from_cairo_surface(ctx, cairo_get_group_target(cr)); } static SeedValue seed_cairo_set_source_rgb(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { gdouble r, g, b; cairo_t* cr; CHECK_THIS(); cr = seed_object_get_private(this_object); if (argument_count != 3) { EXPECTED_EXCEPTION("set_source_rgb", "3 arguments"); } r = seed_value_to_double(ctx, arguments[0], exception); g = seed_value_to_double(ctx, arguments[1], exception); b = seed_value_to_double(ctx, arguments[2], exception); cairo_set_source_rgb(cr, r, g, b); return seed_make_undefined(ctx); } static SeedValue seed_cairo_set_source_rgba(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { gdouble r, g, b, a; cairo_t* cr; CHECK_THIS(); cr = seed_object_get_private(this_object); if (argument_count != 4) { EXPECTED_EXCEPTION("set_source_rgba", "4 arguments"); } r = seed_value_to_double(ctx, arguments[0], exception); g = seed_value_to_double(ctx, arguments[1], exception); b = seed_value_to_double(ctx, arguments[2], exception); a = seed_value_to_double(ctx, arguments[3], exception); cairo_set_source_rgba(cr, r, g, b, a); return seed_make_undefined(ctx); } static SeedValue seed_cairo_set_source_surface(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { gdouble x, y; cairo_surface_t* surface; cairo_t* cr; CHECK_THIS(); cr = seed_object_get_private(this_object); surface = seed_object_to_cairo_surface(ctx, arguments[0], exception); if (!surface) return seed_make_undefined(ctx); x = seed_value_to_double(ctx, arguments[1], exception); y = seed_value_to_double(ctx, arguments[2], exception); cairo_set_source_surface(cr, surface, x, y); return seed_make_undefined(ctx); } static gboolean seed_cairo_set_antialias(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedValue value, SeedException* exception) { cairo_t* cr; cairo_antialias_t antialias; CHECK_THIS_BOOL(); cr = seed_object_get_private(this_object); antialias = seed_value_to_long(ctx, value, exception); cairo_set_antialias(cr, antialias); return TRUE; } static SeedValue seed_cairo_get_antialias(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedException* exception) { cairo_antialias_t antialias; cairo_t* cr; CHECK_THIS(); cr = seed_object_get_private(this_object); antialias = cairo_get_antialias(cr); return seed_value_from_long(ctx, antialias, exception); } static SeedValue seed_cairo_set_dash(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { SeedValue length; cairo_t* cr; gdouble *dashes, offset; gint num_dashes, i; CHECK_THIS(); cr = seed_object_get_private(this_object); if (argument_count != 2) { EXPECTED_EXCEPTION("set_dash", "2 arguments"); } length = seed_object_get_property(ctx, arguments[0], "length"); num_dashes = seed_value_to_int(ctx, length, exception); dashes = g_alloca(num_dashes * sizeof(gdouble)); for (i = 0; i < num_dashes; i++) { dashes[i] = seed_value_to_double( ctx, seed_object_get_property_at_index(ctx, arguments[0], i, exception), exception); } offset = seed_value_to_double(ctx, arguments[1], exception); cairo_set_dash(cr, dashes, num_dashes, offset); return seed_make_undefined(ctx); } static SeedValue seed_cairo_pop_group(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { cairo_t* cr; CHECK_THIS(); cr = seed_object_get_private(this_object); return seed_object_from_cairo_pattern(ctx, cairo_pop_group(cr)); } static SeedValue seed_cairo_get_dash_count(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { cairo_t* cr; gint dash_count; CHECK_THIS(); cr = seed_object_get_private(this_object); dash_count = cairo_get_dash_count(cr); return seed_value_from_int(ctx, dash_count, exception); } static SeedValue seed_cairo_get_dash(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { SeedValue ret[2], *jsdashes; cairo_t* cr; gint dash_count, i; gdouble *dashes, offset; CHECK_THIS(); cr = seed_object_get_private(this_object); dash_count = cairo_get_dash_count(cr); dashes = g_alloca(dash_count * sizeof(gdouble)); jsdashes = g_alloca(dash_count * sizeof(SeedValue)); cairo_get_dash(cr, dashes, &offset); for (i = 0; i < dash_count; i++) { jsdashes[i] = seed_value_from_double(ctx, dashes[i], exception); } ret[0] = seed_make_array(ctx, jsdashes, dash_count, exception); ret[1] = seed_value_from_double(ctx, offset, exception); return seed_make_array(ctx, ret, 2, exception); } static SeedValue seed_cairo_get_fill_rule(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedException* exception) { cairo_t* cr; CHECK_THIS(); cr = seed_object_get_private(this_object); return seed_value_from_long(ctx, cairo_get_fill_rule(cr), exception); } static gboolean seed_cairo_set_fill_rule(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedValue value, SeedException* exception) { cairo_t* cr; CHECK_THIS_BOOL(); cr = seed_object_get_private(this_object); cairo_set_fill_rule(cr, seed_value_to_long(ctx, value, exception)); return TRUE; } static SeedValue seed_cairo_get_line_cap(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedException* exception) { cairo_t* cr; CHECK_THIS(); cr = seed_object_get_private(this_object); return seed_value_from_long(ctx, cairo_get_line_cap(cr), exception); } static gboolean seed_cairo_set_line_cap(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedValue value, SeedException* exception) { cairo_t* cr; CHECK_THIS_BOOL(); cr = seed_object_get_private(this_object); cairo_set_line_cap(cr, seed_value_to_long(ctx, value, exception)); return TRUE; } static SeedValue seed_cairo_get_line_join(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedException* exception) { cairo_t* cr; CHECK_THIS(); cr = seed_object_get_private(this_object); return seed_value_from_long(ctx, cairo_get_line_join(cr), exception); } static gboolean seed_cairo_set_line_join(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedValue value, SeedException* exception) { cairo_t* cr; CHECK_THIS_BOOL(); cr = seed_object_get_private(this_object); cairo_set_line_join(cr, seed_value_to_long(ctx, value, exception)); return TRUE; } static SeedValue seed_cairo_get_line_width(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedException* exception) { cairo_t* cr; CHECK_THIS(); cr = seed_object_get_private(this_object); return seed_value_from_double(ctx, cairo_get_line_width(cr), exception); } static gboolean seed_cairo_set_line_width(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedValue value, SeedException* exception) { cairo_t* cr; CHECK_THIS_BOOL(); cr = seed_object_get_private(this_object); cairo_set_line_width(cr, seed_value_to_double(ctx, value, exception)); return TRUE; } static SeedValue seed_cairo_get_miter_limit(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedException* exception) { cairo_t* cr; CHECK_THIS(); cr = seed_object_get_private(this_object); return seed_value_from_double(ctx, cairo_get_miter_limit(cr), exception); } static gboolean seed_cairo_set_miter_limit(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedValue value, SeedException* exception) { cairo_t* cr; CHECK_THIS_BOOL(); cr = seed_object_get_private(this_object); cairo_set_miter_limit(cr, seed_value_to_double(ctx, value, exception)); return TRUE; } static SeedValue seed_cairo_get_operator(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedException* exception) { cairo_t* cr; CHECK_THIS(); cr = seed_object_get_private(this_object); return seed_value_from_long(ctx, cairo_get_operator(cr), exception); } static gboolean seed_cairo_set_operator(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedValue value, SeedException* exception) { cairo_t* cr; CHECK_THIS_BOOL(); cr = seed_object_get_private(this_object); cairo_set_operator(cr, seed_value_to_long(ctx, value, exception)); return TRUE; } static SeedValue seed_cairo_get_tolerance(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedException* exception) { cairo_t* cr; CHECK_THIS(); cr = seed_object_get_private(this_object); return seed_value_from_double(ctx, cairo_get_tolerance(cr), exception); } static gboolean seed_cairo_set_tolerance(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedValue value, SeedException* exception) { cairo_t* cr; CHECK_THIS_BOOL(); cr = seed_object_get_private(this_object); cairo_set_tolerance(cr, seed_value_to_double(ctx, value, exception)); return TRUE; } static SeedValue seed_cairo_clip(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { CHECK_THIS(); cairo_t* cr = seed_object_get_private(this_object); cairo_clip(cr); return seed_make_undefined(ctx); } static SeedValue seed_cairo_clip_preserve(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { CHECK_THIS(); cairo_t* cr = seed_object_get_private(this_object); cairo_clip_preserve(cr); return seed_make_undefined(ctx); } static SeedValue seed_cairo_reset_clip(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { CHECK_THIS(); cairo_t* cr = seed_object_get_private(this_object); cairo_reset_clip(cr); return seed_make_undefined(ctx); } static SeedValue seed_cairo_clip_extents(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { SeedValue jsextents[4]; gdouble extents[4]; CHECK_THIS(); cairo_t* cr = seed_object_get_private(this_object); if (argument_count != 4) { EXPECTED_EXCEPTION("clip_extents", "4 arguments"); } cairo_clip_extents(cr, &extents[0], &extents[1], &extents[2], &extents[3]); jsextents[0] = seed_value_from_double(ctx, extents[0], exception); jsextents[1] = seed_value_from_double(ctx, extents[1], exception); jsextents[2] = seed_value_from_double(ctx, extents[2], exception); jsextents[3] = seed_value_from_double(ctx, extents[3], exception); return seed_make_array(ctx, jsextents, 4, exception); } static SeedValue seed_cairo_fill(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { CHECK_THIS(); cairo_t* cr = seed_object_get_private(this_object); cairo_fill(cr); return seed_make_undefined(ctx); } static SeedValue seed_cairo_fill_preserve(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { CHECK_THIS(); cairo_t* cr = seed_object_get_private(this_object); cairo_fill_preserve(cr); return seed_make_undefined(ctx); } static SeedValue seed_cairo_fill_extents(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { SeedValue jsextents[4]; gdouble extents[4]; CHECK_THIS(); cairo_t* cr = seed_object_get_private(this_object); if (argument_count != 4) { EXPECTED_EXCEPTION("clip_extents", "4 arguments"); } cairo_fill_extents(cr, &extents[0], &extents[1], &extents[2], &extents[3]); jsextents[0] = seed_value_from_double(ctx, extents[0], exception); jsextents[1] = seed_value_from_double(ctx, extents[1], exception); jsextents[2] = seed_value_from_double(ctx, extents[2], exception); jsextents[3] = seed_value_from_double(ctx, extents[3], exception); return seed_make_array(ctx, jsextents, 4, exception); } static SeedValue seed_cairo_in_fill(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { gdouble x, y; cairo_t* cr; CHECK_THIS(); cr = seed_object_get_private(this_object); if (argument_count != 2) { EXPECTED_EXCEPTION("in_fill", "2 arguments"); } x = seed_value_to_double(ctx, arguments[0], exception); y = seed_value_to_double(ctx, arguments[1], exception); return seed_value_from_boolean(ctx, cairo_in_fill(cr, x, y), exception); } static SeedValue seed_cairo_mask_surface(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { gdouble x, y; cairo_surface_t* surface; cairo_t* cr; cr = seed_object_get_private(this_object); surface = seed_object_to_cairo_surface(ctx, arguments[0], exception); if (!surface) return seed_make_undefined(ctx); x = seed_value_to_double(ctx, arguments[1], exception); y = seed_value_to_double(ctx, arguments[2], exception); cairo_mask_surface(cr, surface, x, y); return seed_make_undefined(ctx); } static SeedValue seed_cairo_mask(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { cairo_t* cr; cairo_pattern_t* pat; CHECK_THIS(); if (argument_count != 1 && argument_count != 3) { EXPECTED_EXCEPTION("mask", "1 or 3 arguments"); } if (argument_count == 3) return seed_cairo_mask_surface(ctx, function, this_object, argument_count, arguments, exception); cr = seed_object_get_private(this_object); pat = seed_object_to_cairo_pattern(ctx, arguments[0], exception); if (!pat) { seed_make_exception(ctx, arguments[0], "ArgumentError", "First argument should be a cairo_pattern" " (or cairo surface if there are three arguments)"); return seed_make_undefined(ctx); } cairo_mask(cr, pat); return seed_make_undefined(ctx); } static SeedValue seed_cairo_paint(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { CHECK_THIS(); cairo_t* cr = seed_object_get_private(this_object); cairo_paint(cr); return seed_make_undefined(ctx); } static SeedValue seed_cairo_paint_with_alpha(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { cairo_t* cr; CHECK_THIS(); if (argument_count != 1) { EXPECTED_EXCEPTION("paint_with_alpha", "1 argument"); } cr = seed_object_get_private(this_object); cairo_paint_with_alpha(cr, seed_value_to_double(ctx, arguments[0], exception)); return seed_make_undefined(ctx); } static SeedValue seed_cairo_stroke(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { CHECK_THIS(); cairo_t* cr = seed_object_get_private(this_object); cairo_stroke(cr); return seed_make_undefined(ctx); } static SeedValue seed_cairo_stroke_preserve(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { CHECK_THIS(); cairo_t* cr = seed_object_get_private(this_object); cairo_stroke_preserve(cr); return seed_make_undefined(ctx); } static SeedValue seed_cairo_stroke_extents(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { SeedValue jsextents[4]; gdouble extents[4]; CHECK_THIS(); cairo_t* cr = seed_object_get_private(this_object); if (argument_count != 4) { EXPECTED_EXCEPTION("clip_extents", "4 arguments"); } cairo_stroke_extents(cr, &extents[0], &extents[1], &extents[2], &extents[3]); jsextents[0] = seed_value_from_double(ctx, extents[0], exception); jsextents[1] = seed_value_from_double(ctx, extents[1], exception); jsextents[2] = seed_value_from_double(ctx, extents[2], exception); jsextents[3] = seed_value_from_double(ctx, extents[3], exception); return seed_make_array(ctx, jsextents, 4, exception); } static SeedValue seed_cairo_in_stroke(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { gdouble x, y; cairo_t* cr; CHECK_THIS(); cr = seed_object_get_private(this_object); if (argument_count != 2) { EXPECTED_EXCEPTION("in_stroke", "2 arguments"); } x = seed_value_to_double(ctx, arguments[0], exception); y = seed_value_to_double(ctx, arguments[1], exception); return seed_value_from_boolean(ctx, cairo_in_stroke(cr, x, y), exception); } static SeedValue seed_cairo_copy_page(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { CHECK_THIS(); cairo_t* cr = seed_object_get_private(this_object); cairo_copy_page(cr); return seed_make_undefined(ctx); } static SeedValue seed_cairo_show_page(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { CHECK_THIS(); cairo_t* cr = seed_object_get_private(this_object); cairo_show_page(cr); return seed_make_undefined(ctx); } static SeedValue seed_cairo_has_current_point(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { CHECK_THIS(); cairo_t* cr = seed_object_get_private(this_object); return seed_value_from_boolean(ctx, cairo_has_current_point(cr), exception); } static SeedValue seed_cairo_get_current_point(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { SeedValue points[2]; gdouble x, y; CHECK_THIS(); cairo_t* cr = seed_object_get_private(this_object); cairo_get_current_point(cr, &x, &y); points[0] = seed_value_from_double(ctx, x, exception); points[1] = seed_value_from_double(ctx, y, exception); return seed_make_array(ctx, points, 2, exception); } static SeedValue seed_cairo_new_path(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { CHECK_THIS(); cairo_t* cr = seed_object_get_private(this_object); cairo_new_path(cr); return seed_make_undefined(ctx); } static SeedValue seed_cairo_new_sub_path(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { CHECK_THIS(); cairo_t* cr = seed_object_get_private(this_object); cairo_new_sub_path(cr); return seed_make_undefined(ctx); } static SeedValue seed_cairo_close_path(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { CHECK_THIS(); cairo_t* cr = seed_object_get_private(this_object); cairo_close_path(cr); return seed_make_undefined(ctx); } static SeedValue seed_cairo_arc(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { gdouble xc, yc, radius, angle1, angle2; CHECK_THIS(); cairo_t* cr = seed_object_get_private(this_object); if (argument_count != 5) { EXPECTED_EXCEPTION("arc", "5 arguments"); } xc = seed_value_to_double(ctx, arguments[0], exception); yc = seed_value_to_double(ctx, arguments[1], exception); radius = seed_value_to_double(ctx, arguments[2], exception); angle1 = seed_value_to_double(ctx, arguments[3], exception); angle2 = seed_value_to_double(ctx, arguments[4], exception); cairo_arc(cr, xc, yc, radius, angle1, angle2); return seed_make_undefined(ctx); } static SeedValue seed_cairo_arc_negative(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { gdouble xc, yc, radius, angle1, angle2; CHECK_THIS(); cairo_t* cr = seed_object_get_private(this_object); if (argument_count != 5) { EXPECTED_EXCEPTION("arc_negative", "5 arguments"); } xc = seed_value_to_double(ctx, arguments[0], exception); yc = seed_value_to_double(ctx, arguments[1], exception); radius = seed_value_to_double(ctx, arguments[2], exception); angle1 = seed_value_to_double(ctx, arguments[3], exception); angle2 = seed_value_to_double(ctx, arguments[4], exception); cairo_arc_negative(cr, xc, yc, radius, angle1, angle2); return seed_make_undefined(ctx); } static SeedValue seed_cairo_curve_to(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { gdouble x1, y1, x2, y2, x3, y3; CHECK_THIS(); cairo_t* cr = seed_object_get_private(this_object); if (argument_count != 6) { EXPECTED_EXCEPTION("curve_to", "6 arguments"); } x1 = seed_value_to_double(ctx, arguments[0], exception); y1 = seed_value_to_double(ctx, arguments[1], exception); x2 = seed_value_to_double(ctx, arguments[2], exception); y2 = seed_value_to_double(ctx, arguments[3], exception); x3 = seed_value_to_double(ctx, arguments[4], exception); y3 = seed_value_to_double(ctx, arguments[5], exception); cairo_curve_to(cr, x1, y1, x2, y2, x3, y3); return seed_make_undefined(ctx); } static SeedValue seed_cairo_rel_curve_to(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { gdouble x1, y1, x2, y2, x3, y3; CHECK_THIS(); cairo_t* cr = seed_object_get_private(this_object); if (argument_count != 6) { EXPECTED_EXCEPTION("rel_curve_to", "6 arguments"); } x1 = seed_value_to_double(ctx, arguments[0], exception); y1 = seed_value_to_double(ctx, arguments[1], exception); x2 = seed_value_to_double(ctx, arguments[2], exception); y2 = seed_value_to_double(ctx, arguments[3], exception); x3 = seed_value_to_double(ctx, arguments[4], exception); y3 = seed_value_to_double(ctx, arguments[5], exception); cairo_rel_curve_to(cr, x1, y1, x2, y2, x3, y3); return seed_make_undefined(ctx); } static SeedValue seed_cairo_line_to(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { gdouble x1, y1; CHECK_THIS(); cairo_t* cr = seed_object_get_private(this_object); if (argument_count != 2) { EXPECTED_EXCEPTION("line_to", "2 arguments"); } x1 = seed_value_to_double(ctx, arguments[0], exception); y1 = seed_value_to_double(ctx, arguments[1], exception); cairo_line_to(cr, x1, y1); return seed_make_undefined(ctx); } static SeedValue seed_cairo_rel_line_to(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { gdouble x1, y1; CHECK_THIS(); cairo_t* cr = seed_object_get_private(this_object); if (argument_count != 2) { EXPECTED_EXCEPTION("rel_line_to", "2 arguments"); } x1 = seed_value_to_double(ctx, arguments[0], exception); y1 = seed_value_to_double(ctx, arguments[1], exception); cairo_rel_line_to(cr, x1, y1); return seed_make_undefined(ctx); } static SeedValue seed_cairo_move_to(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { gdouble x1, y1; CHECK_THIS(); cairo_t* cr = seed_object_get_private(this_object); if (argument_count != 2) { EXPECTED_EXCEPTION("move_to", "2 arguments"); } x1 = seed_value_to_double(ctx, arguments[0], exception); y1 = seed_value_to_double(ctx, arguments[1], exception); cairo_move_to(cr, x1, y1); return seed_make_undefined(ctx); } static SeedValue seed_cairo_rel_move_to(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { gdouble x1, y1; CHECK_THIS(); cairo_t* cr = seed_object_get_private(this_object); if (argument_count != 2) { EXPECTED_EXCEPTION("rel_move_to", "2 arguments"); } x1 = seed_value_to_double(ctx, arguments[0], exception); y1 = seed_value_to_double(ctx, arguments[1], exception); cairo_rel_move_to(cr, x1, y1); return seed_make_undefined(ctx); } static SeedValue seed_cairo_rectangle(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { gdouble x1, y1, width, height; CHECK_THIS(); cairo_t* cr = seed_object_get_private(this_object); if (argument_count != 4) { EXPECTED_EXCEPTION("rectangle", "2 arguments"); } x1 = seed_value_to_double(ctx, arguments[0], exception); y1 = seed_value_to_double(ctx, arguments[1], exception); width = seed_value_to_double(ctx, arguments[2], exception); height = seed_value_to_double(ctx, arguments[3], exception); cairo_rectangle(cr, x1, y1, width, height); return seed_make_undefined(ctx); } static SeedValue seed_cairo_text_path(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { cairo_t* cr; gchar* text; CHECK_THIS(); cr = seed_object_get_private(this_object); if (argument_count != 1) { EXPECTED_EXCEPTION("text_path", "1 argument"); } text = seed_value_to_string(ctx, arguments[0], exception); cairo_text_path(cr, text); g_free(text); return seed_make_undefined(ctx); } static SeedValue seed_cairo_path_extents(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { SeedValue jsextents[4]; gdouble extents[4]; CHECK_THIS(); cairo_t* cr = seed_object_get_private(this_object); if (argument_count != 4) { EXPECTED_EXCEPTION("path_extents", "4 arguments"); } cairo_path_extents(cr, &extents[0], &extents[1], &extents[2], &extents[3]); jsextents[0] = seed_value_from_double(ctx, extents[0], exception); jsextents[1] = seed_value_from_double(ctx, extents[1], exception); jsextents[2] = seed_value_from_double(ctx, extents[2], exception); jsextents[3] = seed_value_from_double(ctx, extents[3], exception); return seed_make_array(ctx, jsextents, 4, exception); } static SeedValue seed_cairo_translate(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { gdouble x1, y1; CHECK_THIS(); cairo_t* cr = seed_object_get_private(this_object); if (argument_count != 2) { EXPECTED_EXCEPTION("translate", "2 arguments"); } x1 = seed_value_to_double(ctx, arguments[0], exception); y1 = seed_value_to_double(ctx, arguments[1], exception); cairo_translate(cr, x1, y1); return seed_make_undefined(ctx); } static SeedValue seed_cairo_scale(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { gdouble x1, y1; CHECK_THIS(); cairo_t* cr = seed_object_get_private(this_object); if (argument_count != 2) { EXPECTED_EXCEPTION("scale", "2 arguments"); } x1 = seed_value_to_double(ctx, arguments[0], exception); y1 = seed_value_to_double(ctx, arguments[1], exception); cairo_scale(cr, x1, y1); return seed_make_undefined(ctx); } static SeedValue seed_cairo_rotate(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { gdouble angle; CHECK_THIS(); cairo_t* cr = seed_object_get_private(this_object); if (argument_count != 1) { EXPECTED_EXCEPTION("rotate", "1 arguments"); } angle = seed_value_to_double(ctx, arguments[0], exception); cairo_rotate(cr, angle); return seed_make_undefined(ctx); } static SeedValue seed_cairo_transform(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { cairo_matrix_t matrix; cairo_t* cr; CHECK_THIS(); if (argument_count != 1) { EXPECTED_EXCEPTION("transform", "1 argument"); } if (!seed_value_to_cairo_matrix(ctx, arguments[0], &matrix, exception)) { seed_make_exception(ctx, exception, "ArgumentError", "transform expects an array [xx,yx,xy,yy,x0,y0]"); return seed_make_undefined(ctx); } cr = seed_object_get_private(this_object); cairo_transform(cr, &matrix); return seed_make_undefined(ctx); } static SeedValue seed_cairo_get_matrix(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedException* exception) { cairo_t* cr; cairo_matrix_t m; CHECK_THIS(); cr = seed_object_get_private(this_object); cairo_get_matrix(cr, &m); return seed_value_from_cairo_matrix(ctx, &m, exception); } static gboolean seed_cairo_set_matrix(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedValue value, SeedException* exception) { cairo_matrix_t m; cairo_t* cr; CHECK_THIS_BOOL(); cr = seed_object_get_private(this_object); if (!seed_value_to_cairo_matrix(ctx, value, &m, exception)) { seed_make_exception(ctx, exception, "ArgumentError", "matrix must be an array [xx,yx,xy,yy,x0,y0]"); return FALSE; } cairo_set_matrix(cr, &m); return TRUE; } static SeedValue seed_cairo_identity_matrix(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { CHECK_THIS(); cairo_t* cr = seed_object_get_private(this_object); cairo_identity_matrix(cr); return seed_make_undefined(ctx); } static SeedValue seed_cairo_user_to_device(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { SeedValue out[2]; cairo_t* cr; double ix, iy; CHECK_THIS(); if (argument_count != 2) { EXPECTED_EXCEPTION("user_to_device", "2 arguments"); } cr = seed_object_get_private(this_object); ix = seed_value_to_double(ctx, arguments[0], exception); iy = seed_value_to_double(ctx, arguments[1], exception); cairo_user_to_device(cr, &ix, &iy); out[0] = seed_value_from_double(ctx, ix, exception); out[1] = seed_value_from_double(ctx, iy, exception); return seed_make_array(ctx, out, 2, exception); } static SeedValue seed_cairo_user_to_device_distance(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { SeedValue out[2]; cairo_t* cr; double ix, iy; CHECK_THIS(); if (argument_count != 2) { EXPECTED_EXCEPTION("user_to_device_distance", "2 arguments"); } cr = seed_object_get_private(this_object); ix = seed_value_to_double(ctx, arguments[0], exception); iy = seed_value_to_double(ctx, arguments[1], exception); cairo_user_to_device_distance(cr, &ix, &iy); out[0] = seed_value_from_double(ctx, ix, exception); out[1] = seed_value_from_double(ctx, iy, exception); return seed_make_array(ctx, out, 2, exception); } static SeedValue seed_cairo_device_to_user(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { SeedValue out[2]; cairo_t* cr; double ix, iy; CHECK_THIS(); if (argument_count != 2) { EXPECTED_EXCEPTION("device_to_user", "2 arguments"); } cr = seed_object_get_private(this_object); ix = seed_value_to_double(ctx, arguments[0], exception); iy = seed_value_to_double(ctx, arguments[1], exception); cairo_device_to_user(cr, &ix, &iy); out[0] = seed_value_from_double(ctx, ix, exception); out[1] = seed_value_from_double(ctx, iy, exception); return seed_make_array(ctx, out, 2, exception); } static SeedValue seed_cairo_device_to_user_distance(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { SeedValue out[2]; cairo_t* cr; double ix, iy; CHECK_THIS(); if (argument_count != 2) { EXPECTED_EXCEPTION("device_to_user_distance", "2 arguments"); } cr = seed_object_get_private(this_object); ix = seed_value_to_double(ctx, arguments[0], exception); iy = seed_value_to_double(ctx, arguments[1], exception); cairo_device_to_user_distance(cr, &ix, &iy); out[0] = seed_value_from_double(ctx, ix, exception); out[1] = seed_value_from_double(ctx, iy, exception); return seed_make_array(ctx, out, 2, exception); } static SeedValue seed_cairo_set_source(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { cairo_t* cr; cairo_pattern_t* pat; CHECK_THIS(); if (argument_count != 1 && argument_count != 3) { EXPECTED_EXCEPTION("set_source", "1 or 3 arguments"); } if (argument_count == 3) return seed_cairo_set_source_surface(ctx, function, this_object, argument_count, arguments, exception); pat = seed_object_to_cairo_pattern(ctx, arguments[0], exception); if (!pat) { seed_make_exception(ctx, exception, "ArgumentError", "set_source needs a Cairo Pattern as argument"); return seed_make_undefined(ctx); } cr = seed_object_get_private(this_object); cairo_set_source(cr, pat); return seed_make_undefined(ctx); } static SeedValue seed_cairo_get_source(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { cairo_t* cr; CHECK_THIS(); cr = seed_object_get_private(this_object); return seed_object_from_cairo_pattern(ctx, cairo_get_source(cr)); } static SeedValue seed_cairo_destroy(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { seed_cairo_context_finalize(this_object); return seed_make_undefined(ctx); } seed_static_value cairo_values[] = { { "antialias", seed_cairo_get_antialias, seed_cairo_set_antialias, SEED_PROPERTY_ATTRIBUTE_DONT_DELETE }, { "fill_rule", seed_cairo_get_fill_rule, seed_cairo_set_fill_rule, SEED_PROPERTY_ATTRIBUTE_DONT_DELETE }, { "line_cap", seed_cairo_get_line_cap, seed_cairo_set_line_cap, SEED_PROPERTY_ATTRIBUTE_DONT_DELETE }, { "line_join", seed_cairo_get_line_join, seed_cairo_set_line_join, SEED_PROPERTY_ATTRIBUTE_DONT_DELETE }, { "line_width", seed_cairo_get_line_width, seed_cairo_set_line_width, SEED_PROPERTY_ATTRIBUTE_DONT_DELETE }, { "miter_limit", seed_cairo_get_miter_limit, seed_cairo_set_miter_limit, SEED_PROPERTY_ATTRIBUTE_DONT_DELETE }, { "operator", seed_cairo_get_operator, seed_cairo_set_operator, SEED_PROPERTY_ATTRIBUTE_DONT_DELETE }, { "tolerance", seed_cairo_get_tolerance, seed_cairo_set_tolerance, SEED_PROPERTY_ATTRIBUTE_DONT_DELETE }, { "matrix", seed_cairo_get_matrix, seed_cairo_set_matrix, SEED_PROPERTY_ATTRIBUTE_DONT_DELETE }, { "target", seed_cairo_get_target, NULL, SEED_PROPERTY_ATTRIBUTE_READ_ONLY | SEED_PROPERTY_ATTRIBUTE_DONT_DELETE }, { NULL, NULL, NULL, 0 } }; seed_static_function cairo_funcs[] = { { "save", seed_cairo_save, 0 }, { "restore", seed_cairo_restore, 0 }, { "push_group", seed_cairo_push_group, 0 }, { "push_group_with_content", seed_cairo_push_group_with_content, 0 }, { "set_dash", seed_cairo_set_dash, 0 }, { "get_dash_count", seed_cairo_get_dash_count, 0 }, { "get_dash", seed_cairo_get_dash, 0 }, { "pop_group", seed_cairo_pop_group, 0 }, { "pop_group_to_source", seed_cairo_pop_group_to_source, 0 }, { "get_group_target", seed_cairo_get_group_target, 0 }, { "set_source_rgb", seed_cairo_set_source_rgb, 0 }, { "set_source_rgba", seed_cairo_set_source_rgba, 0 }, { "set_source", seed_cairo_set_source, 0 }, { "set_source_surface", seed_cairo_set_source_surface, 0 }, { "get_source", seed_cairo_get_source, 0 }, { "clip", seed_cairo_clip, 0 }, { "clip_preserve", seed_cairo_clip_preserve, 0 }, { "reset_clip", seed_cairo_reset_clip, 0 }, { "clip_extents", seed_cairo_clip_extents, 0 }, // Rectangle list stuff? { "fill", seed_cairo_fill, 0 }, { "fill_preserve", seed_cairo_fill_preserve, 0 }, { "fill_extents", seed_cairo_fill_extents, 0 }, { "mask", seed_cairo_mask, 0 }, { "in_fill", seed_cairo_in_fill, 0 }, { "paint", seed_cairo_paint, 0 }, { "paint_with_alpha", seed_cairo_paint_with_alpha, 0 }, { "stroke", seed_cairo_stroke, 0 }, { "stroke_preserve", seed_cairo_stroke_preserve, 0 }, { "stroke_extents", seed_cairo_stroke_extents, 0 }, { "in_stroke", seed_cairo_in_stroke, 0 }, { "copy_page", seed_cairo_copy_page, 0 }, { "show_page", seed_cairo_show_page, 0 }, { "has_current_point", seed_cairo_has_current_point, 0 }, { "get_current_point", seed_cairo_get_current_point, 0 }, { "new_path", seed_cairo_new_path, 0 }, { "new_sub_path", seed_cairo_new_sub_path, 0 }, { "close_path", seed_cairo_close_path, 0 }, { "arc", seed_cairo_arc, 0 }, { "arc_negative", seed_cairo_arc_negative, 0 }, { "curve_to", seed_cairo_curve_to, 0 }, { "line_to", seed_cairo_line_to, 0 }, { "move_to", seed_cairo_move_to, 0 }, { "rectangle", seed_cairo_rectangle, 0 }, //{"cairo_glpyh_path", seed_cairo_glyph_path, 0}, { "text_path", seed_cairo_text_path, 0 }, { "rel_curve_to", seed_cairo_rel_curve_to, 0 }, { "rel_line_to", seed_cairo_rel_line_to, 0 }, { "rel_move_to", seed_cairo_rel_move_to, 0 }, { "path_extents", seed_cairo_path_extents, 0 }, { "translate", seed_cairo_translate, 0 }, { "scale", seed_cairo_scale, 0 }, { "rotate", seed_cairo_rotate, 0 }, { "transform", seed_cairo_transform, 0 }, { "identify_matrix", seed_cairo_identity_matrix, 0 }, { "user_to_device", seed_cairo_user_to_device, 0 }, { "user_to_device_distance", seed_cairo_user_to_device_distance, 0 }, { "device_to_user", seed_cairo_device_to_user, 0 }, { "device_to_user_distance", seed_cairo_device_to_user_distance, 0 }, { "destroy", seed_cairo_destroy, 0 }, { NULL, NULL, 0 } }; SeedObject seed_module_init(SeedEngine* local_eng) { SeedObject context_constructor_ref; SeedObject gdk_context_constructor_ref; SeedObject steal_context_constructor_ref; SeedObject namespace_ref; seed_class_definition cairo_def = seed_empty_class; eng = local_eng; namespace_ref = seed_make_object(eng->context, NULL, NULL); // Temporary hack until API changes. seed_value_protect(eng->context, namespace_ref); seed_define_cairo_enums(eng->context, namespace_ref); seed_define_cairo_surface(eng->context, namespace_ref); seed_define_cairo_matrix(eng->context, namespace_ref); seed_define_cairo_pattern(eng->context, namespace_ref); cairo_def.class_name = "Context"; cairo_def.static_functions = cairo_funcs; cairo_def.static_values = cairo_values; cairo_def.finalize = seed_cairo_context_finalize; seed_cairo_context_class = seed_create_class(&cairo_def); // Hack around WebKit GC bug. context_constructor_ref = seed_make_constructor( eng->context, NULL, // seed_cairo_context_class, seed_cairo_construct_context); gdk_context_constructor_ref = seed_make_constructor( eng->context, NULL, // seed_cairo_context_class, seed_cairo_construct_context_from_window); steal_context_constructor_ref = seed_make_constructor( eng->context, NULL, // seed_cairo_context_class, seed_cairo_construct_context_steal); seed_object_set_property(eng->context, namespace_ref, "Context", context_constructor_ref); seed_object_set_property(eng->context, context_constructor_ref, "from_window", gdk_context_constructor_ref); seed_object_set_property(eng->context, context_constructor_ref, "steal", steal_context_constructor_ref); return namespace_ref; } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/cairo/seed-cairo.h000066400000000000000000000007171303774616400235640ustar00rootroot00000000000000#ifndef _SEED_CAIRO_H #define _SEED_CAIRO_H #include #include #define EXPECTED_EXCEPTION(name, argnum) \ seed_make_exception(ctx, exception, "ArgumentError", \ name " expected " argnum " got %zd", argument_count); \ return seed_make_undefined(ctx); cairo_user_data_key_t* seed_get_cairo_key(); void seed_cairo_destroy_func(void* obj); #endif seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/canvas/000077500000000000000000000000001303774616400215515ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/canvas/Makefile.am000066400000000000000000000011521303774616400236040ustar00rootroot00000000000000if BUILD_CANVAS_MODULE seedlibdir = ${libdir}/seed@SEED_GTK_VERSION@ EXTRA_DIST=run-tests.js seedlib_LTLIBRARIES = \ libseed_canvas.la libseed_canvas_la_SOURCES = \ seed-canvas.c libseed_canvas_la_CFLAGS = \ $(GOBJECT_INTROSPECTION_CFLAGS) \ -I@top_srcdir@/libseed/ \ $(CAIRO_CFLAGS) \ $(SEED_DEBUG_CFLAGS) \ $(SEED_PROFILE_CFLAGS) libseed_canvas_la_LDFLAGS = \ -module -avoid-version \ $(GOBJECT_INTROSPECTION_LDFLAGS) \ $(CAIRO_LDFLAGS) libseed_canvas_la_LIBADD = \ $(top_builddir)/libseed/libseed@SEED_GTK_VERSION@.la \ $(CAIRO_LIBS) \ $(SEED_PROFILE_LIBS) endif -include $(top_srcdir)/git.mk seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/canvas/run-tests.js000077500000000000000000000220001303774616400240500ustar00rootroot00000000000000#!/usr/bin/env seed Canvas = imports.canvas; function drawSpirograph(ctx,R,r,O){ var x1 = R-O; var y1 = 0; var i = 1; ctx.beginPath(); ctx.moveTo(x1,y1); do { if (i>20000) break; var x2 = (R+r)*Math.cos(i*Math.PI/72) - (r+O)*Math.cos(((R+r)/r)*(i*Math.PI/72)) var y2 = (R+r)*Math.sin(i*Math.PI/72) - (r+O)*Math.sin(((R+r)/r)*(i*Math.PI/72)) ctx.lineTo(x2,y2); x1 = x2; y1 = y2; i++; } while (x2 != R-O && y2 != 0 ); ctx.stroke(); } function test10(ctx) { for (i=0;i<6;i++){ for (j=0;j<6;j++){ ctx.fillStyle = 'rgb(' + Math.floor(255-42.5*i) + ',' + Math.floor(255-42.5*j) + ',0)'; ctx.fillRect(j*25,i*25,25,25); } } ctx.translate(150, 0); for (i=0;i<6;i++){ for (j=0;j<6;j++){ ctx.strokeStyle = 'rgb(0,' + Math.floor(255-42.5*i) + ',' + Math.floor(255-42.5*j) + ')'; ctx.beginPath(); ctx.arc(12.5+j*25,12.5+i*25,10,0,Math.PI*2,true); ctx.stroke(); } } } function test11(ctx) { // draw background ctx.fillStyle = '#FD0'; ctx.fillRect(0,0,75,75); ctx.fillStyle = '#6C0'; ctx.fillRect(75,0,75,75); ctx.fillStyle = '#09F'; ctx.fillRect(0,75,75,75); ctx.fillStyle = '#F30'; ctx.fillRect(75,75,75,75); ctx.fillStyle = '#FFF'; // set transparency value ctx.globalAlpha = 0.2; // Draw semi transparent circles for (i=0;i<7;i++){ ctx.beginPath(); ctx.arc(75,75,10+10*i,0,Math.PI*2,true); ctx.fill(); } } function test12(ctx) { ctx.fillStyle = 'rgb(255,221,0)'; ctx.fillRect(0,0,150,37.5); ctx.fillStyle = 'rgb(102,204,0)'; ctx.fillRect(0,37.5,150,37.5); ctx.fillStyle = 'rgb(0,153,255)'; ctx.fillRect(0,75,150,37.5); ctx.fillStyle = 'rgb(255,51,0)'; ctx.fillRect(0,112.5,150,37.5); // Draw semi transparent rectangles for (i=0;i<10;i++){ ctx.fillStyle = 'rgba(255,255,255,'+(i+1)/10+')'; for (j=0;j<4;j++){ ctx.fillRect(5+i*14,5+j*37.5,14,27.5) } } } function test13(ctx) { for (i = 0; i < 10; i++){ ctx.lineWidth = 1+i; ctx.beginPath(); ctx.moveTo(5+i*14,5); ctx.lineTo(5+i*14,140); ctx.stroke(); } } function test14(ctx) { var lineCap = ['butt','round','square']; ctx.strokeStyle = '#09f'; ctx.beginPath(); ctx.moveTo(10,10); ctx.lineTo(140,10); ctx.moveTo(10,140); ctx.lineTo(140,140); ctx.stroke(); // Draw lines ctx.strokeStyle = "rgb(0,0,0)"; for (i=0;i1){ ctx.fill(); } else { ctx.stroke(); } } } } function test7(ctx) { ctx.beginPath(); ctx.moveTo(75,25); ctx.quadraticCurveTo(25,25,25,62.5); ctx.quadraticCurveTo(25,100,50,100); ctx.quadraticCurveTo(50,120,30,125); ctx.quadraticCurveTo(60,120,65,100); ctx.quadraticCurveTo(125,100,125,62.5); ctx.quadraticCurveTo(125,25,75,25); ctx.stroke(); } function test8(ctx) { ctx.beginPath(); ctx.moveTo(75,40); ctx.bezierCurveTo(75,37,70,25,50,25); ctx.bezierCurveTo(20,25,20,62.5,20,62.5); ctx.bezierCurveTo(20,80,40,102,75,120); ctx.bezierCurveTo(110,102,130,80,130,62.5); ctx.bezierCurveTo(130,62.5,130,25,100,25); ctx.bezierCurveTo(85,25,75,37,75,40); ctx.fill(); } function roundedRect(ctx,x,y,width,height,radius){ ctx.beginPath(); ctx.moveTo(x,y+radius); ctx.lineTo(x,y+height-radius); ctx.quadraticCurveTo(x,y+height,x+radius,y+height); ctx.lineTo(x+width-radius,y+height); ctx.quadraticCurveTo(x+width,y+height,x+width,y+height-radius); ctx.lineTo(x+width,y+radius); ctx.quadraticCurveTo(x+width,y,x+width-radius,y); ctx.lineTo(x+radius,y); ctx.quadraticCurveTo(x,y,x,y+radius); ctx.stroke(); } function test9(ctx) { roundedRect(ctx,12,12,150,150,15); roundedRect(ctx,19,19,150,150,9); roundedRect(ctx,53,53,49,33,10); roundedRect(ctx,53,119,49,16,6); roundedRect(ctx,135,53,49,33,10); roundedRect(ctx,135,119,25,49,10); ctx.beginPath(); ctx.arc(37,37,13,Math.PI/7,-Math.PI/7,true); ctx.lineTo(31,37); ctx.fill(); for(i=0;i<8;i++){ ctx.fillRect(51+i*16,35,4,4); } for(i=0;i<6;i++){ ctx.fillRect(115,51+i*16,4,4); } for(i=0;i<8;i++){ ctx.fillRect(51+i*16,99,4,4); } ctx.beginPath(); ctx.moveTo(83,116); ctx.lineTo(83,102); ctx.bezierCurveTo(83,94,89,88,97,88); ctx.bezierCurveTo(105,88,111,94,111,102); ctx.lineTo(111,116); ctx.lineTo(106.333,111.333); ctx.lineTo(101.666,116); ctx.lineTo(97,111.333); ctx.lineTo(92.333,116); ctx.lineTo(87.666,111.333); ctx.lineTo(83,116); ctx.fill(); ctx.fillStyle = "rgb(255,255,255)"; ctx.beginPath(); ctx.moveTo(91,96); ctx.bezierCurveTo(88,96,87,99,87,101); ctx.bezierCurveTo(87,103,88,106,91,106); ctx.bezierCurveTo(94,106,95,103,95,101); ctx.bezierCurveTo(95,99,94,96,91,96); ctx.moveTo(103,96); ctx.bezierCurveTo(100,96,99,99,99,101); ctx.bezierCurveTo(99,103,100,106,103,106); ctx.bezierCurveTo(106,106,107,103,107,101); ctx.bezierCurveTo(107,99,106,96,103,96); ctx.fill(); ctx.fillStyle = "rgb(0,0,0)"; ctx.beginPath(); ctx.arc(101,102,2,0,Math.PI*2,true); ctx.fill(); ctx.beginPath(); ctx.arc(89,102,2,0,Math.PI*2,true); ctx.fill(); } var compositeTypes = [ 'source-over','source-in','source-out','source-atop', 'destination-over','destination-in','destination-out','destination-atop', 'lighter','darker','copy','xor' ]; function test17(ctx){ for (var i=0;i<3;i++){ for (var j = 0;j<4;j++){ // draw rectangle ctx.save(); ctx.fillStyle = "#09f"; ctx.fillRect(70*i,70*j,40,40); // set composite property ctx.globalCompositeOperation = compositeTypes[i*4+j]; // draw circle ctx.fillStyle = "#f30"; ctx.beginPath(); ctx.arc(70*i,70*j,17,0,Math.PI*2,true); ctx.fill(); ctx.restore(); } } } tests = [test1, test2, test3, test4, test5, test6, test7, test8, test9, test10, test11, test12, test13, test14, test15, test16, test17]; ctx = new Canvas.PDFCanvas("tests.pdf", 500, 500); for (test in tests) { ctx.save(); tests[test](ctx); ctx.restore(); ctx.showPage(); } ctx.finish(); seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/canvas/seed-canvas.c000066400000000000000000001012551303774616400241120ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #include "../../libseed/seed.h" #include #include #include #include #include #include SeedObject namespace_ref; SeedClass canvas_class; SeedEngine* eng; typedef struct _SeedCanvasColor { gdouble r; gdouble g; gdouble b; gdouble a; } SeedCanvasColor; typedef struct _SeedCanvasStyle { SeedCanvasColor fill; SeedCanvasColor stroke; gdouble global_opacity; cairo_operator_t operator; } SeedCanvasStyle; typedef struct _SeedCanvasPrivates { cairo_t* cr; GSList* styles; } SeedCanvasPrivates; #define GET_CR \ SeedCanvasPrivates* priv = seed_object_get_private(this_object); \ cairo_t* cr = priv->cr SeedObject canvas_construct_canvas_from_cairo(SeedContext ctx, cairo_t* cr, SeedException* exception) { SeedObject obj; SeedCanvasPrivates* priv = g_slice_alloc(sizeof(SeedCanvasPrivates)); cairo_set_source_rgb(cr, 0, 0, 0); cairo_set_miter_limit(cr, 10); priv->cr = cr; priv->styles = NULL; obj = seed_make_object(ctx, canvas_class, priv); seed_object_set_property(ctx, obj, "globalAlpha", seed_value_from_double(ctx, 1.0, exception)); seed_object_set_property(ctx, obj, "lineWidth", seed_value_from_double(ctx, 1.0, exception)); seed_object_set_property(ctx, obj, "miterLimit", seed_value_from_double(ctx, 10, exception)); seed_object_set_property(ctx, obj, "lineCap", seed_value_from_string(ctx, "butt", exception)); seed_object_set_property(ctx, obj, "lineJoin", seed_value_from_string(ctx, "miter", exception)); seed_object_set_property(ctx, obj, "cairo", (SeedValue) seed_make_pointer(ctx, cr)); return obj; } SeedObject seed_construct_image_canvas(SeedContext ctx, SeedObject constructor, size_t argument_count, const SeedValue arguments[], SeedException* exception) { SeedObject obj; cairo_surface_t* surface; cairo_t* cr; gchar* filename; gdouble width, height; if (argument_count != 3) { seed_make_exception(ctx, exception, "ArgumentError", "Canvas.PDFCanvas constructor expected" "3 arguments"); return (SeedObject) seed_make_null(ctx); } filename = seed_value_to_string(ctx, arguments[0], exception); width = seed_value_to_double(ctx, arguments[1], exception); height = seed_value_to_double(ctx, arguments[2], exception); surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); cr = cairo_create(surface); cairo_surface_destroy(surface); obj = canvas_construct_canvas_from_cairo(ctx, cr, exception); return obj; } SeedObject canvas_construct_pdf_canvas(SeedContext ctx, SeedObject constructor, size_t argument_count, const SeedValue arguments[], SeedException* exception) { SeedObject obj; cairo_surface_t* surface; cairo_t* cr; gchar* filename; gdouble width, height; if (argument_count != 3) { seed_make_exception(ctx, exception, "ArgumentError", "Canvas.PDFCanvas constructor expected" "3 arguments"); return (SeedObject) seed_make_null(ctx); } filename = seed_value_to_string(ctx, arguments[0], exception); width = seed_value_to_double(ctx, arguments[1], exception); height = seed_value_to_double(ctx, arguments[2], exception); surface = cairo_pdf_surface_create(filename, width, height); cr = cairo_create(surface); cairo_surface_destroy(surface); obj = canvas_construct_canvas_from_cairo(ctx, cr, exception); return obj; } SeedObject canvas_construct_svg_canvas(SeedContext ctx, SeedObject constructor, size_t argument_count, const SeedValue arguments[], SeedException* exception) { SeedObject obj; cairo_surface_t* surface; cairo_t* cr; gchar* filename; gdouble width, height; if (argument_count != 3) { seed_make_exception(ctx, exception, "ArgumentError", "Canvas.PDFCanvas constructor expected" "3 arguments"); return (SeedObject) seed_make_null(ctx); } filename = seed_value_to_string(ctx, arguments[0], exception); width = seed_value_to_double(ctx, arguments[1], exception); height = seed_value_to_double(ctx, arguments[2], exception); surface = cairo_svg_surface_create(filename, width, height); cr = cairo_create(surface); cairo_surface_destroy(surface); obj = canvas_construct_canvas_from_cairo(ctx, cr, exception); return obj; } SeedObject canvas_construct_canvas(SeedContext ctx, SeedObject constructor, size_t argument_count, const SeedValue arguments[], SeedException* exception) { SeedObject obj; cairo_t* cr; if (argument_count != 1) { seed_make_exception(ctx, exception, "ArgumentError", "Canvas.CairoCanvas constructor" "expected 1 argument"); return (SeedObject) seed_make_null(ctx); } cr = seed_pointer_get_pointer(ctx, arguments[0]); obj = canvas_construct_canvas_from_cairo(ctx, cr, exception); return obj; } void seed_canvas_parse_color(SeedCanvasColor* color, gchar* spec) { if (*spec == '#') { guint r = 0, g = 0, b = 0, a = 0, found; if (strlen(spec) > 4) found = sscanf(spec, "#%2x%2x%2x%2x", &r, &g, &b, &a); else { found = sscanf(spec, "#%1x%1x%1x%1x", &r, &g, &b, &a); r *= 17; g *= 17; b *= 17; a *= 17; } if (found < 4) a = 0xff; color->r = r / 255.0; color->g = g / 255.0; color->b = b / 255.0; color->a = a / 255.0; return; } else if (*spec == 'r') { switch (*(spec + 3)) { case 'a': { gdouble r, g, b; gfloat a; sscanf(spec, "rgba(%lf,%lf,%lf,%f)", &r, &g, &b, &a); color->r = r / 255.0; color->g = g / 255.0; color->b = b / 255.0; color->a = a; return; } case '(': { gdouble r, g, b; sscanf(spec, "rgb(%lf,%lf,%lf)", &r, &g, &b); color->r = r / 255.0; color->g = g / 255.0; color->b = b / 255.0; color->a = 1.0; return; } } } else if (*spec == '[') { color->r = color->b = color->g = 0; color->a = 1; } } gboolean seed_canvas_update_stroke_style(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedValue value, SeedException* e) { SeedCanvasStyle* style; SeedCanvasPrivates* priv = seed_object_get_private(this_object); gchar* stroke_style = seed_value_to_string(ctx, value, e); if (!priv->styles) { priv->styles = g_slist_prepend(priv->styles, g_new0(SeedCanvasStyle, 1)); ((SeedCanvasStyle*) priv->styles->data)->global_opacity = 1; ((SeedCanvasStyle*) priv->styles->data)->fill.a = 1; ((SeedCanvasStyle*) priv->styles->data)->operator= CAIRO_OPERATOR_OVER; } style = (SeedCanvasStyle*) priv->styles->data; seed_canvas_parse_color(&style->stroke, stroke_style); g_free(stroke_style); return TRUE; } gboolean seed_canvas_update_fill_style(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedValue value, SeedException* e) { SeedCanvasStyle* style; SeedCanvasPrivates* priv = seed_object_get_private(this_object); gchar* fill_style = seed_value_to_string(ctx, value, e); if (!priv->styles) { priv->styles = g_slist_prepend(priv->styles, g_new0(SeedCanvasStyle, 1)); ((SeedCanvasStyle*) priv->styles->data)->global_opacity = 1; ((SeedCanvasStyle*) priv->styles->data)->stroke.a = 1; ((SeedCanvasStyle*) priv->styles->data)->operator= CAIRO_OPERATOR_OVER; } style = (SeedCanvasStyle*) priv->styles->data; seed_canvas_parse_color(&style->fill, fill_style); g_free(fill_style); return TRUE; } gboolean seed_canvas_update_global_alpha(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedValue value, SeedException* e) { SeedCanvasStyle* style; SeedCanvasPrivates* priv = seed_object_get_private(this_object); gdouble global_alpha = seed_value_to_double(ctx, value, e); if (!priv->styles) { priv->styles = g_slist_prepend(priv->styles, g_new0(SeedCanvasStyle, 1)); ((SeedCanvasStyle*) priv->styles->data)->global_opacity = 1; ((SeedCanvasStyle*) priv->styles->data)->stroke.a = 1; ((SeedCanvasStyle*) priv->styles->data)->fill.a = 1; ((SeedCanvasStyle*) priv->styles->data)->operator= CAIRO_OPERATOR_OVER; } style = (SeedCanvasStyle*) priv->styles->data; style->global_opacity = global_alpha; return TRUE; } gboolean seed_canvas_update_global_composite(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedValue value, SeedException* e) { SeedCanvasStyle* style; GET_CR; gchar* composite_op = seed_value_to_string(ctx, value, e); if (!priv->styles) { priv->styles = g_slist_prepend(priv->styles, g_new0(SeedCanvasStyle, 1)); ((SeedCanvasStyle*) priv->styles->data)->global_opacity = 1; ((SeedCanvasStyle*) priv->styles->data)->stroke.a = 1; ((SeedCanvasStyle*) priv->styles->data)->fill.a = 1; ((SeedCanvasStyle*) priv->styles->data)->operator= CAIRO_OPERATOR_OVER; } style = (SeedCanvasStyle*) priv->styles->data; if (!strcmp(composite_op, "copy")) style->operator= CAIRO_OPERATOR_SOURCE; else if (!strcmp(composite_op, "source-over")) style->operator= CAIRO_OPERATOR_OVER; else if (!strcmp(composite_op, "source-in")) style->operator= CAIRO_OPERATOR_IN; else if (!strcmp(composite_op, "source-out")) style->operator= CAIRO_OPERATOR_OUT; else if (!strcmp(composite_op, "source-atop")) style->operator= CAIRO_OPERATOR_ATOP; else if (!strcmp(composite_op, "destination-over")) style->operator= CAIRO_OPERATOR_DEST_OVER; else if (!strcmp(composite_op, "destination-in")) style->operator= CAIRO_OPERATOR_DEST_IN; else if (!strcmp(composite_op, "destination-out")) style->operator= CAIRO_OPERATOR_DEST_OVER; else if (!strcmp(composite_op, "destination-atop")) style->operator= CAIRO_OPERATOR_DEST_ATOP; else if (!strcmp(composite_op, "xor")) style->operator= CAIRO_OPERATOR_XOR; else if (!strcmp(composite_op, "darker")) style->operator= CAIRO_OPERATOR_SATURATE; else if (!strcmp(composite_op, "lighter")) style->operator= CAIRO_OPERATOR_ADD; else style->operator= CAIRO_OPERATOR_OVER; cairo_set_operator(cr, style->operator); g_free(composite_op); return TRUE; } gboolean seed_canvas_set_linewidth(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedValue value, SeedException* e) { GET_CR; gdouble line_width = seed_value_to_double(ctx, value, e); cairo_set_line_width(cr, line_width); return TRUE; } gboolean seed_canvas_set_miterlimit(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedValue value, SeedException* e) { GET_CR; cairo_set_miter_limit(cr, seed_value_to_double(ctx, value, e)); return TRUE; } gboolean seed_canvas_set_linecap(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedValue value, SeedException* e) { GET_CR; cairo_line_cap_t cap = CAIRO_LINE_CAP_BUTT; gchar* line_cap = seed_value_to_string(ctx, value, e); if (!strcmp(line_cap, "round")) cap = CAIRO_LINE_CAP_ROUND; else if (!strcmp(line_cap, "square")) cap = CAIRO_LINE_CAP_SQUARE; g_free(line_cap); cairo_set_line_cap(cr, cap); return TRUE; } gboolean seed_canvas_set_linejoin(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedValue value, SeedException* e) { GET_CR; cairo_line_join_t join = CAIRO_LINE_JOIN_MITER; gchar* line_join = seed_value_to_string(ctx, value, e); if (!strcmp(line_join, "round")) join = CAIRO_LINE_JOIN_ROUND; else if (!strcmp(line_join, "bevel")) join = CAIRO_LINE_JOIN_BEVEL; g_free(line_join); cairo_set_line_join(cr, join); return TRUE; } void seed_canvas_apply_stroke_style(SeedCanvasStyle* style, cairo_t* cr) { cairo_set_source_rgba(cr, style->stroke.r, style->stroke.g, style->stroke.b, style->stroke.a * style->global_opacity); cairo_set_operator(cr, style->operator); } void seed_canvas_apply_fill_style(SeedCanvasStyle* style, cairo_t* cr) { cairo_set_source_rgba(cr, style->fill.r, style->fill.g, style->fill.b, style->fill.a * style->global_opacity); cairo_set_operator(cr, style->operator); } SeedValue seed_canvas_save(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { GET_CR; SeedCanvasStyle* old_style = (SeedCanvasStyle*) priv->styles->data; cairo_save(cr); priv->styles = g_slist_prepend(priv->styles, g_new(SeedCanvasStyle, 1)); memcpy(priv->styles->data, old_style, sizeof(SeedCanvasStyle)); return seed_make_null(ctx); } SeedValue seed_canvas_restore(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { GET_CR; SeedCanvasStyle* style; style = (SeedCanvasStyle*) priv->styles->data; priv->styles = g_slist_delete_link(priv->styles, priv->styles); g_free(style); cairo_restore(cr); return seed_make_null(ctx); } SeedValue seed_canvas_scale(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { GET_CR; gdouble x = seed_value_to_double(ctx, arguments[0], exception); gdouble y = seed_value_to_double(ctx, arguments[1], exception); cairo_scale(cr, x, y); return seed_make_null(ctx); } SeedValue seed_canvas_translate(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { GET_CR; gdouble x = seed_value_to_double(ctx, arguments[0], exception); gdouble y = seed_value_to_double(ctx, arguments[1], exception); cairo_translate(cr, x, y); return seed_make_null(ctx); } SeedValue seed_canvas_rotate(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { GET_CR; gdouble x = seed_value_to_double(ctx, arguments[0], exception); cairo_rotate(cr, x); return seed_make_null(ctx); } SeedValue seed_canvas_transform(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { GET_CR; cairo_matrix_t matrix; gdouble xx, yx, xy, yy, x0, y0; xx = seed_value_to_double(ctx, arguments[0], exception); yx = seed_value_to_double(ctx, arguments[1], exception); xy = seed_value_to_double(ctx, arguments[2], exception); yy = seed_value_to_double(ctx, arguments[3], exception); x0 = seed_value_to_double(ctx, arguments[4], exception); y0 = seed_value_to_double(ctx, arguments[5], exception); cairo_matrix_init(&matrix, xx, yx, xy, yy, x0, y0); cairo_transform(cr, &matrix); return seed_make_null(ctx); } SeedValue seed_canvas_set_transform(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { GET_CR; cairo_matrix_t matrix; gdouble xx, yx, xy, yy, x0, y0; cairo_identity_matrix(cr); xx = seed_value_to_double(ctx, arguments[0], exception); yx = seed_value_to_double(ctx, arguments[1], exception); xy = seed_value_to_double(ctx, arguments[2], exception); yy = seed_value_to_double(ctx, arguments[3], exception); x0 = seed_value_to_double(ctx, arguments[4], exception); y0 = seed_value_to_double(ctx, arguments[5], exception); cairo_matrix_init(&matrix, xx, yx, xy, yy, x0, y0); cairo_transform(cr, &matrix); return seed_make_null(ctx); } SeedValue seed_canvas_clear_rect(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { GET_CR; gdouble x, y, width, height; x = seed_value_to_double(ctx, arguments[0], exception); y = seed_value_to_double(ctx, arguments[1], exception); width = seed_value_to_double(ctx, arguments[2], exception); height = seed_value_to_double(ctx, arguments[3], exception); cairo_save(cr); cairo_set_source_rgb(cr, 1, 1, 1); cairo_rectangle(cr, x, y, width, height); cairo_fill(cr); cairo_restore(cr); return seed_make_null(ctx); } SeedValue seed_canvas_stroke_rect(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { GET_CR; gdouble x, y, width, height; seed_canvas_apply_stroke_style((SeedCanvasStyle*) priv->styles->data, cr); x = seed_value_to_double(ctx, arguments[0], exception); y = seed_value_to_double(ctx, arguments[1], exception); width = seed_value_to_double(ctx, arguments[2], exception); height = seed_value_to_double(ctx, arguments[3], exception); cairo_rectangle(cr, x, y, width, height); cairo_stroke(cr); return seed_make_null(ctx); } SeedValue seed_canvas_fill_rect(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { GET_CR; gdouble x, y, width, height; seed_canvas_apply_fill_style((SeedCanvasStyle*) priv->styles->data, cr); x = seed_value_to_double(ctx, arguments[0], exception); y = seed_value_to_double(ctx, arguments[1], exception); width = seed_value_to_double(ctx, arguments[2], exception); height = seed_value_to_double(ctx, arguments[3], exception); cairo_rectangle(cr, x, y, width, height); cairo_fill(cr); return seed_make_null(ctx); } SeedValue seed_canvas_end_path(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { GET_CR; cairo_close_path(cr); return seed_make_null(ctx); } SeedValue seed_canvas_begin_path(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { GET_CR; cairo_new_path(cr); return seed_make_null(ctx); } SeedValue seed_canvas_move_to(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { GET_CR; gdouble x, y; x = seed_value_to_double(ctx, arguments[0], exception); y = seed_value_to_double(ctx, arguments[1], exception); cairo_move_to(cr, x, y); return seed_make_null(ctx); } SeedValue seed_canvas_line_to(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { GET_CR; gdouble x, y; x = seed_value_to_double(ctx, arguments[0], exception); y = seed_value_to_double(ctx, arguments[1], exception); cairo_line_to(cr, x, y); return seed_make_null(ctx); } SeedValue seed_canvas_stroke(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { GET_CR; seed_canvas_apply_stroke_style((SeedCanvasStyle*) priv->styles->data, cr); cairo_stroke(cr); return seed_make_null(ctx); } SeedValue seed_canvas_clip(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { GET_CR; cairo_clip(cr); return seed_make_null(ctx); } SeedValue seed_canvas_fill(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { GET_CR; seed_canvas_apply_fill_style((SeedCanvasStyle*) priv->styles->data, cr); cairo_fill(cr); return seed_make_null(ctx); } SeedValue seed_canvas_arc(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { GET_CR; gdouble xc, yc, radius, start, end; gboolean counter_clockwise; xc = seed_value_to_double(ctx, arguments[0], exception); yc = seed_value_to_double(ctx, arguments[1], exception); radius = seed_value_to_double(ctx, arguments[2], exception); start = seed_value_to_double(ctx, arguments[3], exception); end = seed_value_to_double(ctx, arguments[4], exception); counter_clockwise = seed_value_to_boolean(ctx, arguments[5], exception); if (counter_clockwise) cairo_arc_negative(cr, xc, yc, radius, end, start); else cairo_arc(cr, xc, yc, radius, start, end); return seed_make_null(ctx); } SeedValue seed_canvas_quadratic(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { GET_CR; gdouble p0x, p0y, cp1x, cp1y, cp2x, cp2y, cp3x, cp3y; gdouble qp1x, qp1y, qp2x, qp2y; cairo_get_current_point(cr, &p0x, &p0y); qp1x = seed_value_to_double(ctx, arguments[0], exception); qp1y = seed_value_to_double(ctx, arguments[1], exception); qp2x = seed_value_to_double(ctx, arguments[2], exception); qp2y = seed_value_to_double(ctx, arguments[3], exception); // Convert quadratic curve to cubic curve... // I think the math is explained in some // freetype documentation somewhere. cp3x = qp2x; cp3y = qp2y; cp1x = p0x + 2 / 3.0 * (qp1x - p0x); cp1y = p0y + 2 / 3.0 * (qp1y - p0y); cp2x = cp1x + 1 / 3.0 * (qp2x - p0x); cp2y = cp1y + 1 / 3.0 * (qp2y - p0y); cairo_curve_to(cr, cp1x, cp1y, cp2x, cp2y, cp3x, cp3y); return seed_make_null(ctx); } SeedValue seed_canvas_bezier(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { GET_CR; gdouble cp0x, cp0y, cp1x, cp1y, cp2x, cp2y; cp0x = seed_value_to_double(ctx, arguments[0], exception); cp0y = seed_value_to_double(ctx, arguments[1], exception); cp1x = seed_value_to_double(ctx, arguments[2], exception); cp1y = seed_value_to_double(ctx, arguments[3], exception); cp2x = seed_value_to_double(ctx, arguments[4], exception); cp2y = seed_value_to_double(ctx, arguments[5], exception); cairo_curve_to(cr, cp0x, cp0y, cp1x, cp1y, cp2x, cp2y); return seed_make_null(ctx); } SeedValue seed_canvas_rect(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { GET_CR; gdouble x, y, width, height; x = seed_value_to_double(ctx, arguments[0], exception); y = seed_value_to_double(ctx, arguments[1], exception); width = seed_value_to_double(ctx, arguments[2], exception); height = seed_value_to_double(ctx, arguments[3], exception); cairo_rectangle(cr, x, y, width, height); return seed_make_null(ctx); } SeedValue seed_canvas_flush(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { GET_CR; cairo_surface_t* surface = cairo_get_target(cr); cairo_surface_flush(surface); return seed_make_null(ctx); } SeedValue seed_canvas_finish(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { GET_CR; cairo_surface_t* surface = cairo_get_target(cr); cairo_surface_finish(surface); return seed_make_null(ctx); } SeedValue seed_canvas_showpage(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { GET_CR; cairo_show_page(cr); return seed_make_null(ctx); } SeedValue seed_canvas_destroy(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { GET_CR; cairo_destroy(cr); return seed_make_null(ctx); } static void canvas_finalize(SeedObject object) { cairo_t* cr = seed_object_get_private(object); if (cr) cairo_destroy(cr); } seed_static_function canvas_funcs[] = { { "save", seed_canvas_save, 0 }, { "restore", seed_canvas_restore, 0 }, { "scale", seed_canvas_scale, 0 }, { "rotate", seed_canvas_rotate, 0 }, { "translate", seed_canvas_translate, 0 }, { "transform", seed_canvas_transform, 0 }, { "setTransform", seed_canvas_set_transform, 0 }, { "clearRect", seed_canvas_clear_rect, 0 }, { "fillRect", seed_canvas_fill_rect, 0 }, { "strokeRect", seed_canvas_stroke_rect, 0 }, { "beginPath", seed_canvas_begin_path, 0 }, { "closePath", seed_canvas_end_path, 0 }, { "moveTo", seed_canvas_move_to, 0 }, { "lineTo", seed_canvas_line_to, 0 }, { "fill", seed_canvas_fill, 0 }, { "stroke", seed_canvas_stroke, 0 }, { "clip", seed_canvas_clip, 0 }, { "arc", seed_canvas_arc, 0 }, { "quadraticCurveTo", seed_canvas_quadratic, 0 }, { "bezierCurveTo", seed_canvas_bezier, 0 }, { "rect", seed_canvas_rect, 0 }, { "flush", seed_canvas_flush, 0 }, { "finish", seed_canvas_finish, 0 }, { "showPage", seed_canvas_showpage, 0 }, { "destroy", seed_canvas_destroy, 0 }, { NULL, NULL, 0 } }; seed_static_value canvas_properties[] = { { "lineWidth", 0, seed_canvas_set_linewidth, 0 }, { "lineCap", 0, seed_canvas_set_linecap, 0 }, { "lineJoin", 0, seed_canvas_set_linejoin, 0 }, { "miterLimit", 0, seed_canvas_set_miterlimit, 0 }, { "strokeStyle", 0, seed_canvas_update_stroke_style, 0 }, { "fillStyle", 0, seed_canvas_update_fill_style, 0 }, { "globalAlpha", 0, seed_canvas_update_global_alpha, 0 }, { "globalCompositeOperation", 0, seed_canvas_update_global_composite, 0 }, { NULL, NULL, NULL, 0 } }; SeedObject seed_module_init(SeedEngine* local_eng) { SeedObject canvas_constructor, pdf_constructor, svg_constructor, image_constructor; seed_class_definition canvas_class_def = seed_empty_class; eng = local_eng; namespace_ref = seed_make_object(eng->context, 0, 0); canvas_class_def.class_name = "CairoCanvas"; canvas_class_def.static_functions = canvas_funcs; canvas_class_def.finalize = canvas_finalize; canvas_class_def.static_values = canvas_properties; canvas_class = seed_create_class(&canvas_class_def); canvas_constructor = seed_make_constructor(eng->context, canvas_class, canvas_construct_canvas); pdf_constructor = seed_make_constructor(eng->context, canvas_class, canvas_construct_pdf_canvas); svg_constructor = seed_make_constructor(eng->context, canvas_class, canvas_construct_svg_canvas); image_constructor = seed_make_constructor(eng->context, canvas_class, seed_construct_image_canvas); seed_object_set_property(eng->context, namespace_ref, "CairoCanvas", canvas_constructor); seed_object_set_property(eng->context, namespace_ref, "PDFCanvas", pdf_constructor); seed_object_set_property(eng->context, namespace_ref, "SVGCanvas", svg_constructor); seed_object_set_property(eng->context, namespace_ref, "ImageCanvas", svg_constructor); return namespace_ref; } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/dbus/000077500000000000000000000000001303774616400212335ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/dbus/Makefile.am000066400000000000000000000017111303774616400232670ustar00rootroot00000000000000if BUILD_DBUS_MODULE SUBDIRS = util EXTRA_DIST = dbus2js.py \ dbus.js \ dbus-values.h \ lang.js \ dbus-exports.h moduledir = $(datadir)/seed@SEED_GTK_VERSION@ module_DATA = dbus.js lang.js seedlibdir = ${libdir}/seed@SEED_GTK_VERSION@ seedlib_LTLIBRARIES = \ libseed_dbusnative.la libseed_dbusnative_la_SOURCES = \ module.c \ util/dbus.c \ util/dbus-proxy.c \ util/dbus-signals.c \ dbus-values.c \ dbus-exports.c libseed_dbusnative_la_CFLAGS = \ -Wall \ -I@top_srcdir@/libseed/ \ $(GOBJECT_INTROSPECTION_CFLAGS) \ $(DBUS_CFLAGS) \ $(DBUSGLIB_CFLAGS) \ $(SEED_DEBUG_CFLAGS) \ $(SEED_PROFILE_CFLAGS) libseed_dbusnative_la_LDFLAGS = \ -module -avoid-version \ $(GOBJECT_INTROSPECTION_LDFLAGS) \ $(DBUS_LDFLAGS) \ $(DBUSGLIB_LDFLAGS) \ -L/lib libseed_dbusnative_la_LIBADD = \ -ldbus-1 \ -ldbus-glib-1 \ $(top_builddir)/libseed/libseed@SEED_GTK_VERSION@.la \ $(SEED_PROFILE_LIBS) endif -include $(top_srcdir)/git.mk seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/dbus/dbus-exports.c000066400000000000000000000505461303774616400240500ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #include "dbus-exports.h" #include "dbus-values.h" #include #include #include typedef struct _Exports { // Why does GJS have this? SeedObject object; DBusBusType which_bus; DBusConnection* connection_weak_ref; gboolean filter_was_registered; } Exports; SeedClass seed_js_exports_class = NULL; static void on_bus_opened(DBusConnection* connection, void* data); static void on_bus_closed(DBusConnection* connection, void* data); static DBusHandlerResult on_message(DBusConnection* connection, DBusMessage* message, void* user_data); static const BigDBusConnectFuncs system_connect_funcs = { DBUS_BUS_SYSTEM, on_bus_opened, on_bus_closed }; static const BigDBusConnectFuncs session_connect_funcs = { DBUS_BUS_SESSION, on_bus_opened, on_bus_closed }; static void on_bus_opened(DBusConnection* connection, void* data) { Exports* priv = data; g_assert(priv->connection_weak_ref == NULL); priv->connection_weak_ref = connection; if (priv->filter_was_registered) return; if (!dbus_connection_add_filter(connection, on_message, priv, NULL)) { g_warning("DBus: Failed to add message filter"); return; } priv->filter_was_registered = TRUE; } static void on_bus_closed(DBusConnection* connection, void* data) { Exports* priv = data; g_assert(priv->connection_weak_ref != NULL); priv->connection_weak_ref = NULL; if (priv->filter_was_registered) { dbus_connection_remove_filter(connection, on_message, priv); priv->filter_was_registered = FALSE; } } #define dbus_reply_from_exception(ctx, message, reply_p, exception) \ (dbus_reply_from_exception_and_sender((ctx), \ dbus_message_get_sender(message), \ dbus_message_get_serial(message), \ (reply_p), exception)) static gboolean dbus_reply_from_exception_and_sender(SeedContext ctx, const gchar* sender, dbus_uint32_t serial, DBusMessage** reply_p, SeedException* exception) { SeedValue name_val; gchar* s; const gchar* name = NULL; *reply_p = NULL; if (seed_value_is_undefined(ctx, *exception) || seed_value_is_null(ctx, *exception) || !seed_value_is_object(ctx, *exception)) return FALSE; name_val = seed_object_get_property(ctx, *exception, "dbusErrorName"); name = seed_value_to_string(ctx, name_val, NULL); s = seed_exception_to_string(ctx, *exception); g_warning("JS exception we will send as dbus reply to %s: %s", sender, s); *reply_p = dbus_message_new(DBUS_MESSAGE_TYPE_ERROR); dbus_message_set_destination(*reply_p, sender); dbus_message_set_reply_serial(*reply_p, serial); dbus_message_set_no_reply(*reply_p, TRUE); dbus_message_set_error_name(*reply_p, name ? name : DBUS_ERROR_FAILED); if (s != NULL) { DBusMessageIter iter; dbus_message_iter_init_append(*reply_p, &iter); if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &s)) { dbus_message_unref(*reply_p); g_free(s); return FALSE; } g_free(s); } return TRUE; } // Is this going to leak later? static gboolean signature_from_method(SeedContext ctx, SeedObject method_obj, const char** signature, SeedException* exception) { SeedValue signature_value; if ((signature_value = seed_object_get_property(ctx, method_obj, "outSignature"))) { *signature = seed_value_to_string(ctx, signature_value, exception); if (*signature == NULL) { return FALSE; } } else { /* We default to a{sv} */ *signature = "a{sv}"; } return TRUE; } static gboolean signature_has_one_element(const char* signature) { DBusSignatureIter iter; if (!signature) return FALSE; dbus_signature_iter_init(&iter, signature); return !dbus_signature_iter_next(&iter); } static DBusMessage* build_reply_from_jsval(SeedContext ctx, const char* signature, const char* sender, dbus_uint32_t serial, SeedValue rval, SeedException* exception) { DBusMessage* reply; DBusMessageIter arg_iter; DBusSignatureIter sig_iter; gboolean marshalled = FALSE; reply = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN); dbus_message_set_destination(reply, sender); dbus_message_set_reply_serial(reply, serial); dbus_message_set_no_reply(reply, TRUE); dbus_message_iter_init_append(reply, &arg_iter); if (seed_value_is_undefined(ctx, rval) || g_str_equal(signature, "")) { /* We don't want to send anything in these cases so skip the * marshalling altogether. */ return reply; } dbus_signature_iter_init(&sig_iter, signature); if (signature_has_one_element(signature)) { marshalled = seed_js_one_value_to_dbus(ctx, rval, &arg_iter, &sig_iter, exception); } else { if (!seed_value_is_object(ctx, rval)) { g_warning( "Signature has multiple items but return value is not an array"); return reply; } marshalled = seed_js_values_to_dbus(ctx, 0, rval, &arg_iter, &sig_iter, exception); } if (!marshalled) { /* replace our planned reply with an error */ dbus_message_unref(reply); if (!dbus_reply_from_exception_and_sender(ctx, sender, serial, &reply, exception)) g_warning("conversion of dbus return value failed but no exception " "was set?"); } return reply; } static DBusMessage* invoke_js_from_dbus(SeedContext ctx, DBusMessage* method_call, SeedObject this_obj, SeedObject method_obj, SeedException* exception) { DBusMessage* reply; int argc; SeedValue* argv; SeedValue rval; DBusMessageIter arg_iter; GArray* values; const char* signature; reply = NULL; dbus_message_iter_init(method_call, &arg_iter); if (!seed_js_values_from_dbus(ctx, &arg_iter, &values, exception)) { if (!dbus_reply_from_exception(ctx, method_call, &reply, exception)) g_warning( "conversion of dbus method arg failed but no exception was set?"); return reply; } argc = values->len; argv = (SeedValue*) values->data; seed_js_add_dbus_props(ctx, method_call, argv[0], exception); rval = seed_object_call(ctx, method_obj, NULL, argc, argv, exception); if (!seed_value_is_null(ctx, *exception) && seed_value_is_object(ctx, *exception)) { g_warning("dbus method invocation failed"); if (!dbus_reply_from_exception(ctx, method_call, &reply, exception)) g_warning( "dbus method invocation failed but no exception was set?"); goto out; } if (dbus_reply_from_exception(ctx, method_call, &reply, exception)) { g_warning("Closure invocation succeeded but an exception was set?"); goto out; } if (!signature_from_method(ctx, method_obj, &signature, exception)) { if (!dbus_reply_from_exception(ctx, method_call, &reply, exception)) g_warning( "dbus method invocation failed but no exception was set?"); goto out; } reply = build_reply_from_jsval(ctx, signature, dbus_message_get_sender(method_call), dbus_message_get_serial(method_call), rval, exception); out: g_array_free(values, TRUE); if (reply) g_warning("Sending %s reply to dbus method %s", dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_METHOD_RETURN ? "normal" : "error", dbus_message_get_member(method_call)); else g_warning("Failed to create reply to dbus method %s", dbus_message_get_member(method_call)); return reply; } static SeedValue async_call_callback(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { DBusConnection* connection; DBusBusType which_bus; DBusMessage* reply; const char* sender; dbus_uint32_t serial; SeedValue prop_value, retval; const char* signature; gboolean thrown; retval = seed_make_undefined(ctx); reply = NULL; thrown = FALSE; prop_value = seed_object_get_property(ctx, function, "_dbusSender"); sender = seed_value_to_string(ctx, prop_value, exception); if (!sender) return FALSE; prop_value = seed_object_get_property(ctx, function, "_dbusSerial"); serial = seed_value_to_uint(ctx, prop_value, exception); prop_value = seed_object_get_property(ctx, function, "_dbusBusType"); which_bus = seed_value_to_int(ctx, prop_value, exception); /* From now we have enough information to * send the exception back to the callee so we'll do so */ prop_value = seed_object_get_property(ctx, function, "_dbusOutSignature"); signature = seed_value_to_string(ctx, prop_value, exception); if (!signature) return FALSE; if (argument_count != 1) { seed_make_exception( ctx, exception, "ArgumentError", "The callback to async DBus calls takes one argument, " "the return value or array of return values"); thrown = TRUE; goto out; } reply = build_reply_from_jsval(ctx, signature, sender, serial, arguments[0], exception); out: if (!reply && thrown) { if (!dbus_reply_from_exception_and_sender(ctx, sender, serial, &reply, exception)) g_warning( "dbus method invocation failed but no exception was set?"); } if (reply) { big_dbus_add_bus_weakref(which_bus, &connection); if (!connection) { seed_make_exception( ctx, exception, "DBusError", "We were disconnected from the bus before the callback " "to some async remote call was called"); dbus_message_unref(reply); big_dbus_remove_bus_weakref(which_bus, &connection); return FALSE; } dbus_connection_send(connection, reply, NULL); big_dbus_remove_bus_weakref(which_bus, &connection); dbus_message_unref(reply); } return retval; } /* returns an error message or NULL */ static DBusMessage* invoke_js_async_from_dbus(SeedContext ctx, DBusBusType bus_type, DBusMessage* method_call, SeedObject this_obj, SeedObject method_obj, SeedException* exception) { DBusMessage* reply; int argc; SeedValue* argv; DBusMessageIter arg_iter; GArray* values; SeedObject callback_object; SeedValue sender_string, signature_string; gboolean thrown; SeedValue ignored; const char* signature; reply = NULL; thrown = FALSE; argv = NULL; if (!seed_js_values_from_dbus(ctx, &arg_iter, &values, exception)) { if (!dbus_reply_from_exception(ctx, method_call, &reply, exception)) g_warning( "conversion of dbus method arg failed but no exception was set?"); return reply; } /* we will add an argument, the callback */ callback_object = seed_make_function(ctx, async_call_callback, "" /* anonymous */); g_assert(callback_object); g_array_append_val(values, callback_object); /* We attach the DBus sender and serial as properties to * callback, so we don't need to bother with memory managing them * if the callback is never called and just discarded.*/ sender_string = seed_value_from_string(ctx, dbus_message_get_sender(method_call), exception); if (!sender_string) { thrown = TRUE; goto out; } seed_object_set_property(ctx, callback_object, "_dbusSender", sender_string); seed_object_set_property(ctx, callback_object, "_dbusSerial", seed_value_from_int(ctx, dbus_message_get_serial( method_call), exception)); seed_object_set_property(ctx, callback_object, "_dbusBusType", seed_value_from_int(ctx, bus_type, exception)); if (!signature_from_method(ctx, method_obj, &signature, exception)) { thrown = TRUE; goto out; } signature_string = seed_value_from_string(ctx, signature, exception); if (!signature_string) { thrown = TRUE; goto out; } seed_object_set_property(ctx, callback_object, "_dbusOutSignature", signature_string); argc = values->len; argv = (SeedValue*) values->data; seed_object_call(ctx, method_obj, this_obj, argc, argv, &ignored); out: if (thrown) { if (!dbus_reply_from_exception(ctx, method_call, &reply, exception)) g_warning( "conversion of dbus method arg failed but no exception was set?"); } g_array_free(values, TRUE); return reply; } static SeedObject find_js_property_by_path(SeedContext ctx, SeedObject root_obj, const gchar* path) { gchar** elements; gint i; SeedObject obj; elements = g_strsplit(path, "/", -1); obj = root_obj; /* g_strsplit returns empty string for the first * '/' so we start with elements[1] */ for (i = 1; elements[i] != NULL; ++i) { obj = seed_object_get_property(ctx, obj, elements[i]); if (seed_value_is_undefined(ctx, obj) || !seed_value_is_object(ctx, obj)) { obj = NULL; break; } } g_strfreev(elements); return obj; } static gboolean find_method(SeedContext ctx, SeedObject obj, const gchar* method_name, SeedValue* method_value) { *method_value = seed_object_get_property(ctx, obj, method_name); if (seed_value_is_undefined(ctx, *method_value) || !seed_value_is_object(ctx, *method_value)) return FALSE; return TRUE; } static DBusHandlerResult on_message(DBusConnection* connection, DBusMessage* message, void* user_data) { SeedContext ctx; const char* path; DBusHandlerResult result; SeedObject obj; const char* method_name; char* async_method_name; SeedValue method_value; DBusMessage* reply; Exports* priv; priv = user_data; async_method_name = NULL; reply = NULL; ctx = seed_context_create(group, NULL); seed_prepare_global_context(ctx); if (dbus_message_get_type(message) != DBUS_MESSAGE_TYPE_METHOD_CALL) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; method_value = seed_make_undefined(ctx); result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; path = dbus_message_get_path(message); obj = find_js_property_by_path(ctx, priv->object, path); if (obj == NULL) { g_warning("There is no JS object at %s", path); goto out; } method_name = dbus_message_get_member(message); async_method_name = g_strdup_printf("%sAsync", method_name); /* try first if an async version exists */ if (find_method(ctx, obj, async_method_name, &method_value)) { g_warning("Invoking async method %s on JS obj at dbus path %s", async_method_name, path); reply = invoke_js_async_from_dbus(ctx, priv->which_bus, message, obj, method_value, NULL); // Need exception here. result = DBUS_HANDLER_RESULT_HANDLED; /* otherwise try the sync version */ } else if (find_method(ctx, obj, method_name, &method_value)) { g_warning("Invoking method %s on JS obj at dbus path %s", method_name, path); reply = invoke_js_from_dbus(ctx, message, obj, method_value, NULL); // Need exception here result = DBUS_HANDLER_RESULT_HANDLED; /* otherwise FAIL */ } else { g_warning("There is a JS object at %s but it has no method %s", path, method_name); } if (reply != NULL) { dbus_connection_send(connection, reply, NULL); dbus_message_unref(reply); } out: seed_context_unref(ctx); if (async_method_name) g_free(async_method_name); return result; } static void exports_constructor(SeedContext ctx, SeedObject obj) { Exports* priv; priv = g_slice_new0(Exports); seed_object_set_private(obj, priv); priv->object = obj; } static gboolean add_connect_funcs(SeedContext ctx, SeedObject obj, DBusBusType which_bus) { Exports* priv; BigDBusConnectFuncs const* connect_funcs; priv = seed_object_get_private(obj); if (priv == NULL) return FALSE; if (which_bus == DBUS_BUS_SESSION) { connect_funcs = &session_connect_funcs; } else if (which_bus == DBUS_BUS_SYSTEM) { connect_funcs = &system_connect_funcs; } else g_assert_not_reached(); priv->which_bus = which_bus; big_dbus_add_connect_funcs_sync_notify(connect_funcs, priv); return TRUE; } static void exports_finalize(SeedObject obj) { Exports* priv; BigDBusConnectFuncs const* connect_funcs = NULL; priv = seed_object_get_private(obj); if (priv == NULL) return; /* we are the prototype, not a real instance, so constructor never called */ if (priv->which_bus == DBUS_BUS_SESSION) { connect_funcs = &session_connect_funcs; } else if (priv->which_bus == DBUS_BUS_SYSTEM) { connect_funcs = &system_connect_funcs; } else g_assert_not_reached(); big_dbus_remove_connect_funcs(connect_funcs, priv); if (priv->connection_weak_ref != NULL) { on_bus_closed(priv->connection_weak_ref, priv); } g_slice_free(Exports, priv); } static SeedObject exports_new(SeedContext ctx, DBusBusType which_bus) { SeedObject exports; if (!seed_js_exports_class) { seed_class_definition def = seed_empty_class; def.initialize = exports_constructor; def.finalize = exports_finalize; seed_js_exports_class = seed_create_class(&def); } exports = seed_make_object(ctx, seed_js_exports_class, NULL); return exports; } gboolean seed_js_define_dbus_exports(SeedContext ctx, SeedObject on_object, DBusBusType which_bus) { SeedObject exports; exports = exports_new(ctx, which_bus); if (!exports) return FALSE; if (!add_connect_funcs(ctx, exports, which_bus)) return FALSE; seed_object_set_property(ctx, on_object, "exports", exports); return TRUE; } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/dbus/dbus-exports.h000066400000000000000000000005231303774616400240430ustar00rootroot00000000000000 #ifndef __SEED_JS_DBUS_EXPORTS_H__ #define __SEED_JS_DBUS_EXPORTS_H__ #include #include #include G_BEGIN_DECLS gboolean seed_js_define_dbus_exports(SeedContext ctx, SeedObject object, DBusBusType which_bus); G_END_DECLS #endif seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/dbus/dbus-values.c000066400000000000000000000734351303774616400236450ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 * Copyright 2008 litl, LLC. All Rights Reserved. */ #include "dbus-values.h" #include #include //#include //#include #include gboolean seed_js_one_value_from_dbus(SeedContext ctx, DBusMessageIter* iter, SeedValue* value_p, SeedException* exception) { int arg_type; *value_p = seed_make_undefined(ctx); arg_type = dbus_message_iter_get_arg_type(iter); SEED_NOTE(MODULE, "Converting dbus type '%c' to SeedValue", arg_type != DBUS_TYPE_INVALID ? arg_type : '0'); switch (arg_type) { case DBUS_TYPE_STRUCT: { SeedObject obj; DBusMessageIter struct_iter; int index; obj = seed_make_object(ctx, NULL, NULL); dbus_message_iter_recurse(iter, &struct_iter); index = 0; while (dbus_message_iter_get_arg_type(&struct_iter) != DBUS_TYPE_INVALID) { SeedValue prop_value; prop_value = seed_make_undefined(ctx); if (!seed_js_one_value_from_dbus(ctx, &struct_iter, &prop_value, exception)) { return FALSE; } seed_object_set_property_at_index(ctx, obj, index, prop_value, exception); dbus_message_iter_next(&struct_iter); index++; } seed_object_set_property(ctx, obj, "length", seed_value_from_int(ctx, index, exception)); *value_p = (SeedValue) obj; } break; case DBUS_TYPE_ARRAY: { int elem_type = dbus_message_iter_get_element_type(iter); if (elem_type == DBUS_TYPE_DICT_ENTRY) { /* Create a dictionary object */ SeedObject obj; DBusMessageIter array_iter; obj = seed_make_object(ctx, NULL, NULL); dbus_message_iter_recurse(iter, &array_iter); while (dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_INVALID) { DBusMessageIter entry_iter; const char* key; SeedValue entry_value; dbus_message_iter_recurse(&array_iter, &entry_iter); if (dbus_message_iter_get_arg_type(&entry_iter) != DBUS_TYPE_STRING) { seed_make_exception(ctx, exception, "ArgumentError", "Dictionary keys are not strings," "can't convert to JavaScript"); return FALSE; } dbus_message_iter_get_basic(&entry_iter, &key); dbus_message_iter_next(&entry_iter); SEED_NOTE(MODULE, "Defining dict entry %s in jsval dict", key); entry_value = seed_make_undefined(ctx); if (!seed_js_one_value_from_dbus(ctx, &entry_iter, &entry_value, exception)) { return FALSE; } seed_object_set_property(ctx, obj, key, entry_value); dbus_message_iter_next(&array_iter); } *value_p = (SeedValue) obj; } else if (elem_type == DBUS_TYPE_BYTE) { /* byte arrays go to a string */ const char* v_BYTES; int n_bytes; DBusMessageIter array_iter; dbus_message_iter_recurse(iter, &array_iter); dbus_message_iter_get_fixed_array(&array_iter, &v_BYTES, &n_bytes); // This is where I am. *value_p = seed_value_from_binary_string(ctx, v_BYTES, n_bytes, exception); } else { SeedObject obj; DBusMessageIter array_iter; int index; obj = seed_make_object(ctx, NULL, NULL); dbus_message_iter_recurse(iter, &array_iter); index = 0; while (dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_INVALID) { SeedValue prop_value; prop_value = seed_make_undefined(ctx); if (!seed_js_one_value_from_dbus(ctx, &array_iter, &prop_value, exception)) { return FALSE; } seed_object_set_property_at_index(ctx, obj, index, prop_value, exception); dbus_message_iter_next(&array_iter); index++; } seed_object_set_property(ctx, obj, "length", seed_value_from_int(ctx, index, exception)); *value_p = (SeedValue) obj; } } break; case DBUS_TYPE_BOOLEAN: { dbus_bool_t v_BOOLEAN; dbus_message_iter_get_basic(iter, &v_BOOLEAN); *value_p = seed_value_from_boolean(ctx, v_BOOLEAN, exception); } break; case DBUS_TYPE_BYTE: { unsigned char v_BYTE; dbus_message_iter_get_basic(iter, &v_BYTE); *value_p = seed_value_from_int(ctx, v_BYTE, exception); } break; case DBUS_TYPE_INT32: { dbus_int32_t v_INT32; dbus_message_iter_get_basic(iter, &v_INT32); *value_p = seed_value_from_int(ctx, v_INT32, exception); } break; case DBUS_TYPE_UINT32: { dbus_uint32_t v_UINT32; dbus_message_iter_get_basic(iter, &v_UINT32); *value_p = seed_value_from_uint(ctx, v_UINT32, exception); } break; case DBUS_TYPE_INT64: { dbus_int64_t v_INT64; dbus_message_iter_get_basic(iter, &v_INT64); *value_p = seed_value_from_int64(ctx, v_INT64, exception); } break; case DBUS_TYPE_UINT64: { dbus_uint64_t v_UINT64; dbus_message_iter_get_basic(iter, &v_UINT64); *value_p = seed_value_from_uint64(ctx, v_UINT64, exception); } break; case DBUS_TYPE_DOUBLE: { double v_DOUBLE; dbus_message_iter_get_basic(iter, &v_DOUBLE); *value_p = seed_value_from_double(ctx, v_DOUBLE, exception); } break; case DBUS_TYPE_OBJECT_PATH: case DBUS_TYPE_STRING: { char* v_STRING; dbus_message_iter_get_basic(iter, &v_STRING); *value_p = seed_value_from_string(ctx, v_STRING, exception); } break; case DBUS_TYPE_VARIANT: { DBusMessageIter variant_iter; dbus_message_iter_recurse(iter, &variant_iter); return seed_js_one_value_from_dbus(ctx, &variant_iter, value_p, exception); } break; case DBUS_TYPE_INVALID: *value_p = seed_make_undefined(ctx); break; default: SEED_NOTE(MODULE, "Don't know how to convert dbus type %c to JavaScript", arg_type); return FALSE; } return TRUE; } gboolean seed_js_values_from_dbus(SeedContext ctx, DBusMessageIter* iter, GArray** array_p, SeedException* exception) { GArray* array; SeedValue value; value = seed_make_undefined(ctx); array = g_array_new(FALSE, FALSE, sizeof(SeedValue)); /* TODO */ // THIS IS WHERE IA M // Wheee. do { if (!seed_js_one_value_from_dbus(ctx, iter, &value, exception)) { g_array_free(array, TRUE); return FALSE; } g_array_append_val(array, value); } while (dbus_message_iter_next(iter)); *array_p = array; return TRUE; } static void append_basic_maybe_in_variant(DBusMessageIter* iter, int dbus_type, void* value, gboolean wrap_in_variant) { if (wrap_in_variant) { char buf[2]; DBusMessageIter variant_iter; buf[0] = dbus_type; buf[1] = '\0'; dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, buf, &variant_iter); dbus_message_iter_append_basic(&variant_iter, dbus_type, value); dbus_message_iter_close_container(iter, &variant_iter); } else { dbus_message_iter_append_basic(iter, dbus_type, value); } } static void append_byte_array_maybe_in_variant(DBusMessageIter* iter, const char* data, gsize len, gboolean wrap_in_variant) { DBusMessageIter array_iter; DBusMessageIter variant_iter; if (wrap_in_variant) { dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, "ay", &variant_iter); } dbus_message_iter_open_container(wrap_in_variant ? &variant_iter : iter, DBUS_TYPE_ARRAY, "y", &array_iter); dbus_message_iter_append_fixed_array(&array_iter, DBUS_TYPE_BYTE, &data, len); dbus_message_iter_close_container(wrap_in_variant ? &variant_iter : iter, &array_iter); if (wrap_in_variant) { dbus_message_iter_close_container(iter, &variant_iter); } } static gboolean append_string(SeedContext ctx, DBusMessageIter* iter, const char* forced_signature, const char* s, gsize len, SeedException* exception) { int forced_type; if (forced_signature == NULL || *forced_signature == DBUS_TYPE_INVALID) forced_type = DBUS_TYPE_STRING; else forced_type = *forced_signature; switch (forced_type) { case DBUS_TYPE_STRING: case DBUS_TYPE_OBJECT_PATH: case DBUS_TYPE_SIGNATURE: append_basic_maybe_in_variant(iter, forced_type, &s, FALSE); break; case DBUS_TYPE_VARIANT: append_basic_maybe_in_variant(iter, DBUS_TYPE_STRING, &s, TRUE); break; case DBUS_TYPE_ARRAY: g_assert(forced_signature != NULL); g_assert(forced_signature[0] == DBUS_TYPE_ARRAY); if (forced_signature[1] == DBUS_TYPE_BYTE) { append_byte_array_maybe_in_variant(iter, s, len, FALSE); } else { seed_make_exception(ctx, exception, "ArgumentError", "JavaScript string can't be converted to " "dbus array with elements of type '%c'", forced_signature[1]); return FALSE; } break; default: seed_make_exception( ctx, exception, "ArgumentError", "JavaScript string can't be converted to dbus type '%c'", forced_type); return FALSE; } return TRUE; } /* Seems to be unused static gboolean append_int32 (SeedContext ctx, DBusMessageIter * iter, int forced_type, dbus_int32_t v_INT32, SeedException *exception) { if (forced_type == DBUS_TYPE_INVALID) forced_type = DBUS_TYPE_INT32; switch (forced_type) { case DBUS_TYPE_INT32: append_basic_maybe_in_variant (iter, forced_type, &v_INT32, FALSE); break; case DBUS_TYPE_VARIANT: append_basic_maybe_in_variant (iter, DBUS_TYPE_INT32, &v_INT32, TRUE); break; case DBUS_TYPE_UINT32: { dbus_uint32_t v_UINT32 = v_INT32; append_basic_maybe_in_variant (iter, forced_type, &v_UINT32, FALSE); } break; case DBUS_TYPE_DOUBLE: { double v_DOUBLE = v_INT32; append_basic_maybe_in_variant (iter, forced_type, &v_DOUBLE, FALSE); } break; case DBUS_TYPE_BYTE: { unsigned char v_BYTE = v_INT32; append_basic_maybe_in_variant (iter, forced_type, &v_BYTE, FALSE); } break; default: seed_make_exception (ctx, exception, "ArgumentError", "JavaScript Integer can't be converted to dbus type '%c'", forced_type); return FALSE; } return TRUE; } */ static gboolean append_double(SeedContext ctx, DBusMessageIter* iter, int forced_type, double v_DOUBLE, SeedException* exception) { if (forced_type == DBUS_TYPE_INVALID) forced_type = DBUS_TYPE_DOUBLE; switch (forced_type) { case DBUS_TYPE_DOUBLE: append_basic_maybe_in_variant(iter, forced_type, &v_DOUBLE, FALSE); break; case DBUS_TYPE_VARIANT: append_basic_maybe_in_variant(iter, DBUS_TYPE_DOUBLE, &v_DOUBLE, TRUE); break; case DBUS_TYPE_INT32: { dbus_int32_t v_INT32 = v_DOUBLE; append_basic_maybe_in_variant(iter, forced_type, &v_INT32, FALSE); } break; case DBUS_TYPE_UINT32: { dbus_uint32_t v_UINT32 = v_DOUBLE; append_basic_maybe_in_variant(iter, forced_type, &v_UINT32, FALSE); } break; default: seed_make_exception( ctx, exception, "ArgumentError", "JavaScript Number can't be converted to dbus type '%c'", forced_type); return FALSE; } return TRUE; } static gboolean append_boolean(SeedContext ctx, DBusMessageIter* iter, int forced_type, dbus_bool_t v_BOOLEAN, SeedException* exception) { if (forced_type == DBUS_TYPE_INVALID) forced_type = DBUS_TYPE_BOOLEAN; switch (forced_type) { case DBUS_TYPE_BOOLEAN: append_basic_maybe_in_variant(iter, forced_type, &v_BOOLEAN, FALSE); break; case DBUS_TYPE_VARIANT: append_basic_maybe_in_variant(iter, DBUS_TYPE_BOOLEAN, &v_BOOLEAN, TRUE); break; default: seed_make_exception( ctx, exception, "ArgumentError", "JavaScript Boolean can't be converted to dbus type '%c'", forced_type); return FALSE; } return TRUE; } static gboolean append_array(SeedContext ctx, DBusMessageIter* iter, DBusSignatureIter* sig_iter, SeedObject array, int length, SeedException* exception) { DBusSignatureIter element_sig_iter; int forced_type; SeedValue element; DBusMessageIter array_iter; DBusMessageIter variant_iter; int i; char* sig; forced_type = dbus_signature_iter_get_current_type(sig_iter); if (forced_type == DBUS_TYPE_VARIANT) { DBusSignatureIter variant_sig_iter; dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, "av", &variant_iter); dbus_signature_iter_init(&variant_sig_iter, "av"); if (!append_array(ctx, &variant_iter, &variant_sig_iter, array, length, exception)) return FALSE; dbus_message_iter_close_container(iter, &variant_iter); return TRUE; } else if (forced_type != DBUS_TYPE_ARRAY) { seed_make_exception( ctx, exception, "ArgumentError", "JavaScript Array can't be converted to dbus type %c", forced_type); return FALSE; } g_assert(dbus_signature_iter_get_current_type(sig_iter) == DBUS_TYPE_ARRAY); dbus_signature_iter_recurse(sig_iter, &element_sig_iter); sig = dbus_signature_iter_get_signature(&element_sig_iter); dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, sig, &array_iter); dbus_free(sig); for (i = 0; i < length; i++) { element = seed_object_get_property_at_index(ctx, array, i, exception); SEED_NOTE(MODULE, " Adding array element %u", i); if (!seed_js_one_value_to_dbus(ctx, element, &array_iter, &element_sig_iter, exception)) return FALSE; } dbus_message_iter_close_container(iter, &array_iter); return TRUE; } // TODO: THIS IS WHERE I AM static gboolean append_dict(SeedContext ctx, DBusMessageIter* iter, DBusSignatureIter* sig_iter, SeedObject props, SeedException* exception) { DBusSignatureIter element_sig_iter; int forced_type; DBusMessageIter variant_iter; gchar** prop_names; guint num_props, i; DBusMessageIter dict_iter; DBusSignatureIter dict_value_sig_iter; char* sig; SeedValue prop_signatures; forced_type = dbus_signature_iter_get_current_type(sig_iter); if (forced_type == DBUS_TYPE_VARIANT) { DBusSignatureIter variant_sig_iter; dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, "a{sv}", &variant_iter); dbus_signature_iter_init(&variant_sig_iter, "a{sv}"); if (!append_dict(ctx, &variant_iter, &variant_sig_iter, props, exception)) return FALSE; dbus_message_iter_close_container(iter, &variant_iter); return TRUE; } else if (forced_type != DBUS_TYPE_ARRAY) { seed_make_exception( ctx, exception, "ArgumentError", "JavaScript Object can't be converted to dbus type %c", forced_type); return FALSE; } g_assert(dbus_signature_iter_get_current_type(sig_iter) == DBUS_TYPE_ARRAY); dbus_signature_iter_recurse(sig_iter, &element_sig_iter); if (dbus_signature_iter_get_current_type(&element_sig_iter) != DBUS_TYPE_DICT_ENTRY) { seed_make_exception( ctx, exception, "ArgumentError", "Objects must be marshaled as array of dict entry not of %c", dbus_signature_iter_get_current_type(&element_sig_iter)); return FALSE; } /* dbus itself enforces that dict keys are strings */ g_assert(dbus_signature_iter_get_current_type(&element_sig_iter) == DBUS_TYPE_DICT_ENTRY); dbus_signature_iter_recurse(&element_sig_iter, &dict_value_sig_iter); /* check it points to key type first */ g_assert(dbus_signature_iter_get_current_type(&dict_value_sig_iter) == DBUS_TYPE_STRING); /* move to value type */ dbus_signature_iter_next(&dict_value_sig_iter); sig = dbus_signature_iter_get_signature(&element_sig_iter); dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, sig, &dict_iter); dbus_free(sig); /* If a dictionary contains another dictionary at key * _dbus_signatures, the sub-dictionary can provide the signature * of each value in the outer dictionary. This allows forcing * integers to unsigned or whatever. * * _dbus_signatures has a weird name to avoid conflicting with * real properties. Matches _dbus_sender which is used elsewhere. * * We don't bother rooting the signature object or the stuff in it * because we assume the outer dictionary is rooted so the stuff * in it is also. */ prop_signatures = seed_object_get_property(ctx, props, "_dbus_signatures"); if (!seed_value_is_undefined(ctx, prop_signatures) && !seed_value_is_object(ctx, prop_signatures)) { seed_make_exception(ctx, exception, "ArgumentError", "_dbus_signatures prop must be an object"); return FALSE; } if (!seed_value_is_undefined(ctx, prop_signatures) && dbus_signature_iter_get_current_type(&dict_value_sig_iter) != DBUS_TYPE_VARIANT) { seed_make_exception(ctx, exception, "ArgumentError", "Specifying _dbus_signatures for a " "dictionary with non-variant values " "is useless"); return FALSE; } prop_names = seed_object_copy_property_names(ctx, props); num_props = g_strv_length(prop_names); for (i = 0; i < num_props; i++) { char* name; SeedValue propval; DBusMessageIter entry_iter; const char* value_signature; name = prop_names[i]; if (strcmp(name, "_dbus_signatures") == 0) { /* skip the magic "_dbus_signatures" field */ goto next; } /* see if this prop has a forced signature */ value_signature = NULL; if (!seed_value_is_undefined(ctx, prop_signatures)) { SeedValue signature_value; signature_value = seed_object_get_property(ctx, prop_signatures, name); if (!seed_value_is_undefined(ctx, signature_value)) { value_signature = seed_value_to_string(ctx, signature_value, exception); if (value_signature == NULL) { return FALSE; } } } // if (!gjs_object_require_property // (ctx, props, "DBus append_dict", name, &propval)) // return FALSE; propval = seed_object_get_property(ctx, props, name); SEED_NOTE(MODULE, " Adding property %s", name); /* seed_js_one_value_to_dbus() would check this also, but would not * print the property name, which is often useful */ if (seed_value_is_null(ctx, propval)) { seed_make_exception( ctx, exception, "ArgumentError", "Property '%s' has a null value, can't send over dbus", name); return FALSE; } dbus_message_iter_open_container(&dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &entry_iter); dbus_message_iter_append_basic(&entry_iter, DBUS_TYPE_STRING, &name); g_free(name); if (value_signature != NULL) { DBusSignatureIter forced_signature_iter; DBusMessageIter variant_iter; g_assert(dbus_signature_iter_get_current_type(&dict_value_sig_iter) == DBUS_TYPE_VARIANT); dbus_message_iter_open_container(&entry_iter, DBUS_TYPE_VARIANT, value_signature, &variant_iter); dbus_signature_iter_init(&forced_signature_iter, value_signature); if (!seed_js_one_value_to_dbus(ctx, propval, &variant_iter, &forced_signature_iter, exception)) return FALSE; dbus_message_iter_close_container(&entry_iter, &variant_iter); } else { if (!seed_js_one_value_to_dbus(ctx, propval, &entry_iter, &dict_value_sig_iter, exception)) return FALSE; } dbus_message_iter_close_container(&dict_iter, &entry_iter); next: continue; } g_strfreev(prop_names); dbus_message_iter_close_container(iter, &dict_iter); return TRUE; } gboolean seed_js_one_value_to_dbus(SeedContext ctx, SeedValue value, DBusMessageIter* iter, DBusSignatureIter* sig_iter, SeedException* exception) { SeedType type; int forced_type; forced_type = dbus_signature_iter_get_current_type(sig_iter); SEED_NOTE(MODULE, "Converting dbus type '%c' from SeedValue", forced_type != DBUS_TYPE_INVALID ? forced_type : '0'); /* Don't write anything on the bus if the signature is empty */ if (forced_type == DBUS_TYPE_INVALID) return TRUE; type = seed_value_get_type(ctx, value); if (seed_value_is_null(ctx, value)) { seed_make_exception(ctx, exception, "ArgumentError", "Can't send null values over dbus"); return FALSE; } else if (type == SEED_TYPE_STRING) { char* data; gsize len; char buf[3] = { '\0', '\0', '\0' }; if (forced_type == DBUS_TYPE_ARRAY) { buf[0] = DBUS_TYPE_ARRAY; buf[1] = dbus_signature_iter_get_element_type(sig_iter); } else { buf[0] = forced_type; } data = NULL; len = 0; // FIX? if (buf[1] == DBUS_TYPE_BYTE) { data = seed_value_to_string(ctx, value, exception); len = strlen(data); // if (!gjs_string_get_binary_data (ctx, value, &data, &len)) // return FALSE; } else { data = seed_value_to_string(ctx, value, exception); len = strlen(data); } if (!append_string(ctx, iter, buf, data, len, exception)) { g_free(data); return FALSE; } g_free(data); } /* else if (type == SEED_TYPE_NUMBER) { dbus_int32_t v_INT32; v_INT32 = seed_value_to_int (ctx, value, exception); if (!append_int32 (ctx, iter, forced_type, v_INT32, exception)) return FALSE; }*/ else if (type == SEED_TYPE_NUMBER) { double v_DOUBLE; v_DOUBLE = seed_value_to_double(ctx, value, exception); if (!append_double(ctx, iter, forced_type, v_DOUBLE, exception)) return FALSE; } else if (type == SEED_TYPE_BOOLEAN) { dbus_bool_t v_BOOLEAN; v_BOOLEAN = seed_value_to_boolean(ctx, value, exception); if (!append_boolean(ctx, iter, forced_type, v_BOOLEAN, exception)) return FALSE; } else if (type == SEED_TYPE_OBJECT) { SeedValue lengthval; /* see if there's a length property */ lengthval = seed_object_get_property(ctx, value, "length"); if (seed_value_get_type(ctx, lengthval) == SEED_TYPE_NUMBER) { guint length; length = seed_value_to_int(ctx, lengthval, exception); SEED_NOTE(MODULE, "Looks like an array length %u", length); if (!append_array(ctx, iter, sig_iter, value, length, exception)) return FALSE; } else { SEED_NOTE(MODULE, "Looks like a dictionary"); if (!append_dict(ctx, iter, sig_iter, value, exception)) return FALSE; } } else if (type == SEED_TYPE_UNDEFINED) { SEED_NOTE(MODULE, "Can't send void (undefined) values over dbus"); seed_make_exception(ctx, exception, "ArgumentError", "Can't send void (undefined) values over dbus"); return FALSE; } else { SEED_NOTE(MODULE, "Don't know how to convert this jsval to dbus type"); seed_make_exception( ctx, exception, "ArgumentError", "Don't know how to convert this jsval to dbus type"); return FALSE; } return TRUE; } gboolean seed_js_values_to_dbus(SeedContext ctx, int index, SeedObject values, DBusMessageIter* iter, DBusSignatureIter* sig_iter, SeedException* exception) { SeedValue value; guint length; length = seed_value_to_int(ctx, seed_object_get_property(ctx, values, "length"), exception); if (index > (int) length) { seed_make_exception(ctx, exception, "ArgumentError", "Index %d is bigger than array length %d", index, length); return FALSE; } if (index == (int) length) return TRUE; value = seed_object_get_property_at_index(ctx, values, index, exception); if (!seed_js_one_value_to_dbus(ctx, value, iter, sig_iter, exception)) { seed_make_exception(ctx, exception, "ArgumentError", "Error marshalling js value to dbus"); return FALSE; } if (dbus_signature_iter_next(sig_iter)) { return seed_js_values_to_dbus(ctx, index + 1, values, iter, sig_iter, exception); } return TRUE; } /* If jsval is an object, add properties from the DBusMessage such as the * sender. If jsval is not an object, do nothing. */ gboolean seed_js_add_dbus_props(SeedContext ctx, DBusMessage* message, SeedValue value, SeedException* exception) { gchar* sender; if (seed_value_is_null(ctx, value) || !seed_value_is_object(ctx, value)) return TRUE; sender = (gchar*) dbus_message_get_sender(message); seed_object_set_property(ctx, value, "_dbus_sender", seed_value_from_string(ctx, sender, exception)); return TRUE; } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/dbus/dbus-values.h000066400000000000000000000031241303774616400236360ustar00rootroot00000000000000/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ /* Copyright 2008 litl, LLC. All Rights Reserved. */ #ifndef __SEED_JS_DBUS_VALUES_H__ #define __SEED_JS_DBUS_VALUES_H__ #include #include #include G_BEGIN_DECLS extern SeedContextGroup group; gboolean seed_js_values_from_dbus(SeedContext ctx, DBusMessageIter* iter, GArray** aray_p, SeedException* exception); gboolean seed_js_one_value_from_dbus(SeedContext ctx, DBusMessageIter* iter, SeedValue* value_p, SeedException* exception); gboolean seed_js_values_to_dbus(SeedContext ctx, int index, SeedObject values, DBusMessageIter* iter, DBusSignatureIter* sig_iter, SeedException* exception); gboolean seed_js_one_value_to_dbus(SeedContext ctx, SeedValue value, DBusMessageIter* iter, DBusSignatureIter* sig_iter, SeedException* exception); gboolean seed_js_add_dbus_props(SeedContext ctx, DBusMessage* message, SeedValue value, SeedException* exception); G_END_DECLS #endif /* __SEED_JS_DBUS_VALUES_H__ */ seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/dbus/dbus.js000066400000000000000000000527621303774616400225420ustar00rootroot00000000000000// Copyright 2008 litl, LLC. All Rights Reserved. log = print Lang = imports.lang; //const StringUtil = imports.stringUtil; //const ArrayUtil = imports.arrayUtil; // Parameters for acquire_name, keep in sync with // enum in util/dbus.h const SINGLE_INSTANCE = 0; const MANY_INSTANCES = 1; const NO_START_IF_NOT_FOUND = false; const START_IF_NOT_FOUND = true; // Merge stuff defined in native code dbusnative = imports.dbusnative; Lang.copyProperties(dbusnative, this); function propsToArray(obj) { var a = new Array(); for (i in ifaces) a.push(i); return a; } var Introspectable = { name: 'org.freedesktop.DBus.Introspectable', methods: [ // Introspectable: return an XML description of the object. // Out Args: // xml_data: XML description of the object. { name: 'Introspect', inSignature: '', outSignature: 's' } ], signals: [], properties: [] }; var Properties = { name: 'org.freedesktop.DBus.Properties', methods: [ { name: 'Get', inSignature: 'ss', outSignature: 'v' }, { name: 'Set', inSignature: 'ssv', outSignature: '' }, { name: 'GetAll', inSignature: 's', outSignature: 'a{sv}' } ], signals: [], properties: [] }; function _proxyInvoker(obj, ifaceName, methodName, outSignature, inSignature, timeout, arg_array) { var replyFunc; /* Note: "this" in here is the module, "obj" is the proxy object */ if (ifaceName == null) ifaceName = obj._dbusInterface; /* Convert arg_array to a *real* array */ arg_array = Array.prototype.slice.call(arg_array); /* The default replyFunc only logs the responses */ replyFunc = _logReply; var expectedNumberArgs = this.signatureLength(inSignature); if (arg_array.length < expectedNumberArgs) { throw new Error("Not enough arguments passed for method: " + methodName + ". Expected " + expectedNumberArgs + ", got " + arg_array.length); } else if (arg_array.length == expectedNumberArgs + 1) { /* If there's one more than the expected number * of argument we asume the last one is the reply * function */ replyFunc = arg_array.pop(); } else if (arg_array.length != expectedNumberArgs) { throw new Error("Too many arguments passed for method: " + methodName + ". Maximum is " + expectedNumberArgs + " + one callback"); } /* Auto-start on method calls is too unpredictable; in particular if * something crashes we want to cleanly restart it, not have it * come back next time someone tries to use it. */ obj._dbusBus.call_async(obj._dbusBusName, obj._dbusPath, ifaceName, methodName, outSignature, inSignature, NO_START_IF_NOT_FOUND, timeout, arg_array, replyFunc); } function _proxyInvokerSync(obj, ifaceName, methodName, outSignature, inSignature, timeout, arg_array) { if (ifaceName == null) ifaceName = obj._dbusInterface; /* Convert arg_array to a *real* array */ arg_array = Array.prototype.slice.call(arg_array); var expectedNumberArgs = this.signatureLength(inSignature); if (arg_array.length < expectedNumberArgs) { throw new Error("Not enough arguments passed for method: " + methodName + ". Expected " + expectedNumberArgs + ", got " + arg_array.length); } else if (arg_array.length > expectedNumberArgs) { throw new Error("Too many arguments passed for method: " + methodName + ". Maximum is " + expectedNumberArgs); } /* Auto-start on method calls is too unpredictable; in particular if * something crashes we want to cleanly restart it, not have it * come back next time someone tries to use it. */ return obj._dbusBus.call(obj._dbusBusName, obj._dbusPath, ifaceName, methodName, outSignature, inSignature, NO_START_IF_NOT_FOUND, arg_array); } function _logReply(result, exc) { if (result != null) { log("Ignored reply to dbus method: " + result.toSource()); } if (exc != null) { log("Ignored exception from dbus method: " + exc.message); } } function _makeProxyMethod(member) { return function() { /* JSON methods are the default */ if (!("outSignature" in member)) member.outSignature = "a{sv}"; if (!("inSignature" in member)) member.inSignature = "a{sv}"; if (!("timeout" in member)) member.timeout = -1; _proxyInvoker(this, null, member.name, member.outSignature, member.inSignature, member.timeout, arguments); }; } function _makeProxyMethodSync(member) { return function() { /* JSON methods are the default */ if (!("outSignature" in member)) member.outSignature = "a{sv}"; if (!("inSignature" in member)) member.inSignature = "a{sv}"; if (!("timeout" in member)) member.timeout = -1; return _proxyInvokerSync(this, null, member.name, member.outSignature, member.inSignature, member.timeout, arguments); }; } // stub we insert in all proxy prototypes function _getBusName() { return this._dbusBusName; } // stub we insert in all proxy prototypes function _getPath() { return this._dbusPath; } // stub we insert in all proxy prototypes function _getBus() { return this._dbusBus; } // stub we insert in all proxy prototypes function _getInterface() { return this._dbusInterface; } function _invokeSignalWatchCallback(callback, emitter, argsFromDBus) { var argArray = [emitter]; var length = argsFromDBus.length; for (var i = 0; i < length; ++i) { argArray.push(argsFromDBus[i]); } callback.apply(null, argArray); } function _connect(signalName, callback) { if (!this._signalNames || !(signalName in this._signalNames)) throw new Error("Signal " + signalName + " not defined in this object"); var me = this; return this._dbusBus.watch_signal(this._dbusBusName, this._dbusPath, this._dbusInterface, signalName, function() { _invokeSignalWatchCallback(callback, me, arguments); }); } function _disconnectByID(ID) { this._dbusBus.unwatch_signal_by_id(ID); } function _getRemote(propName) { // convert arguments to regular array var argArray = [].splice.call(arguments, 0); // prepend iface the property is on argArray.splice(0, 0, this._dbusInterface); _proxyInvoker(this, "org.freedesktop.DBus.Properties", "Get", "v", "ss", -1, argArray); } function _setRemote(propName, value) { // convert arguments to regular array var argArray = [].splice.call(arguments, 0); // prepend iface the property is on argArray.splice(0, 0, this._dbusInterface); _proxyInvoker(this, "org.freedesktop.DBus.Properties", "Set", "", "ssv", -1, argArray); } function _getRemoteSync(propName) { // convert arguments to regular array var argArray = [].splice.call(arguments, 0); // prepend iface the property is on argArray.splice(0, 0, this._dbusInterface); return _proxyInvokerSync(this, "org.freedesktop.DBus.Properties", "Get", "v", "ss", -1, argArray); } function _setRemoteSync(propName, value) { // convert arguments to regular array var argArray = [].splice.call(arguments, 0); // prepend iface the property is on argArray.splice(0, 0, this._dbusInterface); _proxyInvokerSync(this, "org.freedesktop.DBus.Properties", "Set", "", "ssv", -1, argArray); } function _getAllRemote() { // convert arguments to regular array var argArray = [].splice.call(arguments, 0); // prepend iface the properties are on argArray.splice(0, 0, this._dbusInterface); _proxyInvoker(this, "org.freedesktop.DBus.Properties", "GetAll", "a{sv}", "s", -1, argArray); } // adds remote members to a prototype. The instances using // the prototype must be proxified with proxifyObject, too. // Note that the bus (system vs. session) is per-instance not // per-prototype so the bus should not be involved in this // function. // The "iface" arg is a special object that might have properties // for 'name', 'methods', and 'signals' function proxifyPrototype(proto, iface) { if ('name' in iface) proto._dbusInterface = iface.name; else proto._dbusInterface = null; if ('methods' in iface) { var methods = iface.methods; for (var i = 0; i < methods.length; ++i) { var method = methods[i]; if (!('name' in method)) throw new Error("Method definition must have a name"); /* To ease transition let's create two methods: Foo and FooRemote. * Foo will just log a warning so we can catch people using the * old naming system. FooRemote is the actual proxy method. */ var methodName = method.name + "Remote"; proto[methodName] = _makeProxyMethod(method); proto[methodName+"Sync"] = _makeProxyMethodSync(method); proto[method.name] = function() { log("PROXY-ERROR: " + method.name + " called, you should be using " + methodName + " instead"); }; } } if ('signals' in iface) { var signals = iface.signals; var signalNames = {}; for (var i = 0; i < signals.length; i++) { var signal = signals[i]; if (!('name' in signal)) throw new Error("Signal definition must have a name"); var name = signal.name; /* This is a bit silly, but we might want to add more information * later and it still beats an Array in checking if the object has * a given signal */ signalNames[name] = name; } proto['_signalNames'] = signalNames; proto['connect'] = _connect; proto['disconnect'] = _disconnectByID; } // properties just adds GetRemote, SetRemote, and GetAllRemote // methods; using attributes would force synchronous API. if ('properties' in iface && iface.properties.length > 0) { proto['GetRemote'] = _getRemote; proto['SetRemote'] = _setRemote; proto['GetRemoteSync'] = _getRemoteSync; proto['SetRemoteSync'] = _setRemoteSync; proto['GetAllRemote'] = _getAllRemote; } proto['getBusName'] = _getBusName; proto['getPath'] = _getPath; proto['getBus'] = _getBus; proto['getInterface'] = _getInterface; } // methods common to both session and system buses. // add them to the common prototype of this.session and this.system. // convert any object to a dbus proxy ... assumes its prototype is // also proxified this.system.proxifyObject = this.session.proxifyObject = function(obj, busName, path) { if (!busName) { throw new Error('missing bus name proxifying object'); } if (!path) { throw new Error('missing path proxifying object'); } if (path[0] != '/') throw new Error("Path doesn't look like a path: " + path); obj._dbusBus = this; obj._dbusBusName = busName; obj._dbusPath = path; }; // add 'object' to the exports object at the given path var _addExports = function(node, path, object) { if (path == '') { if ('-impl-' in node) throw new Error("Object already registered for path."); node['-impl-'] = object; } else { var idx = path.indexOf('/'); var head = (idx >= 0) ? path.slice(0, idx) : path; var tail = (idx >= 0) ? path.slice(idx+1) : ''; if (!(head in node)) node[head] = {}; _addExports(node[head], tail, object); } }; // Fiiix // remove any implementation from exports at the given path. var _removeExportsPath = function(node, path) { if (path == '') { delete node['-impl-']; } else { var idx = path.indexOf('/'); var head = (idx >= 0) ? path.slice(0, idx) : path; var tail = (idx >= 0) ? path.slice(idx+1) : ''; // recursively delete next component _removeExportsPath(node[head], tail); // are we empty now? if so, clean us up. // If we had destructuring assignment, this would be cool if (propsToArray(node[head]).length == 0) { delete node[head]; } } }; this._busProto = this.session.__proto__ // export the object at the specified object path this._busProto.exportObject = function(path, object) { if (path.slice(0,1) != '/') throw new Error("Bad path! Must start with /"); // keep session and system paths separate, just in case we register on both var pathProp = '_dbusPaths' + this._dbusBusType; // optimize for the common one-path case by using a colon-delimited // string rather than an array. if (!(pathProp in object)) { object[pathProp] = path; } else { object[pathProp] += ':' + path; } _addExports(this.exports, path.slice(1), object); }; // unregister this object from all its paths this._busProto.unexportObject = function(object) { // keep session and system paths separate, just in case we register on both var pathProp = '_dbusPaths' + this._dbusBusType; if (!(pathProp in object)) return; // already or never registered. var dbusPaths = object[pathProp].split(':'); for (var i = 0; i < dbusPaths.length; ++i) { var path = dbusPaths[i]; _removeExportsPath(this.exports, path.slice(1)); } delete object[pathProp]; }; // given a "this" with _dbusInterfaces, return a dict from property // names to property signatures. Used as value of _dbus_signatures // when passing around a dict of properties. function _getPropertySignatures(ifaceName) { var iface = this._dbusInterfaces[ifaceName]; if (!iface) throw new Error("Object has no interface " + ifaceName); if (!('_dbusPropertySignaturesCache' in iface)) { var signatures = {}; if ('properties' in iface) { var properties = iface.properties; for (var i = 0; i < properties.length; ++i) { signatures[properties[i].name] = properties[i].signature; } } iface._dbusPropertySignaturesCache = signatures; } return iface._dbusPropertySignaturesCache; } // split a "single complete type" (SCT) from the rest of a dbus signature. // Returns the tail, and the head is added to acc. function _eatSCT(acc, s) { // eat the first character var c = s.charAt(0); s = s.slice(1); acc.push(c); // if this is a compound type, loop eating until we reach the close paren if (c=='(') { while (s.charAt(0) != ')') { s = _eatSCT(acc, s); } s = _eatSCT(acc, s); // the close paren } else if (c=='{') { s = _eatSCT(acc, s); s = _eatSCT(acc, s); if (s.charAt(0) != '}') throw new Error("Bad DICT_ENTRY signature!"); s = _eatSCT(acc, s); // the close brace } else if (c=='a') { s = _eatSCT(acc, s); // element type } return s; } // parse signature string, generating a list of "single complete types" //function _parseDBusSigs(sig) { // while (sig.length > 0) { // var one = []; // sig = _eatSCT(one, sig); // yield one.join(''); // } //} function _parseDBusSigs(sig){ var sigs = []; while (sig.length > 0) { sig = _eatSCT(sigs, sig); } return sigs.join(''); } // given a "this" with _dbusInterfaces, returns DBus Introspection // format XML giving interfaces and methods implemented. function _getInterfaceXML() { var result = ''; // iterate through defined interfaces var ifaces = ('_dbusInterfaces' in this) ? this._dbusInterfaces : {}; ifaces = propsToArray(ifaces); // add introspectable and properties ifaces.push(Introspectable); ifaces.push(Properties); for (var i = 0; i < ifaces.length; i++) { var iface = ifaces[i]; result += Seed.sprintf(' \n', iface.name); // describe methods. var methods = ('methods' in iface) ? iface.methods : []; for (var j = 0; j < methods.length; j++) { var method = methods[j]; result += Seed.sprintf( ' \n', method.name); for (var sig in _parseDBusSigs(method.inSignature)) { result += Seed.sprintf( ' \n', sig); } for (var sig in _parseDBusSigs(method.outSignature)) { result += Seed.sprintf( ' \n', sig); } result += ' \n'; } // describe signals var signals = ('signals' in iface) ? iface.signals : []; for (var j = 0; j < signals.length; j++) { var signal = signals[j]; result += Seed.sprintf( ' \n', signal.name); for (var sig in _parseDBusSigs(signal.inSignature)) { result += Seed.sprintf( ' \n', sig); } result += ' \n'; } // describe properties var properties = ('properties' in iface) ? iface.properties : []; for (var j = 0; j < properties.length; j++) { var property = properties[j]; result += Seed.sprintf( ' \n', property.name, property.signature, property.access); } // close tag result += ' \n'; } return result; } // Verifies that a given object conforms to a given interface, // and stores meta-info from the interface in the object as // required. // Note that an object can be exported on multiple buses, so conformExport() // should not be specific to the bus (session vs. system) function conformExport(object, iface) { if (!('_dbusInterfaces' in object)) { object._dbusInterfaces = {}; } else if (iface.name in object._dbusInterfaces) { return; } object._dbusInterfaces[iface.name] = iface; object.getDBusPropertySignatures = _getPropertySignatures; if (!('getDBusInterfaceXML' in object)) object.getDBusInterfaceXML = _getInterfaceXML; if ('methods' in iface) { var methods = iface.methods; for (var i = 0; i < methods.length; ++i) { var method = methods[i]; if (!('name' in method)) throw new Error("Method definition must have a name"); if (!('outSignature' in method)) method.outSignature = "a{sv}"; var name = method.name; var asyncName = name +"Async"; var missing = []; if (!(name in object) && !(asyncName in object)) { missing.push(name); } else { if (asyncName in object) object[asyncName].outSignature = method.outSignature; else object[name].outSignature = method.outSignature; } if (missing.length > 0) { throw new Error("Exported object missing members " + missing.toSource()); } } } if ('properties' in iface) { var properties = iface.properties; var missing = []; for (var i = 0; i < properties.length; ++i) { if (!(properties[i].name in object)) { missing += properties[i]; } } if (missing.length > 0) { throw new Error("Exported object missing properties " + missing.toSource()); } } // sanity-check signals if ('signals' in iface) { var signals = iface.signals; for (var i = 0; i < signals.length; ++i) { var signal = signals[i]; if (signal.name.indexOf('-') >= 0) throw new Error("dbus signals cannot have a hyphen in them, use camelCase"); } } } // DBusError object // Used to return dbus error with given name and mesage from // remote methods function DBusError(dbusErrorName, errorMessage) { this.dbusErrorName = dbusErrorName; this.errorMessage = errorMessage; } DBusError.prototype = { toString: function() { return this.errorMessage; } }; // Introspectable proxy function IntrospectableProxy(bus, busName, path) { this._init(bus, busName, path); } IntrospectableProxy.prototype = { _init : function(bus, busName, path) { bus.proxifyObject(this, busName, path); } }; proxifyPrototype(IntrospectableProxy.prototype, Introspectable); seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/dbus/dbus2js.py000077500000000000000000000167551303774616400232020ustar00rootroot00000000000000#! /usr/bin/python # Copyright 2009 litl, LLC. All Rights Reserved. ## this file outputs sortof-indented JavaScript, ## it's semi-readable for use when testing, but ## when checking in real output, run M-x indent-region ## in js2-mode import sys import xml.dom.minidom import textwrap import re out = sys.stdout commentWrapper = textwrap.TextWrapper() commentWrapper.initial_indent = '// ' commentWrapper.subsequent_indent = '// ' def getText(nodelist): rc = "" for node in nodelist: if node.nodeType == node.TEXT_NODE: rc = rc + node.data return rc def getDocstring(node): docstrings = node.getElementsByTagName('tp:docstring') docstring = '' if len(docstrings) > 0 and docstrings[0].parentNode == node: docstring = getText(docstrings[0].childNodes).strip() return re.sub('\s+', ' ', docstring) def methodAsString(method): dbusName = method.getAttribute("name") args = method.getElementsByTagName("arg") methodDocstring = getDocstring(method) inArgs = '' inArgsComments = '' outArgs = '' outArgsComments = '' for arg in args: argName = arg.getAttribute('name') docstring = getDocstring(arg) tpType = arg.getAttribute('tp:type') if tpType and len(tpType) > 0: docstring = "(" + tpType + ") " + docstring comment = commentWrapper.fill(' ' + argName + ': ' + docstring) + '\n' direction = arg.getAttribute('direction') type = arg.getAttribute('type') if direction == 'in' or (method.tagName == 'signal' and not direction): inArgs += type inArgsComments += comment elif direction == 'out': outArgs += type outArgsComments += comment else: raise Exception("unknown direction " + direction) errorComments = '' possibleErrors = method.getElementsByTagName("tp:possible-errors") if possibleErrors: for error in possibleErrors[0].getElementsByTagName("tp:error"): errorName = error.getAttribute("name") docstring = getDocstring(error) errorComments += commentWrapper.fill(' ' + errorName + ' ' + docstring) + '\n' if "'" in methodDocstring: # js2-mode gets pissy about unmatched quotes in comments, # it's a bug methodDocstring = methodDocstring.replace("'", "") docComment = commentWrapper.fill(dbusName + ': ' + methodDocstring) + '\n' if len(inArgsComments) > 0: inArgsComments = "// In Args:\n" + inArgsComments if len(outArgsComments) > 0: outArgsComments = "// Out Args:\n" + outArgsComments if len(errorComments) > 0: errorComments = "// Errors:\n" + errorComments inSig = "inSignature: '%s'" % inArgs outSig = "outSignature: '%s'" % outArgs asString = "\n%s%s%s%s\n{ name: '%s', %s, %s }" % \ (docComment, inArgsComments, outArgsComments, errorComments, dbusName, inSig, outSig) return asString def methodsOrSignalsAsString(methodsOrSignals): if len(methodsOrSignals) == 0: return "[]" asString = '[\n' for method in methodsOrSignals: asString = asString + ' ' + methodAsString(method) + ',\n' asString = asString[:-2] + '\n ]' return asString def propertiesAsString(properties): if len(properties) == 0: return "[]" asString = '[\n' for prop in properties: name = prop.getAttribute("name") type = prop.getAttribute("type") tpType = prop.getAttribute("tp:type") access = prop.getAttribute("access") docComment = name + ': ' if tpType and len(tpType) > 0: docComment += '(' + tpType + ') '; docComment = '\n' + commentWrapper.fill(docComment + getDocstring(prop)) asString += "%s\n\n { name: '%s', signature: '%s', access: '%s' },\n" % \ (docComment, name, type, access); asString = asString[:-2] + '\n ]' return asString def outputEnums(enums, dbusIfaceName): for e in enums: eName = e.getAttribute('name') out.write('\n// ' + eName + ' in ' + dbusIfaceName + '\n') values = [] for val in e.getElementsByTagName('tp:enumvalue'): valSuffix = val.getAttribute('suffix') valValue = val.getAttribute('value') valDocstring = getDocstring(val) values.append((valSuffix, valValue, valDocstring)) for val in values: out.write(commentWrapper.fill(' ' + val[0] + ': ' + val[2]) + '\n') out.write('\n') for val in values: out.write('const %s_%s = %s;\n' % (eName, val[0], val[1])) out.write('\n') def outputFlags(flags, dbusIfaceName): for e in flags: eName = e.getAttribute('name') out.write('\n// ' + eName + ' in ' + dbusIfaceName + '\n') values = [] for val in e.getElementsByTagName('tp:flag'): valSuffix = val.getAttribute('suffix') valValue = val.getAttribute('value') valDocstring = getDocstring(val) values.append((valSuffix, valValue, valDocstring)) for val in values: out.write(commentWrapper.fill(' ' + val[0] + ': ' + val[2]) + '\n') out.write('\n') for val in values: out.write('const %s_%s = %s;\n' % (eName, val[0], val[1])) out.write('\n') def outputInterface(iface): dbusIfaceName = iface.getAttribute("name") jsIfaceName = dbusIfaceName.replace('org.freedesktop.', '').replace('.','') methods = methodsOrSignalsAsString(iface.getElementsByTagName('method')); signals = methodsOrSignalsAsString(iface.getElementsByTagName('signal')); properties = propertiesAsString(iface.getElementsByTagName('property')); out.write(""" var %s = { name: '%s', methods: %s, signals: %s, properties: %s }; """ % (jsIfaceName, dbusIfaceName, methods, signals, properties)); enums = iface.getElementsByTagName('tp:enum') outputEnums(enums, dbusIfaceName); flags = iface.getElementsByTagName('tp:flags') outputFlags(flags, dbusIfaceName); def outputNode(node): for child in node.childNodes: if child.nodeType != child.ELEMENT_NODE: continue if child.tagName == 'interface': outputInterface(child) else: raise Exception("unknown tag in : " + child.tagName) out.write("// AUTOMATICALLY GENERATED INTERFACE FILE\n") out.write("// Do not edit by hand.\n\n") for filename in sys.argv[1:]: if filename.endswith('nm-manager-client.xml'): ## nm-manager-client.xml is nm-manager.xml ## with some deprecated stuff removed, to ## generate dbus-glib client bindings. The ## detailed docs and stuff are in nm-manager.xml though. continue dom = xml.dom.minidom.parse(filename) for child in dom.childNodes: if child.nodeType != child.ELEMENT_NODE: continue if child.tagName == 'node': outputNode(child) elif child.tagName == 'tp:generic-types': enums = child.getElementsByTagName('tp:enum') outputEnums(enums, 'generic-types'); flags = child.getElementsByTagName('tp:flags') outputFlags(flags, 'generic-types'); elif child.tagName in ['tp:spec', 'tp:title', 'tp:version', 'tp:copyright', 'tp:license', 'xi:include', 'tp:errors' ]: continue else: raise Exception("unknown tag at root: " + child.tagName) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/dbus/lang.js000066400000000000000000000062021303774616400225120ustar00rootroot00000000000000// Copyright (c) 2008 litl, LLC // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. // Utilities that are "meta-language" things like manipulating object props function countProperties(obj) { var count = 0; for (var property in obj) { count += 1; } return count; } function _copyProperty(source, dest, property) { dest[property] = source[property]; } function copyProperties(source, dest) { for (var property in source) { _copyProperty(source, dest, property); } } function copyPublicProperties(source, dest) { for (var property in source) { if (typeof(property) == 'string' && property.substring(0, 1) == '_') { continue; } else { _copyProperty(source, dest, property); } } } function copyPropertiesNoOverwrite(source, dest) { for (var property in source) { if (!(property in dest)) { _copyProperty(source, dest, property); } } } function removeNullProperties(obj) { for (var property in obj) { if (obj[property] == null) delete obj[property]; else if (typeof(obj[property]) == 'object') removeNullProperties(obj[property]); } } /** * Binds obj to callback. Makes it possible to refer to "obj" * using this within the callback. * @param {object} obj the object to bind * @param {function} callback callback to bind obj in * @param arguments additional arguments to the callback * @returns: a new callback * @type: function */ function bind(obj, callback) { var me = obj; var bindArguments = Array.prototype.slice.call(arguments, 2); if (typeof(obj) != 'object') { throw new Error( "first argument to Lang.bind() must be an object, not " + typeof(obj)); } if (typeof(callback) != 'function') { throw new Error( "second argument to Lang.bind() must be a function, not " + typeof(callback)); } return function() { var args = Array.prototype.slice.call(arguments); args = args.concat(bindArguments); return callback.apply(me, args); }; } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/dbus/module.c000066400000000000000000001254151303774616400226740ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #include #include #include "util/dbus.h" #include "dbus-values.h" #include "dbus-exports.h" #define DBUS_CONNECTION_FROM_TYPE(type) \ ((type) == DBUS_BUS_SESSION ? session_bus : system_bus) SeedContext ctx; SeedContextGroup group; SeedObject namespace_ref; SeedClass dbus_namespace_class; SeedClass dbus_bus_class; static gboolean session_bus_weakref_added = FALSE; static DBusConnection* session_bus = NULL; static gboolean system_bus_weakref_added = FALSE; static DBusConnection* system_bus = NULL; SeedObject bus_proto; static DBusBusType get_bus_type_from_object(SeedContext ctx, SeedObject object, SeedException* exception) { SeedValue jsbus_type = seed_object_get_property(ctx, object, "_dbusBusType"); return seed_value_to_int(ctx, jsbus_type, exception); } static gboolean bus_check(SeedContext ctx, DBusBusType bus_type, SeedException* exception) { gboolean bus_weakref_added; DBusConnection** bus_connection; bus_weakref_added = bus_type == DBUS_BUS_SESSION ? session_bus_weakref_added : system_bus_weakref_added; bus_connection = bus_type == DBUS_BUS_SESSION ? &session_bus : &system_bus; /* This is all done lazily only if a dbus-related method is actually invoked */ if (!bus_weakref_added) { big_dbus_add_bus_weakref(bus_type, bus_connection); } if (*bus_connection == NULL) big_dbus_try_connecting_now( bus_type); /* force a synchronous connection attempt */ /* Throw exception if connection attempt failed */ if (*bus_connection == NULL) { const char* bus_type_name = bus_type == DBUS_BUS_SESSION ? "session" : "system"; seed_make_exception(ctx, exception, "BusError", "Not connected to %s message bus", bus_type_name); return FALSE; } return TRUE; } static DBusMessage* prepare_call(SeedContext ctx, SeedObject obj, SeedObject arg_array, guint argc, const SeedValue* argv, DBusBusType bus_type, SeedException* exception) { DBusMessage* message; const char* bus_name; const char* path; const char* interface; const char* method; gboolean auto_start; const char* out_signature; const char* in_signature; DBusMessageIter arg_iter; DBusSignatureIter sig_iter; if (!bus_check(ctx, bus_type, exception)) return NULL; bus_name = seed_value_to_string(ctx, argv[0], exception); if (bus_name == NULL) return NULL; path = seed_value_to_string(ctx, argv[1], exception); if (path == NULL) return NULL; if (seed_value_is_null(ctx, argv[2])) { interface = NULL; } else { interface = seed_value_to_string(ctx, argv[2], exception); if (interface == NULL) return NULL; /* exception was set */ } method = seed_value_to_string(ctx, argv[3], exception); if (method == NULL) return NULL; out_signature = seed_value_to_string(ctx, argv[4], exception); if (out_signature == NULL) return NULL; in_signature = seed_value_to_string(ctx, argv[5], exception); if (in_signature == NULL) return NULL; g_assert(bus_name && path && method && in_signature && out_signature); auto_start = seed_value_to_boolean(ctx, argv[6], exception); /* FIXME should validate the bus_name, path, interface, method really, but * we should just not write buggy JS ;-) */ message = dbus_message_new_method_call(bus_name, path, interface, method); if (message == NULL) { seed_make_exception(ctx, exception, "DBusError", "Could not create new method call. (OOM?)"); return NULL; } dbus_message_set_auto_start(message, auto_start); dbus_message_iter_init_append(message, &arg_iter); if (in_signature) dbus_signature_iter_init(&sig_iter, in_signature); else dbus_signature_iter_init(&sig_iter, "a{sv}"); if (!seed_js_values_to_dbus(ctx, 0, arg_array, &arg_iter, &sig_iter, exception)) { SEED_NOTE(MODULE, "Failed to marshal call from JS to dbus"); dbus_message_unref(message); return NULL; } return message; } static gboolean complete_call(SeedContext ctx, SeedValue* retval, DBusMessage* reply, DBusError* derror, SeedException* exception) { DBusMessageIter arg_iter; GArray* ret_values; int array_length; if (dbus_error_is_set(derror)) { SEED_NOTE(MODULE, "Error sending call: %s: %s", derror->name, derror->message); seed_make_exception(ctx, exception, "DBusError", "DBus error: %s: %s", derror->name, derror->message); dbus_error_free(derror); return FALSE; } if (reply == NULL) { SEED_NOTE(MODULE, "No reply received to call"); return FALSE; } if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) { dbus_set_error_from_message(derror, reply); seed_make_exception(ctx, exception, "DBusError", "DBus error: %s: %s", derror->name, derror->message); SEED_NOTE(MODULE, "DBus error: %s: %s", derror->name, derror->message); dbus_error_free(derror); return FALSE; } dbus_message_iter_init(reply, &arg_iter); if (!seed_js_values_from_dbus(ctx, &arg_iter, &ret_values, exception)) { SEED_NOTE(MODULE, "Failed to marshal dbus call reply back to JS"); return FALSE; } g_assert(ret_values != NULL); // TODO: I AM HERE array_length = ret_values->len; if (array_length == 1) { /* If the array only has one element return that element alone */ *retval = g_array_index(ret_values, SeedValue, 0); } else { /* Otherwise return an array with all the return values. The * funny assignment is to avoid creating a temporary JSObject * we'd need to root */ *retval = seed_make_array(ctx, ret_values->data, array_length, exception); } g_array_free(ret_values, TRUE); seed_js_add_dbus_props(ctx, reply, *retval, exception); return TRUE; } static void pending_notify(DBusPendingCall* pending, void* user_data) { SeedException exception = NULL; GClosure* closure; SeedValue argv[2]; DBusMessage* reply; DBusError derror; closure = user_data; SEED_NOTE(MODULE, "Notified of reply to async call closure %p", closure); if (closure == NULL) { SEED_NOTE(MODULE, "Closure destroyed before we could complete pending call"); return; } /* reply may be NULL if none received? I think it may never be if * we've already been notified, but be safe here. */ reply = dbus_pending_call_steal_reply(pending); dbus_error_init(&derror); /* argv[0] will be the return value if any, argv[1] we fill with exception * if any */ argv[0] = seed_make_null(ctx); argv[1] = seed_make_null(ctx); if (!complete_call(ctx, &argv[0], reply, &derror, &exception)) goto noreply; g_assert(!dbus_error_is_set( &derror)); /* not supposed to be left set by complete_call() */ if (reply) dbus_message_unref(reply); if (exception) argv[1] = exception; seed_closure_invoke(closure, &argv[0], 2, &exception); if (exception && seed_value_is_object(ctx, exception)) seed_closure_warn_exception(closure, ctx, exception); seed_context_unref(ctx); // TODO: Do something with exception return; noreply: SEED_NOTE(MODULE, "No reply recieved from complete_call"); if (reply) dbus_message_unref(reply); seed_context_unref(ctx); } static void pending_free_closure(void* data) { GClosure* closure = data; g_closure_invalidate(closure); g_closure_unref(closure); } static SeedValue seed_js_dbus_call_async(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { GClosure* closure; DBusMessage* message; DBusPendingCall* pending; DBusConnection* bus_connection; DBusBusType bus_type; int timeout; if (argument_count < 10) { seed_make_exception(ctx, exception, "ArgmuentError", "Not enough args, need bus name, " "object path, interface, method, " "out signature, in signature, " "autostart flag, timeout limit, " "args, and callback"); return seed_make_null(ctx); } if (!seed_value_is_object(ctx, arguments[9]) || !seed_value_is_function(ctx, arguments[9])) { seed_make_exception( ctx, exception, "ArgumentError", "arg 10 must be a callback to invoke when call completes"); return FALSE; } timeout = seed_value_to_int(ctx, arguments[7], exception); bus_type = get_bus_type_from_object(ctx, this_object, exception); message = prepare_call(ctx, this_object, arguments[8], argument_count, arguments, bus_type, exception); if (message == NULL) return seed_make_null(ctx); bus_connection = DBUS_CONNECTION_FROM_TYPE(bus_type); pending = NULL; if (!dbus_connection_send_with_reply(bus_connection, message, &pending, timeout) || pending == NULL) { SEED_NOTE(MODULE, "Failed to send async dbus message"); seed_make_exception(ctx, exception, "DBusError", "Failed to send dbus message"); dbus_message_unref(message); return seed_make_null(ctx); } g_assert(pending != NULL); dbus_message_unref(message); /* We cheat a bit here and use a closure to store a JavaScript function * and deal with the GC root and other issues, even though we * won't ever marshal via GValue */ closure = seed_closure_new(ctx, arguments[9], NULL, "async DBus reply"); if (closure == NULL) { dbus_pending_call_unref(pending); return seed_make_null(ctx); } g_closure_ref(closure); g_closure_sink(closure); dbus_pending_call_set_notify(pending, pending_notify, closure, pending_free_closure); dbus_pending_call_unref( pending); /* DBusConnection should still hold a ref until it's completed */ return seed_value_from_boolean(ctx, TRUE, exception); } static SeedValue seed_js_dbus_get_machine_id(SeedContext ctx, SeedObject object, SeedString property_name, SeedException* exception) { SeedValue ret; gchar* id; id = dbus_get_local_machine_id(); ret = seed_value_from_string(ctx, id, exception); dbus_free(id); return ret; } static void fill_with_null_or_string(SeedContext ctx, const char** string_p, SeedValue value, SeedException* exception) { if (seed_value_is_null(ctx, value)) *string_p = NULL; else *string_p = seed_value_to_string(ctx, value, exception); } typedef struct { int refcount; DBusBusType bus_type; int connection_id; GClosure* closure; } SignalHandler; /* allow removal by passing in the callable * FIXME don't think we ever end up using this, * could get rid of it, it predates having an ID * to remove by */ static GHashTable* signal_handlers_by_callable = NULL; static void signal_on_closure_invalidated(void* data, GClosure* closure); static void signal_handler_ref(SignalHandler* handler); static void signal_handler_unref(SignalHandler* handler); static SignalHandler* signal_handler_new(SeedContext ctx, SeedValue callable, SeedException* exception) { SignalHandler* handler; if (signal_handlers_by_callable && g_hash_table_lookup(signal_handlers_by_callable, callable) != NULL) { /* To fix this, get rid of signal_handlers_by_callable * and just require removal by id. Not sure we ever use * removal by callable anyway. */ seed_make_exception(ctx, exception, "ArgumentError", "For now, same callback cannot be " "the handler for two dbus signal " "connections"); return NULL; } handler = g_slice_new0(SignalHandler); handler->refcount = 1; /* We cheat a bit here and use a closure to store a JavaScript function * and deal with the GC root and other issues, even though we * won't ever marshal via GValue */ handler->closure = seed_closure_new(ctx, callable, NULL, "DBus signal handler"); if (handler->closure == NULL) { g_free(handler); return NULL; } g_closure_ref(handler->closure); g_closure_sink(handler->closure); g_closure_add_invalidate_notifier(handler->closure, handler, signal_on_closure_invalidated); if (!signal_handlers_by_callable) { signal_handlers_by_callable = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL); } /* We keep a weak reference on the closure in a table indexed * by the object, so we can retrieve it when removing the signal * watch. The signal_handlers_by_callable owns one ref to the SignalHandler. */ signal_handler_ref(handler); g_hash_table_replace(signal_handlers_by_callable, callable, handler); return handler; } static void signal_handler_ref(SignalHandler* handler) { g_assert(handler->refcount > 0); handler->refcount += 1; } static void signal_handler_dispose(SignalHandler* handler) { g_assert(handler->refcount > 0); signal_handler_ref(handler); if (handler->closure) { /* invalidating closure could dispose * re-entrantly, so set handler->closure * NULL before we invalidate */ GClosure* closure = handler->closure; handler->closure = NULL; g_hash_table_remove(signal_handlers_by_callable, seed_closure_get_callable(closure)); if (g_hash_table_size(signal_handlers_by_callable) == 0) { g_hash_table_destroy(signal_handlers_by_callable); signal_handlers_by_callable = NULL; } /* the hash table owned 1 ref */ signal_handler_unref(handler); g_closure_invalidate(closure); g_closure_unref(closure); } /* remove signal if it hasn't been */ if (handler->connection_id != 0) { int id = handler->connection_id; handler->connection_id = 0; /* this should clear another ref off the * handler by calling signal_on_watch_removed */ big_dbus_unwatch_signal_by_id(handler->bus_type, id); } signal_handler_unref(handler); } static void signal_handler_unref(SignalHandler* handler) { g_assert(handler->refcount > 0); if (handler->refcount == 1) { signal_handler_dispose(handler); } handler->refcount -= 1; if (handler->refcount == 0) { g_assert(handler->closure == NULL); g_assert(handler->connection_id == 0); g_slice_free(SignalHandler, handler); } } static void signal_on_watch_removed(void* data) { SignalHandler* handler = data; handler->connection_id = 0; /* don't re-remove it */ /* The watch owns a ref; removing it * also forces dispose, which invalidates * the closure if that hasn't been done. */ signal_handler_dispose(handler); signal_handler_unref(handler); } static void signal_on_closure_invalidated(void* data, GClosure* closure) { SignalHandler* handler; handler = data; /* this removes the watch if it has not been */ signal_handler_dispose(handler); } static void signal_handler_callback(DBusConnection* connection, DBusMessage* message, void* data) { SeedContext ctx; SignalHandler* handler; DBusMessageIter arg_iter; GArray* arguments; SeedException exception; SEED_NOTE(MODULE, "Signal handler called"); handler = data; if (handler->closure == NULL) { SEED_NOTE(MODULE, "dbus signal handler invalidated, ignoring"); return; } ctx = seed_context_create(group, NULL); seed_prepare_global_context(ctx); dbus_message_iter_init(message, &arg_iter); if (!seed_js_values_from_dbus(ctx, &arg_iter, &arguments, &exception)) { SEED_NOTE(MODULE, "Failed to marshal dbus signal to JS"); return; } signal_handler_ref( handler); /* for safety, in case handler removes itself */ g_assert(arguments != NULL); SEED_NOTE(MODULE, "Invoking closure on signal received, %d args", arguments->len); seed_closure_invoke_with_context(ctx, handler->closure, (SeedValue*) arguments->data, arguments->len, &exception); g_array_free(arguments, TRUE); signal_handler_unref(handler); /* for safety */ } static SeedValue seed_js_dbus_watch_signal(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { const char* bus_name; const char* object_path; const char* iface; const char* signal; SignalHandler* handler; int id; DBusBusType bus_type; if (argument_count < 5) { seed_make_exception(ctx, exception, "ArgumentError", "Not enough args, need bus name, " "object path, interface, signal and " "callback"); return seed_make_null(ctx); } if (!seed_value_is_object(ctx, arguments[4]) || !seed_value_is_function(ctx, arguments[4])) { seed_make_exception( ctx, exception, "ArgumentError", "arg 5 must be a callback to invoke when call completes"); return seed_make_null(ctx); } fill_with_null_or_string(ctx, &bus_name, arguments[0], exception); fill_with_null_or_string(ctx, &object_path, arguments[1], exception); fill_with_null_or_string(ctx, &iface, arguments[2], exception); fill_with_null_or_string(ctx, &signal, arguments[3], exception); bus_type = get_bus_type_from_object(ctx, this_object, exception); handler = signal_handler_new(ctx, arguments[4], exception); if (handler == NULL) return seed_make_null(ctx); id = big_dbus_watch_signal(bus_type, bus_name, object_path, iface, signal, signal_handler_callback, handler, signal_on_watch_removed); handler->bus_type = bus_type; handler->connection_id = id; /* signal_on_watch_removed() takes ownership of our * ref to the SignalHandler */ return seed_value_from_int(ctx, id, exception); } /* Args are handler id */ static SeedValue seed_js_dbus_unwatch_signal_by_id(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { int id; DBusBusType bus_type; if (argument_count < 1) { seed_make_exception(ctx, exception, "ArgumentError", "Not enough args, need handler id"); return seed_make_null(ctx); } bus_type = get_bus_type_from_object(ctx, this_object, exception); id = seed_value_to_int(ctx, arguments[0], exception); big_dbus_unwatch_signal_by_id(bus_type, id); return seed_make_undefined(ctx); } static SeedValue seed_js_dbus_unwatch_signal(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { const char* bus_name; const char* object_path; const char* iface; const char* signal; SignalHandler* handler; DBusBusType bus_type; if (argument_count < 5) { seed_make_exception(ctx, exception, "ArgumentError", "Not enough args, need bus name, " "object path, interface, signal and " "callback"); return seed_make_null(ctx); } bus_type = get_bus_type_from_object(ctx, this_object, exception); if (!seed_value_is_object(ctx, arguments[4]) || !seed_value_is_function(ctx, arguments[4])) { seed_make_exception( ctx, exception, "ArgumentError", "arg 5 must be a callback to invoke when call completes"); return seed_make_null(ctx); } fill_with_null_or_string(ctx, &bus_name, arguments[0], exception); fill_with_null_or_string(ctx, &object_path, arguments[1], exception); fill_with_null_or_string(ctx, &iface, arguments[2], exception); fill_with_null_or_string(ctx, &signal, arguments[3], exception); /* we don't complain if the signal seems to have been already removed * or to never have been watched, to match g_signal_handler_disconnect */ if (!signal_handlers_by_callable) return seed_make_undefined(ctx); handler = g_hash_table_lookup(signal_handlers_by_callable, arguments[4]); if (!handler) return seed_make_undefined(ctx); /* This should dispose the handler which should in turn * remove it from the handler table */ big_dbus_unwatch_signal(bus_type, bus_name, object_path, iface, signal, signal_handler_callback, handler); g_assert(g_hash_table_lookup(signal_handlers_by_callable, arguments[4]) == NULL); return seed_make_undefined(ctx); } static SeedValue seed_js_dbus_emit_signal(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { DBusConnection* bus_connection; DBusMessage* message; DBusMessageIter arg_iter; DBusSignatureIter sig_iter; const char* object_path; const char* iface; const char* signal; const char* in_signature; DBusBusType bus_type; if (argument_count < 4) { seed_make_exception(ctx, exception, "ArgumentError", "Not enough args, need object path, " "interface and signal and the " "arguments"); return seed_make_null(ctx); } if (!seed_value_is_object(ctx, arguments[4])) { seed_make_exception(ctx, exception, "ArgumentError", "5th argument should be an array of arguments"); return seed_make_null(ctx); } bus_type = get_bus_type_from_object(ctx, this_object, exception); object_path = seed_value_to_string(ctx, arguments[0], exception); iface = seed_value_to_string(ctx, arguments[1], exception); signal = seed_value_to_string(ctx, arguments[2], exception); in_signature = seed_value_to_string(ctx, arguments[3], exception); if (!bus_check(ctx, bus_type, exception)) return seed_make_null(ctx); SEED_NOTE(MODULE, "Emitting signal %s %s %s", object_path, iface, signal); bus_connection = DBUS_CONNECTION_FROM_TYPE(bus_type); message = dbus_message_new_signal(object_path, iface, signal); dbus_message_iter_init_append(message, &arg_iter); dbus_signature_iter_init(&sig_iter, in_signature); if (!seed_js_values_to_dbus(ctx, 0, arguments[4], &arg_iter, &sig_iter, exception)) { dbus_message_unref(message); return seed_make_null(ctx); } dbus_connection_send(bus_connection, message, NULL); dbus_message_unref(message); return seed_make_undefined(ctx); } static SeedValue seed_js_dbus_call(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { DBusMessage* message; DBusError derror; DBusMessage* reply; DBusConnection* bus_connection; DBusBusType bus_type; SeedValue retval = NULL; if (argument_count < 8) { seed_make_exception(ctx, exception, "ArgumentError", "Not enough args, need bus name, " "object path, interface, method, " "out signature, in signature, " "autostart flag, and args"); return seed_make_null(ctx); } bus_type = get_bus_type_from_object(ctx, this_object, exception); message = prepare_call(ctx, this_object, arguments[7], argument_count, arguments, bus_type, exception); bus_connection = DBUS_CONNECTION_FROM_TYPE(bus_type); /* send_with_reply_and_block() returns NULL if error was set. */ dbus_error_init(&derror); reply = dbus_connection_send_with_reply_and_block(bus_connection, message, -1, &derror); dbus_message_unref(message); complete_call(ctx, &retval, reply, &derror, exception); if (reply) dbus_message_unref(reply); return retval; } typedef struct { BigDBusNameOwnerFuncs funcs; GClosure* acquired_closure; GClosure* lost_closure; DBusBusType bus_type; } BigJSDBusNameOwner; static void on_name_acquired(DBusConnection* connection, const char* name, void* data) { int argc; SeedValue argv[1]; SeedContext ctx; BigJSDBusNameOwner* owner; SeedException exception; // TODO: Do something with this... owner = data; ctx = seed_context_create(group, NULL); seed_prepare_global_context(ctx); if (ctx == NULL) { SEED_NOTE(MODULE, "Closure destroyed before we could notify name acquired"); return; } argc = 1; argv[0] = seed_value_from_string(ctx, name, &exception); seed_closure_invoke_with_context(ctx, owner->acquired_closure, argv, argc, &exception); seed_context_unref(ctx); } static void on_name_lost(DBusConnection* connection, const char* name, void* data) { int argc; SeedValue argv[1]; SeedContext ctx; BigJSDBusNameOwner* owner; SeedException exception; // TODO: Do something with this... owner = data; ctx = seed_context_create(group, NULL); seed_prepare_global_context(ctx); if (ctx == NULL) { SEED_NOTE(MODULE, "Closure destroyed before we could notify name acquired"); return; } argc = 1; argv[0] = seed_value_from_string(ctx, name, &exception); seed_closure_invoke_with_context(ctx, owner->lost_closure, argv, argc, &exception); seed_context_unref(ctx); } static void owner_closure_invalidated(gpointer data, GClosure* closure) { BigJSDBusNameOwner* owner; owner = (BigJSDBusNameOwner*) data; if (owner) { big_dbus_release_name(owner->bus_type, &owner->funcs, owner); g_closure_unref(owner->acquired_closure); g_closure_unref(owner->lost_closure); g_slice_free(BigJSDBusNameOwner, owner); } } static SeedValue seed_js_dbus_acquire_name(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { const char* bus_name; SeedObject acquire_func; SeedObject lost_func; BigJSDBusNameOwner* owner; DBusBusType bus_type; BigDBusNameType name_type; unsigned int id; if (argument_count < 4) { seed_make_exception(ctx, exception, "ArgumentError", "Not enough args, need bus name, " "name type, acquired_func, " "lost_func"); return seed_make_null(ctx); } bus_type = get_bus_type_from_object(ctx, this_object, exception); bus_name = seed_value_to_string(ctx, arguments[0], exception); name_type = (BigDBusNameType) seed_value_to_int(ctx, arguments[1], exception); if (!seed_value_is_object(ctx, arguments[2]) || !seed_value_is_function(ctx, arguments[2])) { seed_make_exception( ctx, exception, "ArgumentError", "Third arg is a callback to invoke on acquiring the name"); return seed_make_null(ctx); } acquire_func = arguments[2]; if (!seed_value_is_object(ctx, arguments[3]) || !seed_value_is_function(ctx, arguments[3])) { seed_make_exception( ctx, exception, "ArgumentError", "Fourth arg is a callback to invoke on acquiring the name"); return seed_make_null(ctx); } lost_func = arguments[3]; owner = g_slice_new0(BigJSDBusNameOwner); owner->funcs.name = g_strdup(bus_name); owner->funcs.type = name_type; owner->funcs.acquired = on_name_acquired; owner->funcs.lost = on_name_lost; owner->bus_type = bus_type; owner->acquired_closure = seed_closure_new(ctx, acquire_func, NULL, "DBus name acquired handler"); g_closure_ref(owner->acquired_closure); g_closure_sink(owner->acquired_closure); owner->lost_closure = seed_closure_new(ctx, lost_func, NULL, "DBus name lost handler"); g_closure_ref(owner->lost_closure); g_closure_sink(owner->lost_closure); /* Only add the invalidate notifier to one of the closures, should * be enough */ g_closure_add_invalidate_notifier(owner->acquired_closure, owner, owner_closure_invalidated); id = big_dbus_acquire_name(bus_type, &owner->funcs, owner); return seed_value_from_int(ctx, id, exception); } static SeedValue seed_js_dbus_release_name_by_id(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { DBusBusType bus_type; unsigned int id; if (argument_count < 1) { seed_make_exception(ctx, exception, "ArgumentError", "Not enough args, need name owner monitor id"); return seed_make_null(ctx); } bus_type = get_bus_type_from_object(ctx, this_object, exception); id = seed_value_to_int(ctx, arguments[0], exception); big_dbus_release_name_by_id(bus_type, id); return seed_make_undefined(ctx); } typedef struct { GClosure* appeared_closure; GClosure* vanished_closure; char* bus_name; DBusBusType bus_type; } BigJSDBusNameWatcher; static void on_name_appeared(DBusConnection* connection, const char* name, const char* owner_unique_name, void* data) { int argc; SeedValue argv[2]; SeedContext ctx; BigJSDBusNameWatcher* watcher; SeedException exception; watcher = data; ctx = seed_context_create(group, NULL); seed_prepare_global_context(ctx); argc = 2; argv[0] = seed_value_from_string(ctx, name, &exception); argv[1] = seed_value_from_string(ctx, owner_unique_name, &exception); seed_closure_invoke_with_context(ctx, watcher->appeared_closure, argv, argc, &exception); // TODO: Do something with exception. seed_context_unref(ctx); } static void on_name_vanished(DBusConnection* connection, const char* name, const char* owner_unique_name, void* data) { int argc; SeedValue argv[2]; SeedContext ctx; BigJSDBusNameWatcher* watcher; SeedException exception; watcher = data; ctx = seed_context_create(group, NULL); seed_prepare_global_context(ctx); argc = 2; argv[0] = seed_value_from_string(ctx, name, &exception); argv[1] = seed_value_from_string(ctx, owner_unique_name, &exception); seed_closure_invoke_with_context(ctx, watcher->vanished_closure, argv, argc, &exception); // TODO: Do something with exception. seed_context_unref(ctx); } static const BigDBusWatchNameFuncs watch_name_funcs = { on_name_appeared, on_name_vanished }; static void watch_closure_invalidated(gpointer data, GClosure* closure) { BigJSDBusNameWatcher* watcher; watcher = (BigJSDBusNameWatcher*) data; if (watcher) { big_dbus_unwatch_name(watcher->bus_type, watcher->bus_name, &watch_name_funcs, watcher); g_free(watcher->bus_name); g_closure_unref(watcher->appeared_closure); g_closure_unref(watcher->vanished_closure); g_slice_free(BigJSDBusNameWatcher, watcher); } } static SeedValue seed_js_dbus_watch_name(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { const char* bus_name; gboolean start_if_not_found; SeedObject appeared_func; SeedObject vanished_func; BigJSDBusNameWatcher* watcher; DBusBusType bus_type; if (argument_count < 4) { seed_make_exception( ctx, exception, "ArgumentError", "Not enough args, need bus name, acquired_func, lost_func"); return seed_make_null(ctx); } bus_type = get_bus_type_from_object(ctx, this_object, exception); bus_name = seed_value_to_string(ctx, arguments[0], exception); start_if_not_found = seed_value_to_boolean(ctx, arguments[1], exception); if (!seed_value_is_object(ctx, arguments[2]) || !seed_value_is_function(ctx, arguments[2])) { seed_make_exception( ctx, exception, "ArgumentError", "Third arg is a callback to invoke on seeing the name"); return seed_make_null(ctx); } appeared_func = arguments[2]; if (!seed_value_is_object(ctx, arguments[3]) || !seed_value_is_function(ctx, arguments[3])) { seed_make_exception( ctx, exception, "ArgumentError", "Fourth arg is a callback to invoke on seeing the name"); return seed_make_null(ctx); } vanished_func = arguments[3]; watcher = g_slice_new0(BigJSDBusNameWatcher); watcher->appeared_closure = seed_closure_new(ctx, appeared_func, NULL, "DBus name appeared handler"); g_closure_ref(watcher->appeared_closure); g_closure_sink(watcher->appeared_closure); watcher->vanished_closure = seed_closure_new(ctx, vanished_func, NULL, "DBus name vanished handler"); g_closure_ref(watcher->vanished_closure); g_closure_sink(watcher->vanished_closure); watcher->bus_type = bus_type; watcher->bus_name = g_strdup(bus_name); /* Only add the invalidate notifier to one of the closures, should * be enough */ g_closure_add_invalidate_notifier(watcher->appeared_closure, watcher, watch_closure_invalidated); big_dbus_watch_name(bus_type, bus_name, start_if_not_found ? BIG_DBUS_NAME_START_IF_NOT_FOUND : 0, &watch_name_funcs, watcher); return seed_make_undefined(ctx); } static SeedValue unique_name_getter(SeedContext ctx, SeedObject object, SeedString property_name, SeedException* exception) { DBusConnection* bus_connection; DBusBusType bus_type; bus_type = get_bus_type_from_object(ctx, object, exception); bus_check(ctx, bus_type, exception); bus_connection = DBUS_CONNECTION_FROM_TYPE(bus_type); if (bus_connection == NULL) { return seed_make_null(ctx); } else { const gchar* unique_name; unique_name = dbus_bus_get_unique_name(bus_connection); return seed_value_from_string(ctx, unique_name, exception); } } static SeedValue seed_js_dbus_start_service(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { const char* name; DBusBusType bus_type; DBusConnection* bus_connection; if (argument_count != 1) { seed_make_exception(ctx, exception, "ArgumentError", "Wrong number of arguments, expected service name"); return seed_make_null(ctx); } name = seed_value_to_string(ctx, arguments[0], exception); bus_type = get_bus_type_from_object(ctx, this_object, exception); if (!bus_check(ctx, bus_type, exception)) return seed_make_null(ctx); bus_connection = DBUS_CONNECTION_FROM_TYPE(bus_type); big_dbus_start_service(bus_connection, name); return seed_make_undefined(ctx); } static SeedValue seed_js_dbus_signature_length(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { const gchar* signature; DBusSignatureIter iter; gint length = 0; if (argument_count < 1) { seed_make_exception(ctx, exception, "ArgumentError", "dbus.signatureLength expected 1 argument, got %zd", argument_count); return seed_make_null(ctx); } signature = seed_value_to_string(ctx, arguments[0], exception); if (!dbus_signature_validate(signature, NULL)) { seed_make_exception(ctx, exception, "ArgumentError", "Invalid signature"); return seed_make_null(ctx); } if (*signature == '\0') return seed_value_from_int(ctx, 0, exception); dbus_signature_iter_init(&iter, signature); do { length++; } while (dbus_signature_iter_next(&iter)); return seed_value_from_int(ctx, length, exception); } seed_static_value bus_values[] = { { "unique_name", unique_name_getter, NULL, 0 }, { NULL, NULL, NULL, 0 } }; seed_static_function bus_funcs[] = { { "call", seed_js_dbus_call, 0 }, { "call_async", seed_js_dbus_call_async, 0 }, { "acquire_name", seed_js_dbus_acquire_name, 0 }, { "release_name_by_id", seed_js_dbus_release_name_by_id, 0 }, { "watch_name", seed_js_dbus_watch_name, 0 }, { "watch_signal", seed_js_dbus_watch_signal, 0 }, { "unwatch_signal_by_id", seed_js_dbus_unwatch_signal_by_id, 0 }, { "unwatch_signal", seed_js_dbus_unwatch_signal, 0 }, { "emit_signal", seed_js_dbus_emit_signal, 0 }, { "start_service", seed_js_dbus_start_service, 0 }, { NULL, NULL, 0 } }; seed_static_function dbus_funcs[] = { { "signatureLength", seed_js_dbus_signature_length, 0 }, { NULL, NULL, 0 } }; seed_static_value dbus_values[] = { { "localMachineID", seed_js_dbus_get_machine_id, NULL, 0 }, { NULL, NULL, NULL, 0 } }; static void define_bus_object(SeedContext ctx, DBusBusType which_bus) { SeedObject bus_obj; const gchar* bus_name; bus_name = BIG_DBUS_NAME_FROM_TYPE(which_bus); bus_obj = seed_make_object(ctx, dbus_bus_class, NULL); seed_object_set_property(ctx, bus_obj, "_dbusBusType", seed_value_from_int(ctx, which_bus, NULL)); // TODO: Define exports seed_js_define_dbus_exports(ctx, bus_obj, which_bus); seed_object_set_property(ctx, namespace_ref, bus_name, bus_obj); } /*static void seed_define_bus_proto (SeedContext ctx) { bus_proto = seed_make_object (ctx, NULL, NULL); seed_value_protect (ctx, bus_proto); }*/ SeedObject seed_module_init(SeedEngine* eng) { seed_class_definition dbus_namespace_class_def = seed_empty_class; seed_class_definition dbus_bus_class_def = seed_empty_class; ctx = eng->context; group = eng->group; dbus_namespace_class_def.class_name = "dbusnative"; dbus_namespace_class_def.static_functions = dbus_funcs; dbus_namespace_class_def.static_values = dbus_values; dbus_bus_class_def.class_name = "dbusbus"; dbus_bus_class_def.static_functions = bus_funcs; dbus_bus_class_def.static_values = bus_values; dbus_namespace_class = seed_create_class(&dbus_namespace_class_def); dbus_bus_class = seed_create_class(&dbus_bus_class_def); namespace_ref = seed_make_object(eng->context, dbus_namespace_class, NULL); seed_object_set_property(ctx, namespace_ref, "BUS_SESSION", seed_value_from_int(ctx, DBUS_BUS_SESSION, NULL)); seed_object_set_property(ctx, namespace_ref, "BUS_SYSTEM", seed_value_from_int(ctx, DBUS_BUS_SYSTEM, NULL)); seed_object_set_property(ctx, namespace_ref, "BUS_STARTER", seed_value_from_int(ctx, DBUS_BUS_STARTER, NULL)); seed_create_function(ctx, "signatureLength", (SeedFunctionCallback) seed_js_dbus_signature_length, namespace_ref); define_bus_object(ctx, DBUS_BUS_SESSION); define_bus_object(ctx, DBUS_BUS_SYSTEM); return namespace_ref; } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/dbus/util/000077500000000000000000000000001303774616400222105ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/dbus/util/Makefile.am000066400000000000000000000001411303774616400242400ustar00rootroot00000000000000EXTRA_DIST = \ dbus.h \ dbus-private.h \ dbus-proxy.h \ log.h -include $(top_srcdir)/git.mk seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/dbus/util/dbus-private.h000066400000000000000000000034371303774616400247750ustar00rootroot00000000000000/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ /* Copyright 2008 litl, LLC. All Rights Reserved. */ #ifndef __BIG_UTIL_DBUS_PRIVATE_H__ #define __BIG_UTIL_DBUS_PRIVATE_H__ #include #include #include G_BEGIN_DECLS typedef struct { DBusBusType bus_type; void* where_connection_was; BigDBusProxy* driver_proxy; GHashTable* json_ifaces; GSList* name_ownership_monitors; GHashTable* name_watches; GSList* all_signal_watchers; /* These signal watcher tables are maps from a * string to a GSList of BigSignalWatcher, * and they are lazily created if a signal watcher * needs to be looked up by the given key. */ GHashTable* signal_watchers_by_unique_sender; GHashTable* signal_watchers_by_path; GHashTable* signal_watchers_by_iface; GHashTable* signal_watchers_by_signal; /* These are matching on well-known name only, * or watching all signals */ GSList* signal_watchers_in_no_table; } BigDBusInfo; BigDBusInfo* _big_dbus_ensure_info(DBusConnection* connection); void _big_dbus_dispose_info(DBusConnection* connection); void _big_dbus_process_pending_signal_watchers(DBusConnection* connection, BigDBusInfo* info); DBusHandlerResult _big_dbus_signal_watch_filter_message( DBusConnection* connection, DBusMessage* message, void* data); void _big_dbus_set_matching_name_owner_changed(DBusConnection* connection, const char* bus_name, gboolean matched); void _big_dbus_ensure_connect_idle(DBusBusType bus_type); DBusConnection* _big_dbus_get_weak_ref(DBusBusType which_bus); G_END_DECLS #endif /* __BIG_UTIL_DBUS_PRIVATE_H__ */ seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/dbus/util/dbus-proxy.c000066400000000000000000000432331303774616400244750ustar00rootroot00000000000000/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ /* Copyright 2008 litl, LLC. All Rights Reserved. */ #include #include "dbus-proxy.h" #include "dbus.h" #include "log.h" #include #include typedef enum { REPLY_CLOSURE_PLAIN, REPLY_CLOSURE_JSON } ReplyClosureType; typedef struct { BigDBusProxy* proxy; ReplyClosureType type; union { BigDBusProxyReplyFunc plain; BigDBusProxyJsonReplyFunc json; } func; BigDBusProxyErrorReplyFunc error_func; void* data; /* this is a debug thing; we want to guarantee * we call exactly 1 time either the reply or error * callback. */ guint reply_invoked : 1; guint error_invoked : 1; } ReplyClosure; static void big_dbus_proxy_dispose(GObject* object); static void big_dbus_proxy_finalize(GObject* object); static GObject* big_dbus_proxy_constructor( GType type, guint n_construct_properties, GObjectConstructParam* construct_params); static void big_dbus_proxy_get_property(GObject* object, guint prop_id, GValue* value, GParamSpec* pspec); static void big_dbus_proxy_set_property(GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec); struct _BigDBusProxy { GObject parent; DBusConnection* connection; char* bus_name; char* object_path; char* iface; }; struct _BigDBusProxyClass { GObjectClass parent; }; G_DEFINE_TYPE(BigDBusProxy, big_dbus_proxy, G_TYPE_OBJECT); #if 0 enum { LAST_SIGNAL }; static int signals[LAST_SIGNAL]; #endif enum { PROP_0, PROP_CONNECTION, PROP_BUS_NAME, PROP_OBJECT_PATH, PROP_INTERFACE }; static void big_dbus_proxy_init(BigDBusProxy* proxy) { } static void big_dbus_proxy_class_init(BigDBusProxyClass* klass) { GObjectClass* object_class = G_OBJECT_CLASS(klass); object_class->dispose = big_dbus_proxy_dispose; object_class->finalize = big_dbus_proxy_finalize; object_class->constructor = big_dbus_proxy_constructor; object_class->get_property = big_dbus_proxy_get_property; object_class->set_property = big_dbus_proxy_set_property; g_object_class_install_property( object_class, PROP_CONNECTION, g_param_spec_boxed("connection", "DBusConnection", "Our connection to the bus", DBUS_TYPE_CONNECTION, G_PARAM_READWRITE)); g_object_class_install_property( object_class, PROP_BUS_NAME, g_param_spec_string("bus-name", "Bus Name", "Name of app on the bus", NULL, G_PARAM_READWRITE)); g_object_class_install_property( object_class, PROP_OBJECT_PATH, g_param_spec_string("object-path", "Object Path", "Object's dbus path", NULL, G_PARAM_READWRITE)); g_object_class_install_property( object_class, PROP_INTERFACE, g_param_spec_string("interface", "Interface", "Interface to invoke methods on", NULL, G_PARAM_READWRITE)); } static void big_dbus_proxy_dispose(GObject* object) { BigDBusProxy* proxy; proxy = BIG_DBUS_PROXY(object); if (proxy->connection) { dbus_connection_unref(proxy->connection); proxy->connection = NULL; } if (proxy->bus_name) { g_free(proxy->bus_name); proxy->bus_name = NULL; } if (proxy->object_path) { g_free(proxy->object_path); proxy->object_path = NULL; } if (proxy->iface) { g_free(proxy->iface); proxy->iface = NULL; } G_OBJECT_CLASS(big_dbus_proxy_parent_class)->dispose(object); } static void big_dbus_proxy_finalize(GObject* object) { G_OBJECT_CLASS(big_dbus_proxy_parent_class)->finalize(object); } static GObject* big_dbus_proxy_constructor(GType type, guint n_construct_properties, GObjectConstructParam* construct_params) { GObject* object; BigDBusProxy* proxy; object = (*G_OBJECT_CLASS(big_dbus_proxy_parent_class) ->constructor)(type, n_construct_properties, construct_params); proxy = BIG_DBUS_PROXY(object); return object; } static void big_dbus_proxy_get_property(GObject* object, guint prop_id, GValue* value, GParamSpec* pspec) { BigDBusProxy* proxy; proxy = BIG_DBUS_PROXY(object); switch (prop_id) { case PROP_CONNECTION: g_value_set_boxed(value, proxy->connection); break; case PROP_BUS_NAME: g_value_set_string(value, proxy->bus_name); break; case PROP_OBJECT_PATH: g_value_set_string(value, proxy->object_path); break; case PROP_INTERFACE: g_value_set_string(value, proxy->iface); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; } } static void big_dbus_proxy_set_property(GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec) { BigDBusProxy* proxy; proxy = BIG_DBUS_PROXY(object); switch (prop_id) { case PROP_CONNECTION: if (proxy->connection != NULL) { g_warning( "Cannot change BigDBusProxy::connection after it's set"); return; } proxy->connection = dbus_connection_ref(g_value_get_boxed(value)); break; case PROP_BUS_NAME: if (proxy->bus_name != NULL) { g_warning( "Cannot change BigDBusProxy::bus-name after it's set"); return; } proxy->bus_name = g_value_dup_string(value); break; case PROP_OBJECT_PATH: if (proxy->object_path != NULL) { g_warning( "Cannot change BigDBusProxy::object-path after it's set"); return; } proxy->object_path = g_value_dup_string(value); break; case PROP_INTERFACE: if (proxy->iface != NULL) { g_warning( "Cannot change BigDBusProxy::interface after it's set"); return; } proxy->iface = g_value_dup_string(value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; } } /* bus_name can be NULL if not going through a bus, and * iface is allowed to be NULL but likely should not be. */ BigDBusProxy* big_dbus_proxy_new(DBusConnection* connection, const char* bus_name, const char* object_path, const char* iface) { BigDBusProxy* proxy; g_return_val_if_fail(connection != NULL, NULL); g_return_val_if_fail(object_path != NULL, NULL); proxy = g_object_new(BIG_TYPE_DBUS_PROXY, "connection", connection, "bus-name", bus_name, "object-path", object_path, "interface", iface, NULL); return proxy; } DBusConnection* big_dbus_proxy_get_connection(BigDBusProxy* proxy) { return proxy->connection; } const char* big_dbus_proxy_get_bus_name(BigDBusProxy* proxy) { return proxy->bus_name; } DBusMessage* big_dbus_proxy_new_method_call(BigDBusProxy* proxy, const char* method_name) { DBusMessage* message; message = dbus_message_new_method_call(proxy->bus_name, proxy->object_path, proxy->iface, method_name); if (message == NULL) g_error("no memory"); /* We don't want methods to auto-start services... if a service * needs starting or restarting, we want to do so explicitly so we * can do it in an orderly and predictable way. */ dbus_message_set_auto_start(message, FALSE); return message; } DBusMessage* big_dbus_proxy_new_json_call(BigDBusProxy* proxy, const char* method_name, DBusMessageIter* arg_iter, DBusMessageIter* dict_iter) { DBusMessage* message; message = big_dbus_proxy_new_method_call(proxy, method_name); dbus_message_iter_init_append(message, arg_iter); dbus_message_iter_open_container(arg_iter, DBUS_TYPE_ARRAY, "{sv}", dict_iter); return message; } static ReplyClosure* reply_closure_new(BigDBusProxy* proxy, BigDBusProxyReplyFunc plain_func, BigDBusProxyJsonReplyFunc json_func, BigDBusProxyErrorReplyFunc error_func, void* data) { ReplyClosure* c; c = g_slice_new0(ReplyClosure); c->proxy = g_object_ref(proxy); g_assert(!(plain_func && json_func)); if (plain_func != NULL) { c->type = REPLY_CLOSURE_PLAIN; c->func.plain = plain_func; } else { c->type = REPLY_CLOSURE_JSON; c->func.json = json_func; } c->error_func = error_func; c->data = data; return c; } static void reply_closure_free(ReplyClosure* c) { /* call exactly one of these */ g_assert(!(c->error_invoked && c->reply_invoked)); if (!(c->error_invoked || c->reply_invoked)) { c->error_invoked = TRUE; if (c->error_func) { (*c->error_func)(c->proxy, DBUS_ERROR_FAILED, "Pending call was freed (due to dbus_shutdown() " "probably) before it was ever notified", c->data); } } g_object_unref(c->proxy); g_slice_free(ReplyClosure, c); } static void reply_closure_invoke_error(ReplyClosure* c, DBusMessage* reply) { g_assert(dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR); g_assert(!c->reply_invoked); g_assert(!c->error_invoked); c->error_invoked = TRUE; if (c->error_func) { DBusError derror; dbus_error_init(&derror); dbus_set_error_from_message(&derror, reply); (*c->error_func)(c->proxy, derror.name, derror.message, c->data); dbus_error_free(&derror); } } static void reply_closure_invoke(ReplyClosure* c, DBusMessage* reply) { if (c->type == REPLY_CLOSURE_PLAIN) { if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_METHOD_RETURN) { g_assert(!c->reply_invoked); g_assert(!c->error_invoked); c->reply_invoked = TRUE; if (c->func.plain != NULL) { (*c->func.plain)(c->proxy, reply, c->data); } } else if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) { reply_closure_invoke_error(c, reply); } else { g_assert(!c->reply_invoked); g_assert(!c->error_invoked); c->error_invoked = TRUE; if (c->error_func) { (*c->error_func)(c->proxy, DBUS_ERROR_FAILED, "Got weird message type back as a reply", c->data); } } } else if (c->type == REPLY_CLOSURE_JSON) { if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_METHOD_RETURN) { if (dbus_message_has_signature(reply, "a{sv}")) { g_assert(!c->reply_invoked); g_assert(!c->error_invoked); c->reply_invoked = TRUE; if (c->func.json) { DBusMessageIter arg_iter; DBusMessageIter dict_iter; dbus_message_iter_init(reply, &arg_iter); dbus_message_iter_recurse(&arg_iter, &dict_iter); (*c->func.json)(c->proxy, reply, &dict_iter, c->data); } } else { g_assert(!c->reply_invoked); g_assert(!c->error_invoked); c->error_invoked = TRUE; if (c->error_func) { (*c->error_func)( c->proxy, DBUS_ERROR_FAILED, "Message we got back did not have the right signature", c->data); } } } else if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) { reply_closure_invoke_error(c, reply); } else { g_assert(!c->reply_invoked); g_assert(!c->error_invoked); c->error_invoked = TRUE; if (c->error_func) { (*c->error_func)(c->proxy, DBUS_ERROR_FAILED, "Got weird message type back as a reply", c->data); } } } else { g_assert_not_reached(); } } static gboolean failed_to_send_idle(void* data) { ReplyClosure* c; c = data; g_assert(!c->reply_invoked); g_assert(!c->error_invoked); c->error_invoked = TRUE; if (c->error_func) { (*c->error_func)(c->proxy, DBUS_ERROR_NO_MEMORY, "Unable to send method call", c->data); } reply_closure_free(c); return FALSE; } static void pending_call_notify(DBusPendingCall* pending, void* user_data) { DBusMessage* reply; ReplyClosure* c; big_debug(BIG_DEBUG_UTIL_DBUS, "BigDBusProxy received reply to pending call"); c = user_data; /* reply may be NULL if none received? I think it may never be if * we've already been notified, but be safe here. */ reply = dbus_pending_call_steal_reply(pending); if (reply) { reply_closure_invoke(c, reply); dbus_message_unref(reply); } else { /* I think libdbus won't let this happen, but to be safe... */ g_assert(!c->reply_invoked); g_assert(!c->error_invoked); c->error_invoked = TRUE; if (c->error_func) { (*c->error_func)(c->proxy, DBUS_ERROR_TIMED_OUT, "Did not receive a reply or error", c->data); } } /* The closure should be freed along with the pending call */ } static void pending_call_free_data(void* data) { ReplyClosure* c = data; reply_closure_free(c); } static void big_dbus_proxy_send_internal(BigDBusProxy* proxy, DBusMessage* message, BigDBusProxyReplyFunc plain_func, BigDBusProxyJsonReplyFunc json_func, BigDBusProxyErrorReplyFunc error_func, void* data) { ReplyClosure* c; DBusPendingCall* pending; if (!(plain_func || json_func || error_func)) { /* Fire and forget! */ big_debug(BIG_DEBUG_UTIL_DBUS, "Firing and forgetting dbus proxy call"); dbus_connection_send(proxy->connection, message, NULL); return; } big_debug(BIG_DEBUG_UTIL_DBUS, "Sending dbus proxy call %s", dbus_message_get_member(message)); c = reply_closure_new(proxy, plain_func, json_func, error_func, data); pending = NULL; if (!dbus_connection_send_with_reply(proxy->connection, message, &pending, -1) || pending == NULL) { big_debug(BIG_DEBUG_UTIL_DBUS, "Failed to send call, will report error in idle handler"); /* Send an error on return to main loop */ g_idle_add(failed_to_send_idle, c); return; } dbus_pending_call_set_notify(pending, pending_call_notify, c, pending_call_free_data); dbus_pending_call_unref( pending); /* DBusConnection should still hold a ref until it's completed */ } void big_dbus_proxy_send(BigDBusProxy* proxy, DBusMessage* message, BigDBusProxyReplyFunc reply_func, BigDBusProxyErrorReplyFunc error_func, void* data) { big_dbus_proxy_send_internal(proxy, message, reply_func, NULL, error_func, data); } static void append_entries_from_valist(DBusMessageIter* dict_iter, const char* first_key, va_list args) { const char* key; int dbus_type; void* value_p; key = first_key; dbus_type = va_arg(args, int); value_p = va_arg(args, void*); big_dbus_append_json_entry(dict_iter, key, dbus_type, value_p); key = va_arg(args, const char*); while (key != NULL) { dbus_type = va_arg(args, int); value_p = va_arg(args, void*); big_dbus_append_json_entry(dict_iter, key, dbus_type, value_p); key = va_arg(args, const char*); } } void big_dbus_proxy_call_json_async(BigDBusProxy* proxy, const char* method_name, BigDBusProxyJsonReplyFunc reply_func, BigDBusProxyErrorReplyFunc error_func, void* data, const char* first_key, ...) { DBusMessageIter arg_iter, dict_iter; DBusMessage* message; va_list args; message = big_dbus_proxy_new_json_call(proxy, method_name, &arg_iter, &dict_iter); if (first_key != NULL) { va_start(args, first_key); append_entries_from_valist(&dict_iter, first_key, args); va_end(args); } dbus_message_iter_close_container(&arg_iter, &dict_iter); big_dbus_proxy_send_internal(proxy, message, NULL, reply_func, error_func, data); dbus_message_unref(message); } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/dbus/util/dbus-proxy.h000066400000000000000000000067151303774616400245060ustar00rootroot00000000000000/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ /* Copyright 2008 litl, LLC. All Rights Reserved. */ #ifndef __BIG_UTIL_DBUS_PROXY_H__ #define __BIG_UTIL_DBUS_PROXY_H__ #include #include G_BEGIN_DECLS typedef struct _BigDBusProxy BigDBusProxy; typedef struct _BigDBusProxyClass BigDBusProxyClass; typedef void (*BigDBusProxyReplyFunc)(BigDBusProxy* proxy, DBusMessage* message, void* data); typedef void (*BigDBusProxyJsonReplyFunc)(BigDBusProxy* proxy, DBusMessage* message, DBusMessageIter* return_value_iter, void* data); typedef void (*BigDBusProxyErrorReplyFunc)(BigDBusProxy* proxy, const char* error_name, const char* error_message, void* data); #define BIG_TYPE_DBUS_PROXY (big_dbus_proxy_get_type()) #define BIG_DBUS_PROXY(object) \ (G_TYPE_CHECK_INSTANCE_CAST((object), BIG_TYPE_DBUS_PROXY, BigDBusProxy)) #define BIG_DBUS_PROXY_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST((klass), BIG_TYPE_DBUS_PROXY, BigDBusProxyClass)) #define BIG_IS_DBUS_PROXY(object) \ (G_TYPE_CHECK_INSTANCE_TYPE((object), BIG_TYPE_DBUS_PROXY)) #define BIG_IS_DBUS_PROXY_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE((klass), BIG_TYPE_DBUS_PROXY)) #define BIG_DBUS_PROXY_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS((obj), BIG_TYPE_DBUS_PROXY, BigDBusProxyClass)) GType big_dbus_proxy_get_type(void) G_GNUC_CONST; BigDBusProxy* big_dbus_proxy_new(DBusConnection* connection, const char* bus_name, const char* object_path, const char* iface); DBusConnection* big_dbus_proxy_get_connection(BigDBusProxy* proxy); const char* big_dbus_proxy_get_bus_name(BigDBusProxy* proxy); DBusMessage* big_dbus_proxy_new_method_call(BigDBusProxy* proxy, const char* method_name); DBusMessage* big_dbus_proxy_new_json_call(BigDBusProxy* proxy, const char* method_name, DBusMessageIter* arg_iter, DBusMessageIter* dict_iter); void big_dbus_proxy_send(BigDBusProxy* proxy, DBusMessage* message, BigDBusProxyReplyFunc reply_func, BigDBusProxyErrorReplyFunc error_func, void* data); /* varargs are like: * * key1, dbus_type_1, &value_1, * key2, dbus_type_2, &value_2, * NULL * * Basic types only (no arrays) */ void big_dbus_proxy_call_json_async(BigDBusProxy* proxy, const char* method_name, BigDBusProxyJsonReplyFunc reply_func, BigDBusProxyErrorReplyFunc error_func, void* data, const char* first_key, ...); G_END_DECLS #endif /* __BIG_UTIL_DBUS_PROXY_H__ */ seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/dbus/util/dbus-signals.c000066400000000000000000001025701303774616400247540ustar00rootroot00000000000000/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ /* Copyright 2008 litl, LLC. All Rights Reserved. */ #include #include "dbus-private.h" #include "log.h" #include #define INVALID_SIGNAL_ID (-1) typedef struct { DBusBusType bus_type; int refcount; char* sender; char* path; char* iface; char* name; BigDBusSignalHandler handler; void* data; GDestroyNotify data_dnotify; int id; unsigned int matching : 1; unsigned int destroyed : 1; } BigSignalWatcher; static GSList* pending_signal_watchers = NULL; static void signal_watcher_remove(DBusConnection* connection, BigDBusInfo* info, BigSignalWatcher* watcher); static int global_handler_id = 0; static BigSignalWatcher* signal_watcher_new(DBusBusType bus_type, const char* sender, const char* path, const char* iface, const char* name, BigDBusSignalHandler handler, void* data, GDestroyNotify data_dnotify) { BigSignalWatcher* watcher; watcher = g_slice_new0(BigSignalWatcher); watcher->refcount = 1; watcher->bus_type = bus_type; watcher->sender = g_strdup(sender); watcher->path = g_strdup(path); watcher->iface = g_strdup(iface); watcher->name = g_strdup(name); watcher->handler = handler; watcher->id = global_handler_id++; watcher->data = data; watcher->data_dnotify = data_dnotify; return watcher; } static void signal_watcher_dnotify(BigSignalWatcher* watcher) { if (watcher->data_dnotify != NULL) { (*watcher->data_dnotify)(watcher->data); watcher->data_dnotify = NULL; } watcher->destroyed = TRUE; } static void signal_watcher_ref(BigSignalWatcher* watcher) { watcher->refcount += 1; } static void signal_watcher_unref(BigSignalWatcher* watcher) { watcher->refcount -= 1; if (watcher->refcount == 0) { signal_watcher_dnotify(watcher); g_free(watcher->sender); g_free(watcher->path); g_free(watcher->iface); g_free(watcher->name); g_slice_free(BigSignalWatcher, watcher); } } static char* signal_watcher_build_match_rule(BigSignalWatcher* watcher) { GString* s; s = g_string_new("type='signal'"); if (watcher->sender) { g_string_append_printf(s, ",sender='%s'", watcher->sender); } if (watcher->path) { g_string_append_printf(s, ",path='%s'", watcher->path); } if (watcher->iface) { g_string_append_printf(s, ",interface='%s'", watcher->iface); } if (watcher->name) { g_string_append_printf(s, ",member='%s'", watcher->name); } return g_string_free(s, FALSE); } static GSList* signal_watcher_table_lookup(GHashTable* table, const char* key) { if (table == NULL) { return NULL; } return g_hash_table_lookup(table, key); } static void signal_watcher_list_free(void* data) { GSList* l = data; while (l != NULL) { GSList* next = l->next; signal_watcher_unref(l->data); g_slist_free_1(l); l = next; } } static void signal_watcher_table_add(GHashTable** table_p, const char* key, BigSignalWatcher* watcher) { GSList* list; char* original_key; if (*table_p == NULL) { list = NULL; original_key = g_strdup(key); *table_p = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, signal_watcher_list_free); } else { if (!g_hash_table_lookup_extended(*table_p, key, (gpointer*) &original_key, (gpointer*) &list)) { original_key = g_strdup(key); list = NULL; } } list = g_slist_prepend(list, watcher); signal_watcher_ref(watcher); g_hash_table_steal(*table_p, key); g_hash_table_insert(*table_p, original_key, list); } static void signal_watcher_table_remove(GHashTable* table, const char* key, BigSignalWatcher* watcher) { GSList* list; GSList* l; char* original_key; if (table == NULL) return; /* Never lazily-created the table, nothing ever added */ if (!g_hash_table_lookup_extended(table, key, (gpointer*) &original_key, (gpointer*) &list)) { return; } l = g_slist_find(list, watcher); if (!l) return; /* we don't want to unref if we weren't in this table */ list = g_slist_delete_link(list, l); g_hash_table_steal(table, key); if (list != NULL) { g_hash_table_insert(table, original_key, list); } else { g_free(original_key); } signal_watcher_unref(watcher); } static void signal_emitter_name_appeared(DBusConnection* connection, const char* name, const char* new_owner_unique_name, void* data) { /* We don't need to do anything here, we installed a name watch so * we could call big_dbus_get_watched_name_owner() to dispatch * signals, and to get destroy notification on unique names. */ } static void signal_emitter_name_vanished(DBusConnection* connection, const char* name, const char* old_owner_unique_name, void* data) { big_debug(BIG_DEBUG_UTIL_DBUS, "Signal emitter '%s' is now gone", name); /* If a watcher is matching on a unique name sender, once the unique * name goes away, the watcher can never see anything so nuke it. */ if (*name == ':') { GSList* list; BigDBusInfo* info; info = _big_dbus_ensure_info(connection); list = signal_watcher_table_lookup(info->signal_watchers_by_unique_sender, name); if (list == NULL) return; /* copy the list since we're about to remove stuff from it * in signal_watcher_remove */ list = g_slist_copy(list); while (list != NULL) { signal_watcher_remove(connection, info, list->data); list = g_slist_delete_link(list, list); } } } static BigDBusWatchNameFuncs signal_emitter_name_funcs = { signal_emitter_name_appeared, signal_emitter_name_vanished }; static void signal_watcher_set_matching(DBusConnection* connection, BigSignalWatcher* watcher, gboolean matching) { char* rule; if (watcher->matching == (matching != FALSE)) { return; } /* Never add match on a destroyed signal watcher */ if (watcher->destroyed && matching) return; /* We can't affect match rules if not connected */ if (!dbus_connection_get_is_connected(connection)) { return; } watcher->matching = matching != FALSE; rule = signal_watcher_build_match_rule(watcher); if (matching) dbus_bus_add_match(connection, rule, NULL); /* asking for error would make this block */ else dbus_bus_remove_match(connection, rule, NULL); g_free(rule); if (watcher->sender) { /* If the signal is from a well-known name, we have to add * a name watch to know who owns that name. * * If the signal is from a unique name, we want to destroy * the watcher if the unique name goes away */ if (matching) { big_dbus_watch_name(watcher->bus_type, watcher->sender, 0, &signal_emitter_name_funcs, NULL); } else { big_dbus_unwatch_name(watcher->bus_type, watcher->sender, &signal_emitter_name_funcs, NULL); } } } static void signal_watcher_add(DBusConnection* connection, BigDBusInfo* info, BigSignalWatcher* watcher) { gboolean in_some_table; signal_watcher_set_matching(connection, watcher, TRUE); info->all_signal_watchers = g_slist_prepend(info->all_signal_watchers, watcher); signal_watcher_ref(watcher); in_some_table = FALSE; if (watcher->sender && *(watcher->sender) == ':') { signal_watcher_table_add(&info->signal_watchers_by_unique_sender, watcher->sender, watcher); in_some_table = TRUE; } if (watcher->path) { signal_watcher_table_add(&info->signal_watchers_by_path, watcher->path, watcher); in_some_table = TRUE; } if (watcher->iface) { signal_watcher_table_add(&info->signal_watchers_by_iface, watcher->iface, watcher); in_some_table = TRUE; } if (watcher->name) { signal_watcher_table_add(&info->signal_watchers_by_signal, watcher->name, watcher); in_some_table = TRUE; } if (!in_some_table) { info->signal_watchers_in_no_table = g_slist_prepend(info->signal_watchers_in_no_table, watcher); signal_watcher_ref(watcher); } } static void signal_watcher_remove(DBusConnection* connection, BigDBusInfo* info, BigSignalWatcher* watcher) { gboolean in_some_table; signal_watcher_set_matching(connection, watcher, FALSE); info->all_signal_watchers = g_slist_remove(info->all_signal_watchers, watcher); in_some_table = FALSE; if (watcher->sender && *(watcher->sender) == ':') { signal_watcher_table_remove(info->signal_watchers_by_unique_sender, watcher->sender, watcher); in_some_table = TRUE; } if (watcher->path) { signal_watcher_table_remove(info->signal_watchers_by_path, watcher->path, watcher); in_some_table = TRUE; } if (watcher->iface) { signal_watcher_table_remove(info->signal_watchers_by_iface, watcher->iface, watcher); in_some_table = TRUE; } if (watcher->name) { signal_watcher_table_remove(info->signal_watchers_by_signal, watcher->name, watcher); in_some_table = TRUE; } if (!in_some_table) { info->signal_watchers_in_no_table = g_slist_remove(info->signal_watchers_in_no_table, watcher); signal_watcher_unref(watcher); } /* Destroy-notify before dropping last ref for a little more safety * (avoids "resurrection" issues), and to ensure we call the destroy * notifier even if we don't finish finalizing just yet. */ signal_watcher_dnotify(watcher); signal_watcher_unref(watcher); } /* This is called before we notify the app that the connection is open, * to add match rules. It must add the match rules, but MUST NOT * invoke application callbacks since the "connection opened" * callback needs to be first. */ void _big_dbus_process_pending_signal_watchers(DBusConnection* connection, BigDBusInfo* info) { GSList* remaining; remaining = NULL; while (pending_signal_watchers) { BigSignalWatcher* watcher = pending_signal_watchers->data; pending_signal_watchers = g_slist_delete_link(pending_signal_watchers, pending_signal_watchers); if (watcher->bus_type == info->bus_type) { /* Transfer to the non-pending BigDBusInfo */ signal_watcher_add(connection, info, watcher); signal_watcher_unref(watcher); } else { remaining = g_slist_prepend(remaining, watcher); } } /* keep the order deterministic by reversing, though I don't know * of a reason it matters. */ pending_signal_watchers = g_slist_reverse(remaining); } static void signal_watchers_disconnected(DBusConnection* connection, BigDBusInfo* info) { /* None should be pending on this bus, because at start of * _big_dbus_signal_watch_filter_message() we process all the pending ones. * However there could be stuff in pending_signal_watchers for * another bus. Anyway bottom line we can ignore pending_signal_watchers * in here. */ GSList* list; GSList* destroyed; /* Build a separate list to destroy to avoid re-entrancy as we are * walking the list */ destroyed = NULL; for (list = info->all_signal_watchers; list != NULL; list = list->next) { BigSignalWatcher* watcher = list->data; if (watcher->sender && *(watcher->sender) == ':') { destroyed = g_slist_prepend(destroyed, watcher); signal_watcher_ref(watcher); } } while (destroyed != NULL) { BigSignalWatcher* watcher = destroyed->data; destroyed = g_slist_delete_link(destroyed, destroyed); signal_watcher_remove(connection, info, watcher); signal_watcher_unref(watcher); } } static void concat_candidates(GSList** candidates_p, GHashTable* table, const char* key) { GSList* list; list = signal_watcher_table_lookup(table, key); if (list == NULL) return; *candidates_p = g_slist_concat(*candidates_p, g_slist_copy(list)); } static int direct_cmp(gconstpointer a, gconstpointer b) { /* gcc dislikes pointer math on void* so cast */ return ((const char*) a) - ((const char*) b); } static gboolean signal_watcher_watches(BigDBusInfo* info, BigSignalWatcher* watcher, const char* sender, const char* path, const char* iface, const char* name) { if (watcher->path && strcmp(watcher->path, path) != 0) return FALSE; if (watcher->iface && strcmp(watcher->iface, iface) != 0) return FALSE; if (watcher->name && strcmp(watcher->name, name) != 0) return FALSE; /* "sender" from message is always the unique name, but * watcher may or may not be. */ if (watcher->sender == NULL) return TRUE; if (*(watcher->sender) == ':') { return strcmp(watcher->sender, sender) == 0; } else { const char* owner; owner = big_dbus_get_watched_name_owner(info->bus_type, watcher->sender); if (owner != NULL && strcmp(sender, owner) == 0) return TRUE; else return FALSE; } } DBusHandlerResult _big_dbus_signal_watch_filter_message(DBusConnection* connection, DBusMessage* message, void* data) { /* Two things we're looking for * 1) signals * 2) if the sender of a signal watcher is a unique name, * we want to destroy notify when it vanishes or * when the bus disconnects. */ BigDBusInfo* info; const char* sender; const char* path; const char* iface; const char* name; GSList* candidates; BigSignalWatcher* previous; info = _big_dbus_ensure_info(connection); /* Be sure they are all in the lookup tables */ _big_dbus_process_pending_signal_watchers(connection, info); if (dbus_message_get_type(message) != DBUS_MESSAGE_TYPE_SIGNAL) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; sender = dbus_message_get_sender(message); path = dbus_message_get_path(message); iface = dbus_message_get_interface(message); name = dbus_message_get_member(message); /* libdbus requires path, iface, name. The bus daemon * will always set a sender but some locally-generated * messages (e.g. disconnected) may not have one. */ g_assert(path != NULL); g_assert(iface != NULL); g_assert(name != NULL); big_debug(BIG_DEBUG_UTIL_DBUS, "Signal from %s %s.%s sender %s", path, iface, name, sender ? sender : "(none)"); candidates = NULL; if (sender != NULL) { concat_candidates(&candidates, info->signal_watchers_by_unique_sender, sender); } concat_candidates(&candidates, info->signal_watchers_by_path, path); concat_candidates(&candidates, info->signal_watchers_by_iface, iface); concat_candidates(&candidates, info->signal_watchers_by_signal, name); candidates = g_slist_concat(candidates, g_slist_copy(info->signal_watchers_in_no_table)); /* Sort so we can find dups */ candidates = g_slist_sort(candidates, direct_cmp); previous = NULL; while (candidates != NULL) { BigSignalWatcher* watcher; watcher = candidates->data; candidates = g_slist_delete_link(candidates, candidates); if (previous == watcher) continue; /* watcher was in more than one table */ previous = watcher; if (!signal_watcher_watches(info, watcher, sender, path, iface, name)) continue; /* destroyed would happen if e.g. removed while we are going * through here. */ if (watcher->destroyed) continue; /* Invoke the watcher */ signal_watcher_ref(watcher); (*watcher->handler)(connection, message, watcher->data); signal_watcher_unref(watcher); } /* Note that signal watchers can also listen to the disconnected * signal, so we do our special handling of it last */ if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) { big_debug(BIG_DEBUG_UTIL_DBUS, "Disconnected in %s", G_STRFUNC); signal_watchers_disconnected(connection, info); } return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } int big_dbus_watch_signal(DBusBusType bus_type, const char* sender, const char* path, const char* iface, const char* name, BigDBusSignalHandler handler, void* data, GDestroyNotify data_dnotify) { BigSignalWatcher* watcher; DBusConnection* weak; watcher = signal_watcher_new(bus_type, sender, path, iface, name, handler, data, data_dnotify); /* If we're already connected, it's essential to get the * match rule added right away. Otherwise the race-free pattern * is not possible: * 1. Add match rule to monitor state of remote object * 2. Get current state of remote object * * Using the pending_signal_watchers codepath, there's no * notification when the match rule is added so you can't * be sure you get current state *after* that. * * Since we add our match rule here immediately if connected, * then apps can rely on first watching the signal, then * getting current state. * * In the connect idle, we process pending signal watchers * before calling any other app callbacks, so if someone * gets current state on connect, that will be after * all their match rules are added. */ weak = _big_dbus_get_weak_ref(bus_type); if (weak != NULL) { signal_watcher_add(weak, _big_dbus_ensure_info(weak), watcher); signal_watcher_unref(watcher); } else { pending_signal_watchers = g_slist_prepend(pending_signal_watchers, watcher); _big_dbus_ensure_connect_idle(bus_type); } return watcher->id; } /* Does the watcher match a removal request? */ static gboolean signal_watcher_matches(BigSignalWatcher* watcher, DBusBusType bus_type, const char* sender, const char* path, const char* iface, const char* name, int id, BigDBusSignalHandler handler, void* data) { /* If we have an ID, check that first. If it matches, we are * done */ if (id != INVALID_SIGNAL_ID && watcher->id == id) return TRUE; /* Start with data, most likely thing to not match */ if (watcher->data != data) return FALSE; /* Second most likely non-match */ if (watcher->handler != handler) return FALSE; /* Then third, do the more expensive checks */ if (watcher->bus_type != bus_type) return FALSE; if (g_strcmp0(watcher->sender, sender) != 0) return FALSE; if (g_strcmp0(watcher->path, path) != 0) return FALSE; if (g_strcmp0(watcher->iface, iface) != 0) return FALSE; if (g_strcmp0(watcher->name, name) != 0) return FALSE; return TRUE; } static void unwatch_signal(DBusBusType bus_type, const char* sender, const char* path, const char* iface, const char* name, int id, BigDBusSignalHandler handler, void* data) { GSList* list; DBusConnection* weak; BigDBusInfo* info; /* Always remove only ONE watcher (the first one we find) */ weak = _big_dbus_get_weak_ref(bus_type); /* First see if it's still pending */ for (list = pending_signal_watchers; list != NULL; list = list->next) { if (signal_watcher_matches(list->data, bus_type, sender, path, iface, name, id, handler, data)) { BigSignalWatcher* watcher = list->data; pending_signal_watchers = g_slist_remove_link(pending_signal_watchers, list); if (weak != NULL) signal_watcher_set_matching(weak, watcher, FALSE); signal_watcher_dnotify( watcher); /* destroy even if we don't finalize */ signal_watcher_unref(watcher); return; } } /* If not pending, and no bus connection, it can't exist */ if (weak == NULL) { /* don't warn on nonexistent, since a vanishing bus name could * have nuked it outside the app's control. */ return; } info = _big_dbus_ensure_info(weak); for (list = info->all_signal_watchers; list != NULL; list = list->next) { if (signal_watcher_matches(list->data, bus_type, sender, path, iface, name, id, handler, data)) { signal_watcher_remove(weak, info, list->data); /* note that "list" node is now invalid */ return; } } /* don't warn on nonexistent, since a vanishing bus name could * have nuked it outside the app's control. Just do nothing. */ } void big_dbus_unwatch_signal(DBusBusType bus_type, const char* sender, const char* path, const char* iface, const char* name, BigDBusSignalHandler handler, void* data) { unwatch_signal(bus_type, sender, path, iface, name, INVALID_SIGNAL_ID, handler, data); } void big_dbus_unwatch_signal_by_id(DBusBusType bus_type, int id) { unwatch_signal(bus_type, NULL, NULL, NULL, NULL, id, (BigDBusSignalHandler) NULL, NULL); } #if BIG_BUILD_TESTS #include "dbus-proxy.h" #include #include #include #include #include #include #include static pid_t test_service_pid = 0; static BigDBusProxy* test_service_proxy = NULL; static GMainLoop* outer_loop = NULL; static GMainLoop* inner_loop = NULL; static int n_running_children = 0; typedef struct { const char* sender; const char* path; const char* iface; const char* member; } SignalWatchTest; static SignalWatchTest watch_tests[] = { { NULL, NULL, NULL, NULL }, { "com.litl.TestService", NULL, NULL, NULL }, { NULL, "/com/litl/test/object42", NULL, NULL }, { NULL, NULL, "com.litl.TestIface", NULL }, { NULL, NULL, NULL, "TheSignal" } }; static void do_test_service_child(void); /* quit when all children are gone */ static void another_child_down(void) { g_assert(n_running_children > 0); n_running_children -= 1; if (n_running_children == 0) { g_main_loop_quit(outer_loop); } } /* This test function doesn't really test anything, just sets up * for the following one */ static void fork_test_signal_service(void) { pid_t child_pid; /* it would break to fork after we already connected */ g_assert(_big_dbus_get_weak_ref(DBUS_BUS_SESSION) == NULL); g_assert(_big_dbus_get_weak_ref(DBUS_BUS_SYSTEM) == NULL); g_assert(test_service_pid == 0); child_pid = fork(); if (child_pid == -1) { g_error("Failed to fork dbus service"); } else if (child_pid > 0) { /* We are the parent */ test_service_pid = child_pid; n_running_children += 1; return; } /* we are the child, set up a service for main test process to talk to */ do_test_service_child(); } static void kill_child(void) { if (kill(test_service_pid, SIGTERM) < 0) { g_error("Test service was no longer around... it must have failed " "somehow (%s)", strerror(errno)); } /* We will quit main loop when we see the child go away */ } static int signal_received_count = 0; static int destroy_notify_count = 0; static void the_destroy_notifier(void* data) { big_debug(BIG_DEBUG_IN_TESTS, "got destroy notification on signal watch"); destroy_notify_count += 1; } static void the_destroy_notifier_that_quits(void* data) { the_destroy_notifier(data); g_main_loop_quit(inner_loop); } static void expect_receive_signal_handler(DBusConnection* connection, DBusMessage* message, void* data) { big_debug(BIG_DEBUG_IN_TESTS, "dbus signal watch handler called"); g_assert( dbus_message_is_signal(message, "com.litl.TestIface", "TheSignal")); signal_received_count += 1; g_main_loop_quit(inner_loop); } static void test_match_combo(const char* sender, const char* path, const char* iface, const char* member) { signal_received_count = 0; destroy_notify_count = 0; big_debug(BIG_DEBUG_IN_TESTS, "Watching %s %s %s %s", sender, path, iface, member); big_dbus_watch_signal(DBUS_BUS_SESSION, sender, path, iface, member, expect_receive_signal_handler, GINT_TO_POINTER(1), the_destroy_notifier); big_dbus_proxy_call_json_async(test_service_proxy, "emitTheSignal", NULL, NULL, NULL, NULL); g_main_loop_run(inner_loop); g_assert(signal_received_count == 1); g_assert(destroy_notify_count == 0); big_dbus_unwatch_signal(DBUS_BUS_SESSION, sender, path, iface, member, expect_receive_signal_handler, GINT_TO_POINTER(1)); g_assert(destroy_notify_count == 1); } static gboolean run_signal_tests_idle(void* data) { int i; const char* unique_name; for (i = 0; i < (int) G_N_ELEMENTS(watch_tests); ++i) { SignalWatchTest* test = &watch_tests[i]; test_match_combo(test->sender, test->path, test->iface, test->member); } /* Now try on the unique bus name */ unique_name = big_dbus_proxy_get_bus_name(test_service_proxy); test_match_combo(unique_name, NULL, NULL, NULL); /* Now test we get destroy notify when the unique name disappears * on killing the child. */ signal_received_count = 0; destroy_notify_count = 0; big_debug(BIG_DEBUG_IN_TESTS, "Watching unique name %s", unique_name); big_dbus_watch_signal(DBUS_BUS_SESSION, unique_name, NULL, NULL, NULL, expect_receive_signal_handler, GINT_TO_POINTER(1), the_destroy_notifier_that_quits); /* kill owner of unique_name */ kill_child(); /* wait for destroy notify */ g_main_loop_run(inner_loop); g_assert(signal_received_count == 0); /* roundabout way to write == 1 that gives more info on fail */ g_assert(destroy_notify_count > 0); g_assert(destroy_notify_count < 2); big_dbus_unwatch_signal(DBUS_BUS_SESSION, unique_name, NULL, NULL, NULL, expect_receive_signal_handler, GINT_TO_POINTER(1)); g_assert(signal_received_count == 0); g_assert(destroy_notify_count == 1); /* remove idle */ return FALSE; } static void on_test_service_appeared(DBusConnection* connection, const char* name, const char* new_owner_unique_name, void* data) { big_debug(BIG_DEBUG_IN_TESTS, "%s appeared", name); inner_loop = g_main_loop_new(NULL, FALSE); test_service_proxy = big_dbus_proxy_new(connection, new_owner_unique_name, "/com/litl/test/object42", "com.litl.TestIface"); g_idle_add(run_signal_tests_idle, NULL); } static void on_test_service_vanished(DBusConnection* connection, const char* name, const char* old_owner_unique_name, void* data) { big_debug(BIG_DEBUG_IN_TESTS, "%s vanished", name); another_child_down(); } static BigDBusWatchNameFuncs watch_test_service_funcs = { on_test_service_appeared, on_test_service_vanished }; void bigtest_test_func_util_dbus_signals_client(void) { pid_t result; int status; /* See comment in dbus.c above the g_test_trap_fork() * there on why we have to do this. */ if (!g_test_trap_fork(0, 0)) { /* We are the parent */ g_test_trap_assert_passed(); return; } /* All this code runs in a child process */ fork_test_signal_service(); g_type_init(); /* We rely on the child-forking test functions being called first */ g_assert(test_service_pid != 0); big_dbus_watch_name(DBUS_BUS_SESSION, "com.litl.TestService", 0, &watch_test_service_funcs, NULL); outer_loop = g_main_loop_new(NULL, FALSE); g_main_loop_run(outer_loop); if (test_service_proxy != NULL) g_object_unref(test_service_proxy); big_debug(BIG_DEBUG_IN_TESTS, "waitpid() for first child"); result = waitpid(test_service_pid, &status, 0); if (result < 0) { g_error("Failed to waitpid() for forked child: %s", strerror(errno)); } if (WIFEXITED(status) && WEXITSTATUS(status) != 0) { g_error("Forked dbus service child exited with error code %d", WEXITSTATUS(status)); } if (WIFSIGNALED(status) && WTERMSIG(status) != SIGTERM) { g_error("Forked dbus service child exited on wrong signal number %d", WTERMSIG(status)); } big_debug(BIG_DEBUG_IN_TESTS, "dbus signals test completed"); /* We want to kill dbus so the weak refs are NULL to start the * next dbus-related test, which allows those tests * to fork new child processes. */ _big_dbus_dispose_info(_big_dbus_get_weak_ref(DBUS_BUS_SESSION)); dbus_shutdown(); big_debug(BIG_DEBUG_IN_TESTS, "dbus shut down"); /* FIXME this is only here because we've forked */ exit(0); } /* * Child service that emits signals */ static gboolean currently_have_test_service = FALSE; static GObject* test_service_object = NULL; static void test_service_emit_the_signal(DBusConnection* connection, DBusMessage* message, DBusMessageIter* in_iter, DBusMessageIter* out_iter, void* data, DBusError* error) { DBusMessage* signal; signal = dbus_message_new_signal("/com/litl/test/object42", "com.litl.TestIface", "TheSignal"); dbus_connection_send(connection, signal, NULL); dbus_message_unref(signal); } static BigDBusJsonMethod test_service_methods[] = { { "emitTheSignal", test_service_emit_the_signal, NULL } }; static void on_test_service_acquired(DBusConnection* connection, const char* name, void* data) { g_assert(!currently_have_test_service); currently_have_test_service = TRUE; big_debug(BIG_DEBUG_IN_TESTS, "com.litl.TestService acquired by child"); big_dbus_register_json(connection, "com.litl.TestIface", test_service_methods, G_N_ELEMENTS(test_service_methods)); test_service_object = g_object_new(G_TYPE_OBJECT, NULL); big_dbus_register_g_object(connection, "/com/litl/test/object42", test_service_object, "com.litl.TestIface"); } static void on_test_service_lost(DBusConnection* connection, const char* name, void* data) { g_assert(currently_have_test_service); currently_have_test_service = FALSE; big_debug(BIG_DEBUG_IN_TESTS, "com.litl.TestService lost by child"); big_dbus_unregister_g_object(connection, "/com/litl/test/object42"); big_dbus_unregister_json(connection, "com.litl.TestIface"); } static BigDBusNameOwnerFuncs test_service_funcs = { "com.litl.TestService", DBUS_BUS_SESSION, on_test_service_acquired, on_test_service_lost }; static void do_test_service_child(void) { GMainLoop* loop; g_type_init(); loop = g_main_loop_new(NULL, FALSE); big_dbus_acquire_name(DBUS_BUS_SESSION, &test_service_funcs, NULL); g_main_loop_run(loop); /* Don't return to the test program main() */ exit(0); } #endif /* BIG_BUILD_TESTS */ seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/dbus/util/dbus.c000066400000000000000000002541721303774616400233240ustar00rootroot00000000000000/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ /* Copyright 2008 litl, LLC. All Rights Reserved. */ #include #include "dbus.h" #include #include #include #include #include "dbus-private.h" #include "dbus-proxy.h" #include "log.h" #include "glib.h" typedef struct { const BigDBusConnectFuncs* funcs; void* data; unsigned int opened : 1; } ConnectFuncs; typedef enum { NAME_NOT_REQUESTED, NAME_PRIMARY_OWNER, NAME_IN_QUEUE, NAME_NOT_OWNED } NameOwnershipState; typedef struct { char* name; const BigDBusJsonMethod* methods; int n_methods; } BigJsonIface; typedef struct { DBusBusType bus_type; /* If prev_state != state then we may need to notify */ NameOwnershipState prev_state; NameOwnershipState state; const BigDBusNameOwnerFuncs* funcs; void* data; unsigned int id; } BigNameOwnershipMonitor; typedef struct { char* name; char* current_owner; GSList* watchers; } BigNameWatch; typedef struct { BigDBusWatchNameFlags flags; const BigDBusWatchNameFuncs* funcs; void* data; DBusBusType bus_type; BigNameWatch* watch; guint notify_idle; int refcount; guint destroyed : 1; } BigNameWatcher; typedef struct { DBusBusType bus_type; char* name; BigNameWatcher* watcher; } BigPendingNameWatcher; static DBusConnection* session_bus_weak_ref = NULL; static GSList* session_bus_weak_refs = NULL; static DBusConnection* system_bus_weak_ref = NULL; static GSList* system_bus_weak_refs = NULL; static guint session_connect_idle_id = 0; static guint system_connect_idle_id = 0; static GSList* all_connect_funcs = NULL; static GSList* pending_name_ownership_monitors = NULL; static GSList* pending_name_watchers = NULL; #define BIG_DBUS_NAME_OWNER_MONITOR_INVALID_ID 0 static unsigned int global_monitor_id = 0; static DBusHandlerResult disconnect_filter_message(DBusConnection* connection, DBusMessage* message, void* data); static DBusHandlerResult name_ownership_monitor_filter_message( DBusConnection* connection, DBusMessage* message, void* data); static void process_name_ownership_monitors(DBusConnection* connection, BigDBusInfo* info); static void name_watch_remove_watcher(BigNameWatch* watch, BigNameWatcher* watcher); static DBusHandlerResult name_watch_filter_message(DBusConnection* connection, DBusMessage* message, void* data); static void process_pending_name_watchers(DBusConnection* connection, BigDBusInfo* info); static void json_iface_free(BigJsonIface* iface); static void info_free(BigDBusInfo* info); static gboolean notify_watcher_name_appeared(gpointer data); static dbus_int32_t info_slot = -1; BigDBusInfo* _big_dbus_ensure_info(DBusConnection* connection) { BigDBusInfo* info; dbus_connection_allocate_data_slot(&info_slot); info = dbus_connection_get_data(connection, info_slot); if (info == NULL) { info = g_slice_new0(BigDBusInfo); info->where_connection_was = connection; if (connection == session_bus_weak_ref) info->bus_type = DBUS_BUS_SESSION; else if (connection == system_bus_weak_ref) info->bus_type = DBUS_BUS_SYSTEM; else g_error("Unknown bus type opened in %s", __FILE__); info->json_ifaces = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, (GFreeFunc) json_iface_free); info->name_watches = g_hash_table_new(g_str_hash, g_str_equal); dbus_connection_set_data(connection, info_slot, info, (DBusFreeFunction) info_free); dbus_connection_add_filter(connection, name_ownership_monitor_filter_message, NULL, NULL); dbus_connection_add_filter(connection, name_watch_filter_message, NULL, NULL); dbus_connection_add_filter(connection, _big_dbus_signal_watch_filter_message, NULL, NULL); /* Important: disconnect_filter_message() must be LAST so * it runs last when the disconnect message arrives. */ dbus_connection_add_filter(connection, disconnect_filter_message, NULL, NULL); /* caution, this could get circular if proxy_new() goes back around * and tries to use dbus.c - but we'll fix it when it happens. * Also, this refs the connection ... */ info->driver_proxy = big_dbus_proxy_new(connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS); } return info; } void _big_dbus_dispose_info(DBusConnection* connection) { BigDBusInfo* info; if (info_slot < 0) return; info = dbus_connection_get_data(connection, info_slot); if (info != NULL) { big_debug(BIG_DEBUG_UTIL_DBUS, "Disposing info on connection %p", connection); /* the driver proxy refs the connection, we want * to break that cycle. */ g_object_unref(info->driver_proxy); info->driver_proxy = NULL; dbus_connection_set_data(connection, info_slot, NULL, NULL); dbus_connection_free_data_slot(&info_slot); } } DBusConnection* _big_dbus_get_weak_ref(DBusBusType which_bus) { if (which_bus == DBUS_BUS_SESSION) { return session_bus_weak_ref; } else if (which_bus == DBUS_BUS_SYSTEM) { return system_bus_weak_ref; } g_assert_not_reached(); return NULL; } static DBusHandlerResult disconnect_filter_message(DBusConnection* connection, DBusMessage* message, void* data) { /* We should be running after all other filters */ if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) { big_debug(BIG_DEBUG_UTIL_DBUS, "Disconnected in %s", G_STRFUNC); _big_dbus_dispose_info(connection); if (session_bus_weak_ref == connection) session_bus_weak_ref = NULL; if (system_bus_weak_ref == connection) system_bus_weak_ref = NULL; } return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } static DBusConnection* try_connecting(DBusBusType which_bus) { DBusGConnection* gconnection; DBusConnection* connection; GError* error; connection = _big_dbus_get_weak_ref(which_bus); if (connection != NULL) return connection; big_debug(BIG_DEBUG_UTIL_DBUS, "trying to connect to message bus"); error = NULL; gconnection = dbus_g_bus_get(which_bus, &error); if (gconnection == NULL) { big_debug(BIG_DEBUG_UTIL_DBUS, "bus connection failed: %s", error->message); g_error_free(error); return NULL; } connection = dbus_g_connection_get_connection(gconnection); /* Disable this because all our apps will be well-behaved! */ dbus_connection_set_exit_on_disconnect(connection, FALSE); if (which_bus == DBUS_BUS_SESSION && session_bus_weak_ref == NULL) { GSList* l; session_bus_weak_ref = connection; for (l = session_bus_weak_refs; l != NULL; l = l->next) { DBusConnection** connection_p = l->data; *connection_p = session_bus_weak_ref; } } else if (which_bus == DBUS_BUS_SYSTEM && system_bus_weak_ref == NULL) { GSList* l; system_bus_weak_ref = connection; for (l = system_bus_weak_refs; l != NULL; l = l->next) { DBusConnection** connection_p = l->data; *connection_p = system_bus_weak_ref; } } dbus_g_connection_unref(gconnection); /* rely on libdbus holding a ref */ big_debug(BIG_DEBUG_UTIL_DBUS, "Successfully connected"); return connection; } static gboolean connect_idle(void* data) { GSList* l; DBusConnection* connection; BigDBusInfo* info; DBusBusType bus_type; bus_type = GPOINTER_TO_INT(data); if (bus_type == DBUS_BUS_SESSION) session_connect_idle_id = 0; else if (bus_type == DBUS_BUS_SYSTEM) system_connect_idle_id = 0; else g_assert_not_reached(); big_debug(BIG_DEBUG_UTIL_DBUS, "connection idle with %d connect listeners to traverse", g_slist_length(all_connect_funcs)); connection = try_connecting(bus_type); if (connection == NULL) { if (bus_type == DBUS_BUS_SESSION) { g_printerr("Lost connection to session bus, exiting\n"); exit(1); } else { /* Here it would theoretically make sense to reinstall the * idle as a timeout or something, but we don't for now, * just wait for something to trigger a reconnect. It is * not a situation that should happen in reality (we won't * restart the system bus without rebooting). */ } return FALSE; } info = _big_dbus_ensure_info(connection); /* We first need to call AddMatch on all signal watchers. * This is so if on connect, the app calls methods to get * the state the signal notifies the app of changes in, * the match rule is added before the "get current state" * methods are called. Otherwise there's a race where * a signal can be missed between a "get current state" method * call reply and the AddMatch. */ _big_dbus_process_pending_signal_watchers(connection, info); /* We want the app to see notification of connection opening, * THEN other notifications, so notify it's open first. */ for (l = all_connect_funcs; l != NULL; l = l->next) { ConnectFuncs* f; f = l->data; if (!f->opened && f->funcs->which_bus == bus_type) { f->opened = TRUE; (*f->funcs->opened)(connection, f->data); } } /* These two invoke application callbacks, unlike * _big_dbus_process_pending_signal_watchers(), so should come after * the above calls to the "connection opened" callbacks. */ process_name_ownership_monitors(connection, info); process_pending_name_watchers(connection, info); return FALSE; } void _big_dbus_ensure_connect_idle(DBusBusType bus_type) { if (bus_type == DBUS_BUS_SESSION) { if (session_connect_idle_id == 0) { session_connect_idle_id = g_idle_add(connect_idle, GINT_TO_POINTER(bus_type)); } } else if (bus_type == DBUS_BUS_SYSTEM) { if (system_connect_idle_id == 0) { system_connect_idle_id = g_idle_add(connect_idle, GINT_TO_POINTER(bus_type)); } } else { g_assert_not_reached(); } } static void internal_add_connect_funcs(const BigDBusConnectFuncs* funcs, void* data, gboolean sync_notify) { ConnectFuncs* f; f = g_slice_new0(ConnectFuncs); f->funcs = funcs; f->data = data; f->opened = FALSE; all_connect_funcs = g_slist_prepend(all_connect_funcs, f); _big_dbus_ensure_connect_idle(f->funcs->which_bus); if (sync_notify) { /* sync_notify means IF we are already connected * (we have a weak ref != NULL) then notify * right away before we return. */ DBusConnection* connection; connection = _big_dbus_get_weak_ref(f->funcs->which_bus); if (connection != NULL && !f->opened) { f->opened = TRUE; (*f->funcs->opened)(connection, f->data); } } } /* this should guarantee that the funcs are only called async, which is why * it does not try_connecting right away; the idea is to defer to inside the * main loop. */ void big_dbus_add_connect_funcs(const BigDBusConnectFuncs* funcs, void* data) { internal_add_connect_funcs(funcs, data, FALSE); } /* The sync_notify flavor calls the open notification right away if * we are already connected. */ void big_dbus_add_connect_funcs_sync_notify(const BigDBusConnectFuncs* funcs, void* data) { internal_add_connect_funcs(funcs, data, TRUE); } void big_dbus_remove_connect_funcs(const BigDBusConnectFuncs* funcs, void* data) { ConnectFuncs* f; GSList* l; f = NULL; for (l = all_connect_funcs; l != NULL; l = l->next) { f = l->data; if (f->funcs == funcs && f->data == data) break; } if (l == NULL) { g_warning("Could not find functions matching %p %p", funcs, data); return; } g_assert(l->data == f); all_connect_funcs = g_slist_delete_link(all_connect_funcs, l); g_slice_free(ConnectFuncs, f); } void big_dbus_add_bus_weakref(DBusBusType which_bus, DBusConnection** connection_p) { if (which_bus == DBUS_BUS_SESSION) { *connection_p = session_bus_weak_ref; session_bus_weak_refs = g_slist_prepend(session_bus_weak_refs, connection_p); } else if (which_bus == DBUS_BUS_SYSTEM) { *connection_p = system_bus_weak_ref; system_bus_weak_refs = g_slist_prepend(system_bus_weak_refs, connection_p); } else { g_assert_not_reached(); } _big_dbus_ensure_connect_idle(which_bus); } void big_dbus_remove_bus_weakref(DBusBusType which_bus, DBusConnection** connection_p) { if (which_bus == DBUS_BUS_SESSION) { *connection_p = NULL; session_bus_weak_refs = g_slist_remove(session_bus_weak_refs, connection_p); } else if (which_bus == DBUS_BUS_SYSTEM) { *connection_p = NULL; system_bus_weak_refs = g_slist_remove(system_bus_weak_refs, connection_p); } else { g_assert_not_reached(); } } void big_dbus_try_connecting_now(DBusBusType which_bus) { try_connecting(which_bus); } static BigJsonIface* json_iface_new(const char* name, const BigDBusJsonMethod* methods, int n_methods) { BigJsonIface* iface; iface = g_slice_new0(BigJsonIface); iface->name = g_strdup(name); iface->methods = methods; iface->n_methods = n_methods; return iface; } static void json_iface_free(BigJsonIface* iface) { g_free(iface->name); g_slice_free(BigJsonIface, iface); } static BigNameOwnershipMonitor* name_ownership_monitor_new(DBusBusType bus_type, const BigDBusNameOwnerFuncs* funcs, void* data) { BigNameOwnershipMonitor* monitor; monitor = g_slice_new0(BigNameOwnershipMonitor); monitor->bus_type = bus_type; monitor->prev_state = NAME_NOT_REQUESTED; monitor->state = NAME_NOT_REQUESTED; monitor->funcs = funcs; monitor->data = data; monitor->id = ++global_monitor_id; return monitor; } static void name_ownership_monitor_free(BigNameOwnershipMonitor* monitor) { g_slice_free(BigNameOwnershipMonitor, monitor); } static BigNameWatch* name_watch_new(const char* name) { BigNameWatch* watch; watch = g_slice_new0(BigNameWatch); watch->name = g_strdup(name); /* For unique names, we assume the owner is itself, * so we default to "exists" and maybe emit "vanished", * while with well-known names we do the opposite. */ if (*watch->name == ':') { watch->current_owner = g_strdup(watch->name); } return watch; } static void name_watch_free(BigNameWatch* watch) { g_assert(watch->watchers == NULL); g_free(watch->name); g_free(watch->current_owner); g_slice_free(BigNameWatch, watch); } static BigNameWatcher* name_watcher_new(BigDBusWatchNameFlags flags, const BigDBusWatchNameFuncs* funcs, void* data, DBusBusType bus_type) { BigNameWatcher* watcher; watcher = g_slice_new0(BigNameWatcher); watcher->flags = flags; watcher->funcs = funcs; watcher->data = data; watcher->bus_type = bus_type; watcher->watch = NULL; watcher->refcount = 1; return watcher; } static void name_watcher_ref(BigNameWatcher* watcher) { watcher->refcount += 1; } static void name_watcher_unref(BigNameWatcher* watcher) { watcher->refcount -= 1; if (watcher->refcount == 0) g_slice_free(BigNameWatcher, watcher); } static void info_free(BigDBusInfo* info) { void* key; void* value; big_debug(BIG_DEBUG_UTIL_DBUS, "Destroy notify invoked on bus connection info for %p", info->where_connection_was); if (info->where_connection_was == session_bus_weak_ref) session_bus_weak_ref = NULL; if (info->where_connection_was == system_bus_weak_ref) system_bus_weak_ref = NULL; /* This could create some strange re-entrancy so do it first. * If we processed a disconnect message, this should have been done * already at that time, but if we were finalized without that, * it may not have been. */ if (info->driver_proxy != NULL) { g_object_unref(info->driver_proxy); info->driver_proxy = NULL; } while (info->name_ownership_monitors != NULL) { name_ownership_monitor_free(info->name_ownership_monitors->data); info->name_ownership_monitors = g_slist_remove(info->name_ownership_monitors, info->name_ownership_monitors->data); } while ((value = g_hash_table_lookup(info->name_watches, &key))) { BigNameWatch* watch = value; while (watch->watchers) { name_watch_remove_watcher(watch, watch->watchers->data); } name_watch_free(watch); g_hash_table_steal(info->name_watches, &key); } if (info->signal_watchers_by_unique_sender) { g_hash_table_destroy(info->signal_watchers_by_unique_sender); } if (info->signal_watchers_by_path) { g_hash_table_destroy(info->signal_watchers_by_path); } if (info->signal_watchers_by_iface) { g_hash_table_destroy(info->signal_watchers_by_iface); } if (info->signal_watchers_by_signal) { g_hash_table_destroy(info->signal_watchers_by_signal); } g_hash_table_destroy(info->name_watches); g_hash_table_destroy(info->json_ifaces); g_slice_free(BigDBusInfo, info); } static DBusHandlerResult name_ownership_monitor_filter_message(DBusConnection* connection, DBusMessage* message, void* data) { BigDBusInfo* info; gboolean states_changed; info = _big_dbus_ensure_info(connection); states_changed = FALSE; if (dbus_message_is_signal(message, DBUS_INTERFACE_DBUS, "NameLost") && dbus_message_has_sender(message, DBUS_SERVICE_DBUS)) { const char* name = NULL; if (dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID)) { GSList* l; big_debug(BIG_DEBUG_UTIL_DBUS, "Lost name %s", name); for (l = info->name_ownership_monitors; l != NULL; l = l->next) { BigNameOwnershipMonitor* monitor; monitor = l->data; if (monitor->state == NAME_PRIMARY_OWNER && strcmp(name, monitor->funcs->name) == 0) { monitor->prev_state = monitor->state; monitor->state = NAME_NOT_OWNED; states_changed = TRUE; /* keep going, don't break, there may be more matches */ } } } else { big_debug(BIG_DEBUG_UTIL_DBUS, "NameLost has wrong arguments???"); } } else if (dbus_message_is_signal(message, DBUS_INTERFACE_DBUS, "NameAcquired") && dbus_message_has_sender(message, DBUS_SERVICE_DBUS)) { const char* name = NULL; if (dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID)) { GSList* l; big_debug(BIG_DEBUG_UTIL_DBUS, "Acquired name %s", name); for (l = info->name_ownership_monitors; l != NULL; l = l->next) { BigNameOwnershipMonitor* monitor; monitor = l->data; if (monitor->state != NAME_PRIMARY_OWNER && strcmp(name, monitor->funcs->name) == 0) { monitor->prev_state = monitor->state; monitor->state = NAME_PRIMARY_OWNER; states_changed = TRUE; /* keep going, don't break, there may be more matches */ } } } else { big_debug(BIG_DEBUG_UTIL_DBUS, "NameAcquired has wrong arguments???"); } } else if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) { GSList* l; big_debug(BIG_DEBUG_UTIL_DBUS, "Disconnected in %s", G_STRFUNC); for (l = info->name_ownership_monitors; l != NULL; l = l->next) { BigNameOwnershipMonitor* monitor; monitor = l->data; if (monitor->state != NAME_NOT_REQUESTED) { /* Set things up to re-request the name */ monitor->prev_state = monitor->state; monitor->state = NAME_NOT_REQUESTED; states_changed = TRUE; } } /* FIXME move the monitors back to the pending list so they'll be found * on reconnect */ } if (states_changed) process_name_ownership_monitors(connection, info); return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } static void process_name_ownership_monitors(DBusConnection* connection, BigDBusInfo* info) { GSList* l; gboolean connected; GSList* still_pending; /* First pull anything out of pending queue */ still_pending = NULL; while (pending_name_ownership_monitors != NULL) { BigNameOwnershipMonitor* monitor; monitor = pending_name_ownership_monitors->data; pending_name_ownership_monitors = g_slist_remove(pending_name_ownership_monitors, pending_name_ownership_monitors->data); if (monitor->bus_type == info->bus_type) { info->name_ownership_monitors = g_slist_prepend(info->name_ownership_monitors, monitor); } else { still_pending = g_slist_prepend(still_pending, monitor); } } g_assert(pending_name_ownership_monitors == NULL); pending_name_ownership_monitors = still_pending; /* Now send notifications to the app */ connected = dbus_connection_get_is_connected(connection); if (connected) { for (l = info->name_ownership_monitors; l != NULL; l = l->next) { BigNameOwnershipMonitor* monitor; monitor = l->data; if (monitor->state == NAME_NOT_REQUESTED) { int result; unsigned int flags; DBusError derror; flags = DBUS_NAME_FLAG_ALLOW_REPLACEMENT; if (monitor->funcs->type == BIG_DBUS_NAME_SINGLE_INSTANCE) flags |= DBUS_NAME_FLAG_DO_NOT_QUEUE; dbus_error_init(&derror); result = dbus_bus_request_name(connection, monitor->funcs->name, flags, &derror); /* log 'error' word only when one occurred */ if (derror.message != NULL) { big_debug(BIG_DEBUG_UTIL_DBUS, "Requested name %s result %d error %s", monitor->funcs->name, result, derror.message); } else { big_debug(BIG_DEBUG_UTIL_DBUS, "Requested name %s result %d", monitor->funcs->name, result); } dbus_error_free(&derror); /* An important feature of this code is that we always * transition from NOT_REQUESTED to something else when * a name monitor is first added, so we always notify * the app either "acquired" or "lost" and don't * leave the app in limbo. * * This means the app can "get going" when it gets the name * and exit when it loses it, and that will just work * since one or the other will always happen on startup. */ monitor->prev_state = monitor->state; if (result == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER || result == DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER) { monitor->state = NAME_PRIMARY_OWNER; } else if (result == DBUS_REQUEST_NAME_REPLY_IN_QUEUE) { monitor->state = NAME_IN_QUEUE; } else if (result == DBUS_REQUEST_NAME_REPLY_EXISTS) { monitor->state = NAME_NOT_OWNED; } else { /* reply code we don't understand? */ monitor->state = NAME_NOT_OWNED; } } } } /* Do notifications with a list copy for extra safety * (for true safety we also need to refcount each monitor * and have a "destroyed" flag) */ l = g_slist_copy(info->name_ownership_monitors); while (l != NULL) { BigNameOwnershipMonitor* monitor; monitor = l->data; l = g_slist_remove(l, l->data); if (monitor->prev_state != monitor->state) { monitor->prev_state = monitor->state; if (monitor->state == NAME_PRIMARY_OWNER) { big_debug(BIG_DEBUG_UTIL_DBUS, "Notifying acquired %s", monitor->funcs->name); (*monitor->funcs->acquired)(connection, monitor->funcs->name, monitor->data); } else if (monitor->state != NAME_PRIMARY_OWNER) { big_debug(BIG_DEBUG_UTIL_DBUS, "Notifying lost %s", monitor->funcs->name); (*monitor->funcs->lost)(connection, monitor->funcs->name, monitor->data); } } } } unsigned int big_dbus_acquire_name(DBusBusType bus_type, const BigDBusNameOwnerFuncs* funcs, void* data) { BigNameOwnershipMonitor* monitor; monitor = name_ownership_monitor_new(bus_type, funcs, data); pending_name_ownership_monitors = g_slist_prepend(pending_name_ownership_monitors, monitor); _big_dbus_ensure_connect_idle(bus_type); return monitor->id; } static void release_name_internal(DBusBusType bus_type, const BigDBusNameOwnerFuncs* funcs, void* data, unsigned int id) { BigDBusInfo* info; GSList* l; BigNameOwnershipMonitor* monitor; DBusConnection* connection; connection = _big_dbus_get_weak_ref(bus_type); if (!connection) return; info = _big_dbus_ensure_info(connection); /* Check first pending list */ for (l = pending_name_ownership_monitors; l; l = l->next) { monitor = l->data; /* If the id is valid an matches, we are done */ if (monitor->state == NAME_PRIMARY_OWNER && ((id != BIG_DBUS_NAME_OWNER_MONITOR_INVALID_ID && monitor->id == id) || (monitor->funcs == funcs && monitor->data == data))) { dbus_bus_release_name(connection, monitor->funcs->name, NULL); pending_name_ownership_monitors = g_slist_remove(pending_name_ownership_monitors, monitor); name_ownership_monitor_free(monitor); /* If the monitor was in the pending list it * can't be in the processed list */ return; } } for (l = info->name_ownership_monitors; l; l = l->next) { monitor = l->data; /* If the id is valid an matches, we are done */ if (monitor->state == NAME_PRIMARY_OWNER && ((id != BIG_DBUS_NAME_OWNER_MONITOR_INVALID_ID && monitor->id == id) || (monitor->funcs == funcs && monitor->data == data))) { dbus_bus_release_name(connection, monitor->funcs->name, NULL); info->name_ownership_monitors = g_slist_remove(info->name_ownership_monitors, monitor); name_ownership_monitor_free(monitor); break; } } } void big_dbus_release_name_by_id(DBusBusType bus_type, unsigned int id) { release_name_internal(bus_type, NULL, NULL, id); } void big_dbus_release_name(DBusBusType bus_type, const BigDBusNameOwnerFuncs* funcs, void* data) { release_name_internal(bus_type, funcs, data, BIG_DBUS_NAME_OWNER_MONITOR_INVALID_ID); } static void notify_name_owner_changed(DBusConnection* connection, const char* name, const char* new_owner) { BigDBusInfo* info; BigNameWatch* watch; GSList *l, *watchers; gchar* old_owner; info = _big_dbus_ensure_info(connection); if (*new_owner == '\0') new_owner = NULL; watch = g_hash_table_lookup(info->name_watches, name); if (watch == NULL) return; if ((watch->current_owner == new_owner) || (watch->current_owner && new_owner && strcmp(watch->current_owner, new_owner) == 0)) { /* No change */ return; } /* we copy the list before iterating, because the * callbacks may modify it */ watchers = g_slist_copy(watch->watchers); g_slist_foreach(watchers, (GFunc) name_watcher_ref, NULL); /* copy the old owner in case the watch is removed in * the callbacks */ old_owner = g_strdup(watch->current_owner); /* vanish the old owner */ if (old_owner != NULL) { for (l = watchers; l != NULL; l = l->next) { BigNameWatcher* watcher = l->data; if (watcher->notify_idle != 0) { /* Name owner changed before we notified * the watcher of the initial name. We will notify * him now of the old name, then that this name * vanished. * * This is better than not sending calling any * callback, it might for instance trigger destroying * signal watchers on the unique name. */ g_source_remove(watcher->notify_idle); notify_watcher_name_appeared(watcher); } if (!watcher->destroyed) { (*watcher->funcs->vanished)(connection, name, old_owner, watcher->data); } } } /* lookup for the watch again, since it might have vanished * if all watchers were removed in the watcher->vanished * callbacks */ watch = g_hash_table_lookup(info->name_watches, name); if (watch) { g_free(watch->current_owner); watch->current_owner = g_strdup(new_owner); } /* appear the new owner */ if (new_owner != NULL) { for (l = watchers; l != NULL; l = l->next) { BigNameWatcher* watcher = l->data; if (!watcher->destroyed) { (*watcher->funcs->appeared)(connection, name, new_owner, watcher->data); } } } /* now destroy our copy */ g_slist_foreach(watchers, (GFunc) name_watcher_unref, NULL); g_slist_free(watchers); g_free(old_owner); } static DBusHandlerResult name_watch_filter_message(DBusConnection* connection, DBusMessage* message, void* data) { BigDBusInfo* info; info = _big_dbus_ensure_info(connection); if (dbus_message_is_signal(message, DBUS_INTERFACE_DBUS, "NameOwnerChanged") && dbus_message_has_sender(message, DBUS_SERVICE_DBUS)) { const char* name = NULL; const char* old_owner = NULL; const char* new_owner = NULL; if (dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_STRING, &old_owner, DBUS_TYPE_STRING, &new_owner, DBUS_TYPE_INVALID)) { big_debug(BIG_DEBUG_UTIL_DBUS, "NameOwnerChanged %s: %s -> %s", name, old_owner, new_owner); notify_name_owner_changed(connection, name, new_owner); } else { big_debug(BIG_DEBUG_UTIL_DBUS, "NameOwnerChanged has wrong arguments???"); } } else if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) { big_debug(BIG_DEBUG_UTIL_DBUS, "Disconnected in %s", G_STRFUNC); /* FIXME set all current owners to NULL, and move watches back to the * pending * list so they are found on reconnect. */ } return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } void _big_dbus_set_matching_name_owner_changed(DBusConnection* connection, const char* bus_name, gboolean matched) { char* s; big_debug(BIG_DEBUG_UTIL_DBUS, "%s NameOwnerChanged on name '%s'", matched ? "Matching" : "No longer matching", bus_name); s = g_strdup_printf("type='signal',sender='" DBUS_SERVICE_DBUS "',interface='" DBUS_INTERFACE_DBUS "',member='" "NameOwnerChanged" "',arg0='%s'", bus_name); if (matched) dbus_bus_add_match(connection, s, NULL); /* asking for error would make this block */ else dbus_bus_remove_match(connection, s, NULL); g_free(s); } static void on_start_service_reply(BigDBusProxy* proxy, DBusMessage* message, void* data) { big_debug(BIG_DEBUG_UTIL_DBUS, "Got successful reply to service start"); } static void on_start_service_error(BigDBusProxy* proxy, const char* error_name, const char* error_message, void* data) { big_debug(BIG_DEBUG_UTIL_DBUS, "Got error starting service: %s: %s", error_name, error_message); } void big_dbus_start_service(DBusConnection* connection, const char* name) { DBusMessage* message; dbus_uint32_t flags; BigDBusInfo* info; big_debug(BIG_DEBUG_UTIL_DBUS, "Starting service '%s'", name); info = _big_dbus_ensure_info(connection); message = big_dbus_proxy_new_method_call(info->driver_proxy, "StartServiceByName"); flags = 0; if (dbus_message_append_args(message, DBUS_TYPE_STRING, &name, DBUS_TYPE_UINT32, &flags, DBUS_TYPE_INVALID)) { big_dbus_proxy_send(info->driver_proxy, message, on_start_service_reply, on_start_service_error, NULL); } else { big_debug(BIG_DEBUG_UTIL_DBUS, "No memory appending args to StartServiceByName"); } dbus_message_unref(message); } typedef struct { DBusConnection* connection; char* name; BigDBusWatchNameFlags flags; } GetOwnerRequest; static GetOwnerRequest* get_owner_request_new(DBusConnection* connection, const char* name, BigDBusWatchNameFlags flags) { GetOwnerRequest* gor; gor = g_slice_new0(GetOwnerRequest); gor->connection = connection; gor->name = g_strdup(name); gor->flags = flags; dbus_connection_ref(connection); return gor; } static void get_owner_request_free(GetOwnerRequest* gor) { dbus_connection_unref(gor->connection); g_free(gor->name); g_slice_free(GetOwnerRequest, gor); } static void on_get_owner_reply(DBusPendingCall* pending, void* user_data) { DBusMessage* reply; GetOwnerRequest* gor; gor = user_data; reply = dbus_pending_call_steal_reply(pending); if (reply == NULL) { g_warning("NULL reply in on_get_owner_reply?"); return; } if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_METHOD_RETURN) { const char* current_owner = NULL; if (!dbus_message_get_args(reply, NULL, DBUS_TYPE_STRING, ¤t_owner, DBUS_TYPE_INVALID)) { big_debug(BIG_DEBUG_UTIL_DBUS, "GetNameOwner has wrong args '%s'", dbus_message_get_signature(reply)); } else { big_debug(BIG_DEBUG_UTIL_DBUS, "Got owner '%s' for name '%s'", current_owner, gor->name); if (current_owner != NULL) { notify_name_owner_changed(gor->connection, gor->name, current_owner); } } } else if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) { if (g_str_equal(dbus_message_get_error_name(reply), DBUS_ERROR_NAME_HAS_NO_OWNER)) { big_debug(BIG_DEBUG_UTIL_DBUS, "'%s' was not running", gor->name); if (gor->flags & BIG_DBUS_NAME_START_IF_NOT_FOUND) { big_debug(BIG_DEBUG_UTIL_DBUS, " (starting it up)"); big_dbus_start_service(gor->connection, gor->name); } else { /* no owner for now, notify app */ notify_name_owner_changed(gor->connection, gor->name, ""); } } else { big_debug(BIG_DEBUG_UTIL_DBUS, "Error getting owner of name '%s': %s", gor->name, dbus_message_get_error_name(reply)); /* Notify no owner for now, ensuring the app * gets advised "appeared" or "vanished", * one or the other. */ notify_name_owner_changed(gor->connection, gor->name, ""); } } else { big_debug(BIG_DEBUG_UTIL_DBUS, "Nonsensical reply type to GetNameOwner"); } dbus_message_unref(reply); } static void request_name_owner(DBusConnection* connection, BigDBusInfo* info, BigNameWatch* watch) { DBusMessage* message; DBusPendingCall* call; message = dbus_message_new_method_call(DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "GetNameOwner"); if (message == NULL) g_error("no memory"); if (!dbus_message_append_args(message, DBUS_TYPE_STRING, &watch->name, DBUS_TYPE_INVALID)) g_error("no memory"); call = NULL; dbus_connection_send_with_reply(connection, message, &call, -1); if (call != NULL) { GetOwnerRequest* gor; BigDBusWatchNameFlags flags; GSList* l; big_debug(BIG_DEBUG_UTIL_DBUS, "Sent GetNameOwner for '%s'", watch->name); flags = 0; for (l = watch->watchers; l != NULL; l = l->next) { BigNameWatcher* watcher = l->data; if (watcher->flags & BIG_DBUS_NAME_START_IF_NOT_FOUND) flags |= BIG_DBUS_NAME_START_IF_NOT_FOUND; } gor = get_owner_request_new(connection, watch->name, flags); if (!dbus_pending_call_set_notify(call, on_get_owner_reply, gor, (DBusFreeFunction) get_owner_request_free)) g_error("no memory"); /* the connection will hold a ref to the pending call */ dbus_pending_call_unref(call); } else { big_debug(BIG_DEBUG_UTIL_DBUS, "GetNameOwner for '%s' not sent, connection disconnected", watch->name); } } static gboolean notify_watcher_name_appeared(gpointer data) { BigNameWatcher* watcher; DBusConnection* connection; watcher = data; watcher->notify_idle = 0; connection = _big_dbus_get_weak_ref(watcher->bus_type); if (!connection) return FALSE; (*watcher->funcs->appeared)(connection, watcher->watch->name, watcher->watch->current_owner, watcher->data); return FALSE; } static void create_watch_for_watcher(DBusConnection* connection, BigDBusInfo* info, const char* name, BigNameWatcher* watcher) { BigNameWatch* watch; watch = g_hash_table_lookup(info->name_watches, name); if (watch == NULL) { watch = name_watch_new(name); g_hash_table_replace(info->name_watches, watch->name, watch); watch->watchers = g_slist_prepend(watch->watchers, watcher); _big_dbus_set_matching_name_owner_changed(connection, watch->name, TRUE); request_name_owner(connection, info, watch); } else { watch->watchers = g_slist_prepend(watch->watchers, watcher); } name_watcher_ref(watcher); watcher->watch = watch; } static void process_pending_name_watchers(DBusConnection* connection, BigDBusInfo* info) { GSList* still_pending; still_pending = NULL; while (pending_name_watchers != NULL) { BigPendingNameWatcher* pending; BigNameWatch* watch; pending = pending_name_watchers->data; pending_name_watchers = g_slist_remove(pending_name_watchers, pending_name_watchers->data); if (pending->bus_type != info->bus_type) { still_pending = g_slist_prepend(still_pending, pending); continue; } create_watch_for_watcher(connection, info, pending->name, pending->watcher); watch = pending->watcher->watch; /* If we already know the owner, let the new watcher know */ if (watch->current_owner != NULL) { (*pending->watcher->funcs->appeared)(connection, watch->name, watch->current_owner, pending->watcher->data); } g_free(pending->name); name_watcher_unref(pending->watcher); g_slice_free(BigPendingNameWatcher, pending); } g_assert(pending_name_watchers == NULL); pending_name_watchers = still_pending; } static void name_watch_remove_watcher(BigNameWatch* watch, BigNameWatcher* watcher) { watch->watchers = g_slist_remove(watch->watchers, watcher); if (watcher->notify_idle) { g_source_remove(watcher->notify_idle); watcher->notify_idle = 0; } watcher->destroyed = TRUE; name_watcher_unref(watcher); } void big_dbus_watch_name(DBusBusType bus_type, const char* name, BigDBusWatchNameFlags flags, const BigDBusWatchNameFuncs* funcs, void* data) { BigNameWatcher* watcher; DBusConnection* connection; big_debug(BIG_DEBUG_UTIL_DBUS, "Adding watch on name '%s'", name); watcher = name_watcher_new(flags, funcs, data, bus_type); connection = _big_dbus_get_weak_ref(bus_type); if (connection) { BigDBusInfo* info; info = _big_dbus_ensure_info(connection); create_watch_for_watcher(connection, info, name, watcher); /* The initial reference is now transferred to the watch */ name_watcher_unref(watcher); /* If we already know the owner, notify the user in an idle */ if (watcher->watch->current_owner) { watcher->notify_idle = g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, notify_watcher_name_appeared, watcher, (GDestroyNotify) name_watcher_unref); name_watcher_ref(watcher); } } else { BigPendingNameWatcher* pending; pending = g_slice_new0(BigPendingNameWatcher); pending->bus_type = bus_type; pending->name = g_strdup(name); pending->watcher = watcher; pending_name_watchers = g_slist_prepend(pending_name_watchers, pending); _big_dbus_ensure_connect_idle(pending->bus_type); } } void big_dbus_unwatch_name(DBusBusType bus_type, const char* name, const BigDBusWatchNameFuncs* funcs, void* data) { DBusConnection* connection; BigDBusInfo* info; BigNameWatch* watch; GSList* l; BigNameWatcher* watcher; big_debug(BIG_DEBUG_UTIL_DBUS, "Removing watch on name '%s'", name); connection = _big_dbus_get_weak_ref(bus_type); if (connection == NULL) { /* right now our state is entirely hosed if we disconnect * (we don't move the watchers out of the connection data), * so can't do much here without larger changes to the file */ g_warning("Have not implemented disconnect handling"); return; } info = _big_dbus_ensure_info(connection); /* could still be pending */ process_pending_name_watchers(connection, info); watch = g_hash_table_lookup(info->name_watches, name); if (watch == NULL) { g_warning("attempt to unwatch name %s but nobody is watching that", name); return; } watcher = NULL; for (l = watch->watchers; l != NULL; l = l->next) { watcher = l->data; if (watcher->funcs == funcs && watcher->data == data) break; } if (l == NULL) { g_warning("Could not find a watch on %s matching %p %p", name, funcs, data); return; } g_assert(l->data == watcher); name_watch_remove_watcher(watch, watcher); /* Clear out the watch if it's gone */ if (watch->watchers == NULL) { g_hash_table_remove(info->name_watches, watch->name); _big_dbus_set_matching_name_owner_changed(connection, watch->name, FALSE); name_watch_free(watch); } } const char* big_dbus_get_watched_name_owner(DBusBusType bus_type, const char* name) { DBusConnection* connection; BigNameWatch* watch; BigDBusInfo* info; connection = _big_dbus_get_weak_ref(bus_type); if (connection == NULL) { return NULL; } info = _big_dbus_ensure_info(connection); /* could still be pending */ process_pending_name_watchers(connection, info); watch = g_hash_table_lookup(info->name_watches, name); if (watch == NULL) { g_warning("Tried to get owner of '%s' but there is no watch on it", name); return NULL; } return watch->current_owner; } void big_dbus_register_json(DBusConnection* connection, const char* iface_name, const BigDBusJsonMethod* methods, int n_methods) { BigDBusInfo* info; BigJsonIface* iface; info = _big_dbus_ensure_info(connection); iface = json_iface_new(iface_name, methods, n_methods); g_hash_table_replace(info->json_ifaces, iface->name, iface); } void big_dbus_unregister_json(DBusConnection* connection, const char* iface_name) { BigDBusInfo* info; info = _big_dbus_ensure_info(connection); g_hash_table_remove(info->json_ifaces, iface_name); } typedef struct { DBusConnection* connection; GObject* gobj; char* iface_name; } BigDBusGObject; static void gobj_path_unregistered(DBusConnection* connection, void* user_data) { BigDBusGObject* g; g = user_data; if (g->gobj) { g_object_remove_weak_pointer(g->gobj, (void**) &g->gobj); g->gobj = NULL; } g_free(g->iface_name); g_slice_free(BigDBusGObject, g); } static DBusHandlerResult gobj_path_message(DBusConnection* connection, DBusMessage* message, void* user_data) { BigDBusGObject* g; BigDBusInfo* info; BigJsonIface* iface; const char* message_iface; const char* message_method; DBusError derror; int i; const BigDBusJsonMethod* method; DBusMessageIter arg_iter, dict_iter; info = _big_dbus_ensure_info(connection); g = user_data; big_debug(BIG_DEBUG_UTIL_DBUS, "Received message to iface %s gobj %p", g->iface_name, g->gobj); if (g->gobj == NULL) { /* GObject was destroyed */ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } if (dbus_message_get_type(message) != DBUS_MESSAGE_TYPE_METHOD_CALL) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; dbus_error_init(&derror); message_iface = dbus_message_get_interface(message); /* FIXME implement Introspectable() just to enable dbus debugger */ if (message_iface != NULL && strcmp(message_iface, g->iface_name) != 0) { dbus_set_error( &derror, DBUS_ERROR_UNKNOWN_METHOD, "Interface '%s' not implemented by this object, did you mean '%s'?", message_iface, g->iface_name); goto out; } iface = g_hash_table_lookup(info->json_ifaces, g->iface_name); if (iface == NULL) { g_warning( "Object registered with iface %s but that iface is not registered", g->iface_name); dbus_set_error(&derror, DBUS_ERROR_UNKNOWN_METHOD, "Bug - '%s' is not registered", g->iface_name); goto out; } method = NULL; message_method = dbus_message_get_member(message); for (i = 0; i < iface->n_methods; ++i) { if (strcmp(message_method, iface->methods[i].name) == 0) { method = &iface->methods[i]; break; } } if (method == NULL) { dbus_set_error(&derror, DBUS_ERROR_UNKNOWN_METHOD, "Interface '%s' has no method '%s'", g->iface_name, message_method); goto out; } if (!dbus_message_has_signature(message, "a{sv}")) { dbus_set_error( &derror, DBUS_ERROR_INVALID_ARGS, "Method %s.%s should have 1 argument which is a dictionary", g->iface_name, message_method); goto out; } dbus_message_iter_init(message, &arg_iter); dbus_message_iter_recurse(&arg_iter, &dict_iter); if (method->sync_func != NULL) { DBusMessage* reply; DBusMessageIter out_arg_iter, out_dict_iter; reply = dbus_message_new_method_return(message); if (reply == NULL) { dbus_set_error(&derror, DBUS_ERROR_NO_MEMORY, "No memory"); goto out; } dbus_message_iter_init_append(reply, &out_arg_iter); dbus_message_iter_open_container(&out_arg_iter, DBUS_TYPE_ARRAY, "{sv}", &out_dict_iter); g_object_ref(g->gobj); (*method->sync_func)(connection, message, &dict_iter, &out_dict_iter, g->gobj, &derror); g_object_unref(g->gobj); dbus_message_iter_close_container(&out_arg_iter, &out_dict_iter); if (!dbus_error_is_set(&derror)) { dbus_connection_send(connection, reply, NULL); } dbus_message_unref(reply); } else if (method->async_func != NULL) { g_object_ref(g->gobj); (*method->async_func)(connection, message, &dict_iter, g->gobj); g_object_unref(g->gobj); } else { g_warning("Method %s does not have any implementation", method->name); } out: if (dbus_error_is_set(&derror)) { DBusMessage* reply; reply = dbus_message_new_error(message, derror.name, derror.message); dbus_error_free(&derror); if (reply != NULL) { dbus_connection_send(connection, reply, NULL); dbus_message_unref(reply); } else { /* use g_printerr not g_warning since this is NOT a "can * never happen" just a "probably will never happen" */ g_printerr("Could not send OOM error\n"); } } return DBUS_HANDLER_RESULT_HANDLED; } static DBusObjectPathVTable gobj_vtable = { gobj_path_unregistered, gobj_path_message, NULL, }; /* Note that because of how this works, each object can be registered * at multiple paths but only once per path. Which is sort of bizarre, * but we'll fix it when we need it. */ void big_dbus_register_g_object(DBusConnection* connection, const char* path, GObject* gobj, const char* iface_name) { BigDBusGObject* g; g = g_slice_new0(BigDBusGObject); g->iface_name = g_strdup(iface_name); g->gobj = gobj; if (!dbus_connection_register_object_path(connection, path, &gobj_vtable, g)) { g_warning("Failed to register object path %s", path); } g_object_add_weak_pointer(g->gobj, (void**) &g->gobj); } void big_dbus_unregister_g_object(DBusConnection* connection, const char* path) { dbus_connection_unregister_object_path(connection, path); } static void open_json_entry(DBusMessageIter* dict_iter, const char* key, const char* signature, DBusMessageIter* entry_iter, DBusMessageIter* variant_iter) { dbus_message_iter_open_container(dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, entry_iter); dbus_message_iter_append_basic(entry_iter, DBUS_TYPE_STRING, &key); dbus_message_iter_open_container(entry_iter, DBUS_TYPE_VARIANT, signature, variant_iter); } static void close_json_entry(DBusMessageIter* dict_iter, DBusMessageIter* entry_iter, DBusMessageIter* variant_iter) { dbus_message_iter_close_container(entry_iter, variant_iter); dbus_message_iter_close_container(dict_iter, entry_iter); } static void open_json_entry_array(DBusMessageIter* dict_iter, const char* key, int array_element_type, DBusMessageIter* entry_iter, DBusMessageIter* variant_iter, DBusMessageIter* array_iter) { char buf[3]; buf[0] = 'a'; buf[1] = array_element_type; buf[2] = '\0'; open_json_entry(dict_iter, key, buf, entry_iter, variant_iter); dbus_message_iter_open_container(variant_iter, DBUS_TYPE_ARRAY, &buf[1], array_iter); } static void close_json_entry_array(DBusMessageIter* dict_iter, DBusMessageIter* entry_iter, DBusMessageIter* variant_iter, DBusMessageIter* array_iter) { dbus_message_iter_close_container(variant_iter, array_iter); close_json_entry(dict_iter, entry_iter, variant_iter); } void big_dbus_append_json_entry(DBusMessageIter* dict_iter, const char* key, int dbus_type, void* basic_value_p) { DBusMessageIter entry_iter, variant_iter; char buf[2]; buf[0] = dbus_type; buf[1] = '\0'; open_json_entry(dict_iter, key, buf, &entry_iter, &variant_iter); dbus_message_iter_append_basic(&variant_iter, dbus_type, basic_value_p); close_json_entry(dict_iter, &entry_iter, &variant_iter); } void big_dbus_append_json_entry_STRING(DBusMessageIter* dict_iter, const char* key, const char* value) { big_dbus_append_json_entry(dict_iter, key, DBUS_TYPE_STRING, &value); } void big_dbus_append_json_entry_INT32(DBusMessageIter* dict_iter, const char* key, dbus_int32_t value) { big_dbus_append_json_entry(dict_iter, key, DBUS_TYPE_INT32, &value); } void big_dbus_append_json_entry_DOUBLE(DBusMessageIter* dict_iter, const char* key, double value) { big_dbus_append_json_entry(dict_iter, key, DBUS_TYPE_DOUBLE, &value); } void big_dbus_append_json_entry_BOOLEAN(DBusMessageIter* dict_iter, const char* key, dbus_bool_t value) { big_dbus_append_json_entry(dict_iter, key, DBUS_TYPE_BOOLEAN, &value); } /* when coming from a dynamic language, we don't know what type of array '[]' is * supposed to be */ void big_dbus_append_json_entry_EMPTY_ARRAY(DBusMessageIter* dict_iter, const char* key) { DBusMessageIter entry_iter, variant_iter, array_iter; /* so just say VARIANT even though there won't be any elements in the array */ open_json_entry_array(dict_iter, key, DBUS_TYPE_VARIANT, &entry_iter, &variant_iter, &array_iter); close_json_entry_array(dict_iter, &entry_iter, &variant_iter, &array_iter); } void big_dbus_append_json_entry_STRING_ARRAY(DBusMessageIter* dict_iter, const char* key, const char** value) { DBusMessageIter entry_iter, variant_iter, array_iter; int i; open_json_entry_array(dict_iter, key, DBUS_TYPE_STRING, &entry_iter, &variant_iter, &array_iter); for (i = 0; value[i] != NULL; ++i) { dbus_message_iter_append_basic(&array_iter, DBUS_TYPE_STRING, &value[i]); } close_json_entry_array(dict_iter, &entry_iter, &variant_iter, &array_iter); } gboolean big_dbus_message_iter_get_gsize(DBusMessageIter* iter, gsize* value_p) { switch (dbus_message_iter_get_arg_type(iter)) { case DBUS_TYPE_INT32: { dbus_int32_t v; dbus_message_iter_get_basic(iter, &v); if (v < 0) return FALSE; *value_p = v; } break; case DBUS_TYPE_UINT32: { dbus_uint32_t v; dbus_message_iter_get_basic(iter, &v); *value_p = v; } break; case DBUS_TYPE_INT64: { dbus_int64_t v; dbus_message_iter_get_basic(iter, &v); if (v < 0) return FALSE; if (((guint64) v) > G_MAXSIZE) return FALSE; *value_p = v; } break; case DBUS_TYPE_UINT64: { dbus_uint64_t v; dbus_message_iter_get_basic(iter, &v); if (v > G_MAXSIZE) return FALSE; *value_p = v; } break; default: return FALSE; } return TRUE; } gboolean big_dbus_message_iter_get_gssize(DBusMessageIter* iter, gssize* value_p) { switch (dbus_message_iter_get_arg_type(iter)) { case DBUS_TYPE_INT32: { dbus_int32_t v; dbus_message_iter_get_basic(iter, &v); *value_p = v; } break; case DBUS_TYPE_UINT32: { dbus_uint32_t v; dbus_message_iter_get_basic(iter, &v); if (v > (guint32) G_MAXSSIZE) return FALSE; *value_p = v; } break; case DBUS_TYPE_INT64: { dbus_int64_t v; dbus_message_iter_get_basic(iter, &v); if (v > (gint64) G_MAXSSIZE) return FALSE; if (v < (gint64) G_MINSSIZE) return FALSE; *value_p = v; } break; case DBUS_TYPE_UINT64: { dbus_uint64_t v; dbus_message_iter_get_basic(iter, &v); if (v > (guint64) G_MAXSSIZE) return FALSE; *value_p = v; } break; default: return FALSE; } return TRUE; } #if BIG_BUILD_TESTS #include "dbus-proxy.h" #include "dbus-input-stream.h" #include "dbus-output-stream.h" #include #include #include #include #include #include #include static pid_t test_service_pid = 0; static BigDBusProxy* test_service_proxy = NULL; static pid_t test_io_pid = 0; static BigDBusProxy* test_io_proxy = NULL; static GMainLoop* client_loop = NULL; static int n_running_children = 0; static BigDBusInputStream* input_from_io_service; static BigDBusOutputStream* output_to_io_service; static const char stream_data_to_io_service[] = "This is sent from the main test process to the IO service."; static const char stream_data_from_io_service[] = "This is sent from the IO " "service to the main test " "process. The quick brown " "fox, etc."; static void do_test_service_child(void); static void do_test_io_child(void); /* quit when all children are gone */ static void another_child_down(void) { g_assert(n_running_children > 0); n_running_children -= 1; if (n_running_children == 0) { g_main_loop_quit(client_loop); } } static const char* extract_string_arg(DBusMessageIter* in_iter, const char* prop_name, DBusError* error) { const char* s; s = NULL; while (dbus_message_iter_get_arg_type(in_iter) == DBUS_TYPE_DICT_ENTRY) { DBusMessageIter entry_iter, variant_iter; const char* key; dbus_message_iter_recurse(in_iter, &entry_iter); dbus_message_iter_get_basic(&entry_iter, &key); if (strcmp(key, prop_name) == 0) { dbus_message_iter_next(&entry_iter); dbus_message_iter_recurse(&entry_iter, &variant_iter); if (dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_STRING) { dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "Value of '%s' prop should be a string", prop_name); return NULL; } dbus_message_iter_get_basic(&variant_iter, &s); return s; } } dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "No '%s' prop provided", prop_name); return NULL; } static void fork_child_test_service(void) { pid_t child_pid; /* it would break to fork after we already connected */ g_assert(session_bus_weak_ref == NULL); g_assert(system_bus_weak_ref == NULL); g_assert(test_service_pid == 0); child_pid = fork(); if (child_pid == -1) { g_error("Failed to fork dbus service"); } else if (child_pid > 0) { /* We are the parent */ test_service_pid = child_pid; n_running_children += 1; return; } /* we are the child, set up a service for main test process to talk to */ do_test_service_child(); } /* This test function doesn't really test anything, just sets up * for the following one */ static void fork_child_test_io(void) { pid_t child_pid; /* it would break to fork after we already connected */ g_assert(session_bus_weak_ref == NULL); g_assert(system_bus_weak_ref == NULL); g_assert(test_io_pid == 0); child_pid = fork(); if (child_pid == -1) { g_error("Failed to fork dbus service"); } else if (child_pid > 0) { /* We are the parent */ test_io_pid = child_pid; n_running_children += 1; return; } /* we are the child, set up a service for main test process to talk to */ do_test_io_child(); } static void on_expected_fnf_error_reply_kill_child(BigDBusProxy* proxy, const char* error_name, const char* error_message, void* data) { big_debug(BIG_DEBUG_IN_TESTS, "got expected error reply to alwaysErrorSync, killing child"); /* We were expecting an error, good. */ if (strcmp(error_name, DBUS_ERROR_FILE_NOT_FOUND) != 0) { g_error("Got error we did not expect %s: %s", error_name, error_message); } if (kill(test_service_pid, SIGTERM) < 0) { g_error("Test service was no longer around... it must have failed " "somehow (%s)", strerror(errno)); } /* We will quit main loop when we see the child go away */ } static void on_unexpected_error_reply(BigDBusProxy* proxy, const char* error_name, const char* error_message, void* data) { const char* context_text = data; g_error("Got error %s: '%s' context was: %s", error_name, error_message, context_text); } static void on_get_always_error_reply(BigDBusProxy* proxy, DBusMessage* message, DBusMessageIter* return_value_iter, void* data) { g_error("alwaysError json method supposed to return an error always, not a " "valid reply"); } static void on_get_some_stuff_reply(BigDBusProxy* proxy, DBusMessage* message, DBusMessageIter* return_value_iter, void* data) { big_debug(BIG_DEBUG_IN_TESTS, "reply received to getSomeStuffSync"); /* FIXME look at the return value to see if it's what * the test service sends */ big_dbus_proxy_call_json_async(test_service_proxy, "alwaysErrorSync", on_get_always_error_reply, on_expected_fnf_error_reply_kill_child, NULL, NULL); } static void on_test_service_appeared(DBusConnection* connection, const char* name, const char* new_owner_unique_name, void* data) { dbus_int32_t v_INT32; big_debug(BIG_DEBUG_IN_TESTS, "%s appeared", name); test_service_proxy = big_dbus_proxy_new(connection, new_owner_unique_name, "/com/litl/test/object42", "com.litl.TestIface"); v_INT32 = 42; big_dbus_proxy_call_json_async( test_service_proxy, "getSomeStuffSync", on_get_some_stuff_reply, on_unexpected_error_reply, "getSomeStuffSync call from on_test_service_appeared", "yourNameIs", DBUS_TYPE_STRING, &name, "yourUniqueNameIs", DBUS_TYPE_STRING, &new_owner_unique_name, "anIntegerIs", DBUS_TYPE_INT32, &v_INT32, NULL); } static void on_test_service_vanished(DBusConnection* connection, const char* name, const char* old_owner_unique_name, void* data) { big_debug(BIG_DEBUG_IN_TESTS, "%s vanished", name); another_child_down(); } static BigDBusWatchNameFuncs watch_test_service_funcs = { on_test_service_appeared, on_test_service_vanished }; static void on_confirm_streams_reply(BigDBusProxy* proxy, DBusMessage* message, DBusMessageIter* return_value_iter, void* data) { const char* received; received = extract_string_arg(return_value_iter, "received", NULL); g_assert(received != NULL); if (strcmp(received, stream_data_to_io_service) != 0) { g_error("We sent the child process '%s' but it says it got '%s'", stream_data_to_io_service, received); } big_debug(BIG_DEBUG_IN_TESTS, "com.litl.TestIO says it got: '%s'", received); /* We've exchanged all our streams - time to kill the TestIO * child process */ big_debug(BIG_DEBUG_IN_TESTS, "Sending TERM to TestIO child"); if (kill(test_io_pid, SIGTERM) < 0) { g_error("Test IO service was no longer around... it must have failed " "somehow (%s)", strerror(errno)); } } static void on_setup_streams_reply(BigDBusProxy* proxy, DBusMessage* message, DBusMessageIter* return_value_iter, void* data) { const char* stream_path; gsize total; gssize result; gsize read_size; GError* error; GString* str; char buf[10]; big_debug(BIG_DEBUG_IN_TESTS, "Got reply to setupStreams"); stream_path = extract_string_arg(return_value_iter, "stream", NULL); g_assert(stream_path != NULL); output_to_io_service = big_dbus_output_stream_new(big_dbus_proxy_get_connection(proxy), dbus_message_get_sender(message), stream_path); g_assert(input_from_io_service && output_to_io_service); /* Write to the output stream */ total = strlen(stream_data_to_io_service); error = NULL; result = g_output_stream_write(G_OUTPUT_STREAM(output_to_io_service), stream_data_to_io_service, 10, NULL, &error); if (result < 0) { g_error("Error writing to output stream: %s", error->message); g_error_free(error); } if (result != 10) { g_error("Wrote %d instead of 10 bytes", (int) result); } if (!g_output_stream_write_all(G_OUTPUT_STREAM(output_to_io_service), stream_data_to_io_service + 10, total - 10, NULL, NULL, &error)) { g_error("Error writing all to output stream: %s", error->message); g_error_free(error); } /* flush should do nothing here, and is not needed, but * just calling it to test it */ if (!g_output_stream_flush(G_OUTPUT_STREAM(output_to_io_service), NULL, &error)) { g_error("Error flushing output stream: %s", error->message); g_error_free(error); } if (!g_output_stream_close(G_OUTPUT_STREAM(output_to_io_service), NULL, &error)) { g_error("Error closing output stream: %s", error->message); g_error_free(error); } g_object_unref(output_to_io_service); output_to_io_service = NULL; /* Now read from the input stream - in an inefficient way to be sure * we test multiple, partial reads */ read_size = 1; str = g_string_new(NULL); while (TRUE) { /* test get_received() */ g_assert(big_dbus_input_stream_get_received(input_from_io_service) <= strlen(stream_data_from_io_service)); /* This is a blocking read... in production code, you would * want to use the ready-to-read signal instead to avoid * blocking when there is nothing to read. */ result = g_input_stream_read(G_INPUT_STREAM(input_from_io_service), buf, read_size, NULL, &error); if (result < 0) { g_error("Error reading %d bytes from input stream: %s", (int) read_size, error->message); g_error_free(error); } if (result == 0) { /* EOF */ break; } g_string_append_len(str, buf, result); if (read_size < sizeof(buf)) read_size += 1; } if (!g_input_stream_close(G_INPUT_STREAM(input_from_io_service), NULL, &error)) { g_error("Error closing input stream: %s", error->message); g_error_free(error); } g_object_unref(input_from_io_service); input_from_io_service = NULL; /* Now make the confirmStreams call */ big_debug(BIG_DEBUG_IN_TESTS, "Confirming to com.litl.TestIO we got: '%s'", str->str); big_dbus_proxy_call_json_async( test_io_proxy, "confirmStreamsData", on_confirm_streams_reply, on_unexpected_error_reply, "confirmStreamsData call from on_setup_streams_reply", "received", DBUS_TYPE_STRING, &str->str, NULL); g_string_free(str, TRUE); } static void on_test_io_appeared(DBusConnection* connection, const char* name, const char* new_owner_unique_name, void* data) { const char* stream_path; big_debug(BIG_DEBUG_IN_TESTS, "%s appeared", name); test_io_proxy = big_dbus_proxy_new(connection, new_owner_unique_name, "/com/litl/test/object47", "com.litl.TestIO"); input_from_io_service = g_object_new(BIG_TYPE_DBUS_INPUT_STREAM, NULL); big_dbus_input_stream_attach(input_from_io_service, connection); stream_path = big_dbus_input_stream_get_path(input_from_io_service); big_dbus_proxy_call_json_async(test_io_proxy, "setupStreams", on_setup_streams_reply, on_unexpected_error_reply, "setupStreams call from on_test_io_appeared", "stream", DBUS_TYPE_STRING, &stream_path, NULL); } static void on_test_io_vanished(DBusConnection* connection, const char* name, const char* old_owner_unique_name, void* data) { big_debug(BIG_DEBUG_IN_TESTS, "%s vanished", name); another_child_down(); } static BigDBusWatchNameFuncs watch_test_io_funcs = { on_test_io_appeared, on_test_io_vanished }; void bigtest_test_func_util_dbus_client(void) { pid_t result; int status; /* We have to fork() to avoid creating the DBusConnection* * and thus preventing other dbus-using tests from forking * children. This dbus bug, when the fix makes it into Ubuntu, * should solve the problem: * https://bugs.freedesktop.org/show_bug.cgi?id=15570 * * The symptom of that bug is failure to connect to the bus in * dbus-signals.c tests. The symptom of opening a connection * before forking children is the connection FD shared among * multiple processes, i.e. huge badness. */ if (!g_test_trap_fork(0, 0)) { /* We are the parent */ g_test_trap_assert_passed(); return; } /* All this stuff runs in the forked child only */ fork_child_test_service(); fork_child_test_io(); g_type_init(); g_assert(test_service_pid != 0); g_assert(test_io_pid != 0); big_dbus_watch_name(DBUS_BUS_SESSION, "com.litl.TestService", 0, &watch_test_service_funcs, NULL); big_dbus_watch_name(DBUS_BUS_SESSION, "com.litl.TestIO", 0, &watch_test_io_funcs, NULL); client_loop = g_main_loop_new(NULL, FALSE); g_main_loop_run(client_loop); if (test_service_proxy != NULL) g_object_unref(test_service_proxy); if (test_io_proxy != NULL) g_object_unref(test_io_proxy); /* child was killed already, or should have been */ big_debug(BIG_DEBUG_IN_TESTS, "waitpid() for first child"); result = waitpid(test_service_pid, &status, 0); if (result < 0) { g_error("Failed to waitpid() for forked child: %s", strerror(errno)); } if (WIFEXITED(status) && WEXITSTATUS(status) != 0) { g_error("Forked dbus service child exited with error code %d", WEXITSTATUS(status)); } if (WIFSIGNALED(status) && WTERMSIG(status) != SIGTERM) { g_error("Forked dbus service child exited on wrong signal number %d", WTERMSIG(status)); } big_debug(BIG_DEBUG_IN_TESTS, "waitpid() for second child"); result = waitpid(test_io_pid, &status, 0); if (result < 0) { g_error("Failed to waitpid() for forked child: %s", strerror(errno)); } if (WIFEXITED(status) && WEXITSTATUS(status) != 0) { g_error("Forked dbus service child exited with error code %d", WEXITSTATUS(status)); } if (WIFSIGNALED(status) && WTERMSIG(status) != SIGTERM) { g_error("Forked dbus service child exited on wrong signal number %d", WTERMSIG(status)); } big_debug(BIG_DEBUG_IN_TESTS, "dbus client test completed"); /* We want to kill dbus so the weak refs are NULL to start the * next dbus-related test, which allows those tests * to fork new child processes. */ _big_dbus_dispose_info(_big_dbus_get_weak_ref(DBUS_BUS_SESSION)); dbus_shutdown(); big_debug(BIG_DEBUG_IN_TESTS, "dbus shut down"); /* FIXME this is here only while we need g_test_trap_fork(), * see comment above. */ exit(0); } /* * First child service we forked, tests general dbus API */ static gboolean currently_have_test_service = FALSE; static GObject* test_service_object = NULL; static void test_service_get_some_stuff_sync(DBusConnection* connection, DBusMessage* message, DBusMessageIter* in_iter, DBusMessageIter* out_iter, void* data, DBusError* error) { big_debug(BIG_DEBUG_IN_TESTS, "com.litl.TestService got getSomeStuffSync"); g_assert(G_IS_OBJECT(data)); big_dbus_append_json_entry_BOOLEAN(out_iter, "haveTestService", currently_have_test_service); } static void test_service_always_error_sync(DBusConnection* connection, DBusMessage* message, DBusMessageIter* in_iter, DBusMessageIter* out_iter, void* data, DBusError* error) { big_debug(BIG_DEBUG_IN_TESTS, "com.litl.TestService got alwaysErrorSync"); g_assert(G_IS_OBJECT(data)); dbus_set_error(error, DBUS_ERROR_FILE_NOT_FOUND, "Did not find some kind of file! Help!"); } static BigDBusJsonMethod test_service_methods[] = { { "getSomeStuffSync", test_service_get_some_stuff_sync, NULL }, { "alwaysErrorSync", test_service_always_error_sync, NULL } }; static void on_test_service_acquired(DBusConnection* connection, const char* name, void* data) { g_assert(!currently_have_test_service); currently_have_test_service = TRUE; big_debug(BIG_DEBUG_IN_TESTS, "com.litl.TestService acquired by child"); big_dbus_register_json(connection, "com.litl.TestIface", test_service_methods, G_N_ELEMENTS(test_service_methods)); test_service_object = g_object_new(G_TYPE_OBJECT, NULL); big_dbus_register_g_object(connection, "/com/litl/test/object42", test_service_object, "com.litl.TestIface"); } static void on_test_service_lost(DBusConnection* connection, const char* name, void* data) { g_assert(currently_have_test_service); currently_have_test_service = FALSE; big_debug(BIG_DEBUG_IN_TESTS, "com.litl.TestService lost by child"); big_dbus_unregister_g_object(connection, "/com/litl/test/object42"); big_dbus_unregister_json(connection, "com.litl.TestIface"); } static BigDBusNameOwnerFuncs test_service_funcs = { "com.litl.TestService", BIG_DBUS_NAME_SINGLE_INSTANCE, on_test_service_acquired, on_test_service_lost }; static void do_test_service_child(void) { GMainLoop* loop; g_type_init(); loop = g_main_loop_new(NULL, FALSE); big_dbus_acquire_name(DBUS_BUS_SESSION, &test_service_funcs, NULL); g_main_loop_run(loop); /* Don't return to the test program main() */ exit(0); } /* * Second child service we forked, tests IO streams */ static gboolean currently_have_test_io = FALSE; static GObject* test_io_object = NULL; static BigDBusInputStream* io_input_stream = NULL; static BigDBusOutputStream* io_output_stream = NULL; static GString* input_buffer = NULL; static void test_io_confirm_streams_data(DBusConnection* connection, DBusMessage* message, DBusMessageIter* in_iter, DBusMessageIter* out_iter, void* data, DBusError* error) { const char* received; big_debug(BIG_DEBUG_IN_TESTS, "com.litl.TestIO got confirmStreamsData"); g_assert(G_IS_OBJECT(data)); received = extract_string_arg(in_iter, "received", error); if (received == NULL) { g_assert(error == NULL || dbus_error_is_set(error)); return; } if (strcmp(received, stream_data_from_io_service) != 0) { g_error("We sent the main process '%s' but it says it got '%s'", stream_data_from_io_service, received); return; } /* We were reading from the main process in the main loop. * As a hack, we'll block in the main loop here to test. * In a real app, never block in the main loop; you would * just plain block, e.g. in g_input_stream_read(), if * you wanted to block. But don't block. */ while (io_input_stream != NULL) { g_main_context_iteration(NULL, TRUE); } big_dbus_append_json_entry_STRING(out_iter, "received", input_buffer->str); g_string_free(input_buffer, TRUE); input_buffer = NULL; } static void on_input_ready(BigDBusInputStream* dbus_stream, void* data) { GInputStream* stream; char buf[3]; gssize result; GError* error; stream = G_INPUT_STREAM(dbus_stream); g_assert(dbus_stream == io_input_stream); /* test get_received() */ g_assert(big_dbus_input_stream_get_received(dbus_stream) <= strlen(stream_data_to_io_service)); /* Should not block, since we got the ready-to-read signal */ error = NULL; result = g_input_stream_read(G_INPUT_STREAM(io_input_stream), buf, sizeof(buf), NULL, &error); if (result < 0) { g_error("Error reading bytes from input stream: %s", error->message); g_error_free(error); } if (result == 0) { /* EOF */ if (!g_input_stream_close(G_INPUT_STREAM(io_input_stream), NULL, &error)) { g_error("Error closing input stream in child: %s", error->message); g_error_free(error); } g_object_unref(io_input_stream); io_input_stream = NULL; return; } g_string_append_len(input_buffer, buf, result); /* We should automatically get another callback if there's more data or EOF * was not yet reached. */ } static void test_io_setup_streams(DBusConnection* connection, DBusMessage* message, DBusMessageIter* in_iter, DBusMessageIter* out_iter, void* data, DBusError* error) { const char* stream_path; gsize total; gsize remaining; gssize result; GError* gerror; big_debug(BIG_DEBUG_IN_TESTS, "com.litl.TestIO got setupStreams"); g_assert(G_IS_OBJECT(data)); stream_path = extract_string_arg(in_iter, "stream", error); if (stream_path == NULL) { g_assert(error == NULL || dbus_error_is_set(error)); return; } /* Create output stream to write to caller's path */ io_output_stream = big_dbus_output_stream_new(connection, dbus_message_get_sender(message), stream_path); /* Create input stream and return its path to caller */ io_input_stream = g_object_new(BIG_TYPE_DBUS_INPUT_STREAM, NULL); big_dbus_input_stream_attach(io_input_stream, connection); stream_path = big_dbus_input_stream_get_path(io_input_stream); big_dbus_append_json_entry_STRING(out_iter, "stream", stream_path); /* Set up callbacks to read input stream in an async way */ input_buffer = g_string_new(NULL); g_signal_connect(io_input_stream, "ready-to-read", G_CALLBACK(on_input_ready), NULL); /* Write to output stream */ gerror = NULL; total = strlen(stream_data_from_io_service); remaining = total; while (remaining > 0) { /* One byte at a time, fun torture test, totally silly in real * code of course */ result = g_output_stream_write(G_OUTPUT_STREAM(io_output_stream), stream_data_from_io_service + (total - remaining), 1, NULL, &gerror); if (result < 0) { g_assert(gerror != NULL); g_error("Error writing to output stream: %s", gerror->message); g_error_free(gerror); } if (result != 1) { g_error("Wrote %d instead of 1 bytes", (int) result); } remaining -= 1; } /* flush should do nothing here, and is not needed, but * just calling it to test it */ if (!g_output_stream_flush(G_OUTPUT_STREAM(io_output_stream), NULL, &gerror)) { g_assert(gerror != NULL); g_error("Error flushing output stream: %s", gerror->message); g_error_free(gerror); } if (!g_output_stream_close(G_OUTPUT_STREAM(io_output_stream), NULL, &gerror)) { g_assert(gerror != NULL); g_error("Error closing output stream: %s", gerror->message); g_error_free(gerror); } g_object_unref(io_output_stream); io_output_stream = NULL; /* Now return, and wait for our input stream data to come in from * the main process */ } static BigDBusJsonMethod test_io_methods[] = { { "setupStreams", test_io_setup_streams, NULL }, { "confirmStreamsData", test_io_confirm_streams_data, NULL } }; static void on_test_io_acquired(DBusConnection* connection, const char* name, void* data) { g_assert(!currently_have_test_io); currently_have_test_io = TRUE; big_debug(BIG_DEBUG_IN_TESTS, "com.litl.TestIO acquired by child"); big_dbus_register_json(connection, "com.litl.TestIO", test_io_methods, G_N_ELEMENTS(test_io_methods)); test_io_object = g_object_new(G_TYPE_OBJECT, NULL); big_dbus_register_g_object(connection, "/com/litl/test/object47", test_io_object, "com.litl.TestIO"); } static void on_test_io_lost(DBusConnection* connection, const char* name, void* data) { g_assert(currently_have_test_io); currently_have_test_io = FALSE; big_debug(BIG_DEBUG_IN_TESTS, "com.litl.TestIO lost by child"); big_dbus_unregister_g_object(connection, "/com/litl/test/object47"); big_dbus_unregister_json(connection, "com.litl.TestIO"); } static BigDBusNameOwnerFuncs test_io_funcs = { "com.litl.TestIO", BIG_DBUS_NAME_SINGLE_INSTANCE, on_test_io_acquired, on_test_io_lost }; static void do_test_io_child(void) { GMainLoop* loop; g_type_init(); loop = g_main_loop_new(NULL, FALSE); big_dbus_acquire_name(DBUS_BUS_SESSION, &test_io_funcs, NULL); g_main_loop_run(loop); /* Don't return to the test program main() */ exit(0); } #endif /* BIG_BUILD_TESTS */ seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/dbus/util/dbus.h000066400000000000000000000205371303774616400233250ustar00rootroot00000000000000/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ /* Copyright 2008 litl, LLC. All Rights Reserved. */ #ifndef __BIG_UTIL_DBUS_H__ #define __BIG_UTIL_DBUS_H__ #include #include G_BEGIN_DECLS /* Convenience macro */ #define BIG_DBUS_NAME_FROM_TYPE(type) \ ((type) == DBUS_BUS_SESSION ? "session" : "system") /* Error names */ #define BIG_DBUS_ERROR_STREAM_RECEIVER_CLOSED \ "com.litl.Error.Stream.ReceiverClosed" /* * Monitor whether we are connected / not-connected to the bus */ typedef void (*BigDBusConnectionOpenedFunc)(DBusConnection* connection, void* data); typedef void (*BigDBusConnectionClosedFunc)(DBusConnection* connection, void* data); typedef struct { DBusBusType which_bus; BigDBusConnectionOpenedFunc opened; BigDBusConnectionClosedFunc closed; } BigDBusConnectFuncs; void big_dbus_add_connect_funcs(const BigDBusConnectFuncs* funcs, void* data); void big_dbus_remove_connect_funcs(const BigDBusConnectFuncs* funcs, void* data); void big_dbus_add_connect_funcs_sync_notify(const BigDBusConnectFuncs* funcs, void* data); void big_dbus_add_bus_weakref(DBusBusType bus_type, DBusConnection** connection_p); void big_dbus_remove_bus_weakref(DBusBusType bus_type, DBusConnection** connection_p); void big_dbus_try_connecting_now(DBusBusType which_bus); /* * Own a bus name * */ typedef enum { BIG_DBUS_NAME_SINGLE_INSTANCE, BIG_DBUS_NAME_MANY_INSTANCES } BigDBusNameType; typedef void (*BigDBusNameAcquiredFunc)(DBusConnection* connection, const char* name, void* data); typedef void (*BigDBusNameLostFunc)(DBusConnection* connection, const char* name, void* data); typedef struct { const char* name; BigDBusNameType type; BigDBusNameAcquiredFunc acquired; BigDBusNameLostFunc lost; } BigDBusNameOwnerFuncs; guint big_dbus_acquire_name(DBusBusType bus_type, const BigDBusNameOwnerFuncs* funcs, void* data); void big_dbus_release_name(DBusBusType bus_type, const BigDBusNameOwnerFuncs* funcs, void* data); void big_dbus_release_name_by_id(DBusBusType bus_type, guint id); /* * Keep track of someone else's bus name * */ typedef enum { BIG_DBUS_NAME_START_IF_NOT_FOUND = 0x1 } BigDBusWatchNameFlags; typedef void (*BigDBusNameAppearedFunc)(DBusConnection* connection, const char* name, const char* new_owner_unique_name, void* data); typedef void (*BigDBusNameVanishedFunc)(DBusConnection* connection, const char* name, const char* old_owner_unique_name, void* data); typedef struct { BigDBusNameAppearedFunc appeared; BigDBusNameVanishedFunc vanished; } BigDBusWatchNameFuncs; void big_dbus_watch_name(DBusBusType bus_type, const char* name, BigDBusWatchNameFlags flags, const BigDBusWatchNameFuncs* funcs, void* data); void big_dbus_unwatch_name(DBusBusType bus_type, const char* name, const BigDBusWatchNameFuncs* funcs, void* data); const char* big_dbus_get_watched_name_owner(DBusBusType bus_type, const char* name); typedef void (*BigDBusSignalHandler)(DBusConnection* connection, DBusMessage* message, void* data); int big_dbus_watch_signal(DBusBusType bus_type, const char* sender, const char* path, const char* iface, const char* name, BigDBusSignalHandler handler, void* data, GDestroyNotify data_dnotify); void big_dbus_unwatch_signal(DBusBusType bus_type, const char* sender, const char* path, const char* iface, const char* name, BigDBusSignalHandler handler, void* data); void big_dbus_unwatch_signal_by_id(DBusBusType bus_type, int id); /* A "json method" is a D-Bus method with signature * DICT jsonMethodName(DICT) * with the idea that it both takes and returns * a JavaScript-style dictionary. This makes * our JavaScript-to-dbus bindings really simple, * and avoids a lot of futzing with dbus IDL. * * Of course it's completely annoying for someone * using D-Bus in a "normal" way but the idea is just * to use this to communicate within our own app * that happens to consist of multiple processes * and have bits written in JS. */ typedef void (*BigDBusJsonSyncMethodFunc)(DBusConnection* connection, DBusMessage* message, DBusMessageIter* in_iter, DBusMessageIter* out_iter, void* data, DBusError* error); typedef void (*BigDBusJsonAsyncMethodFunc)(DBusConnection* connection, DBusMessage* message, DBusMessageIter* in_iter, void* data); typedef struct { const char* name; /* one of these two but not both should be non-NULL */ BigDBusJsonSyncMethodFunc sync_func; BigDBusJsonAsyncMethodFunc async_func; } BigDBusJsonMethod; void big_dbus_register_json(DBusConnection* connection, const char* iface_name, const BigDBusJsonMethod* methods, int n_methods); void big_dbus_unregister_json(DBusConnection* connection, const char* iface_name); void big_dbus_register_g_object(DBusConnection* connection, const char* path, GObject* gobj, const char* iface_name); void big_dbus_unregister_g_object(DBusConnection* connection, const char* path); void big_dbus_append_json_entry(DBusMessageIter* dict_iter, const char* key, int dbus_type, void* basic_value_p); void big_dbus_append_json_entry_STRING(DBusMessageIter* dict_iter, const char* key, const char* value); void big_dbus_append_json_entry_INT32(DBusMessageIter* dict_iter, const char* key, dbus_int32_t value); void big_dbus_append_json_entry_DOUBLE(DBusMessageIter* dict_iter, const char* key, double value); void big_dbus_append_json_entry_BOOLEAN(DBusMessageIter* dict_iter, const char* key, dbus_bool_t value); void big_dbus_append_json_entry_EMPTY_ARRAY(DBusMessageIter* dict_iter, const char* key); void big_dbus_append_json_entry_STRING_ARRAY(DBusMessageIter* dict_iter, const char* key, const char** value); gboolean big_dbus_message_iter_get_gsize(DBusMessageIter* iter, gsize* value_p); gboolean big_dbus_message_iter_get_gssize(DBusMessageIter* iter, gssize* value_p); void big_dbus_start_service(DBusConnection* connection, const char* name); G_END_DECLS #endif /* __BIG_UTIL_DBUS_H__ */ seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/dbus/util/log.h000066400000000000000000000000731303774616400231420ustar00rootroot00000000000000#define BIG_DEBUG_UTIL_DBUS 1 #define big_debug(type, ...) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/example/000077500000000000000000000000001303774616400217315ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/example/Makefile.am000066400000000000000000000010251303774616400237630ustar00rootroot00000000000000if BUILD_EXAMPLE_MODULE seedlibdir = ${libdir}/seed@SEED_GTK_VERSION@ seedlib_LTLIBRARIES = \ libseed_example.la libseed_example_la_SOURCES = \ seed-example.c AM_CPPFLAGS = \ -I@top_srcdir@/libseed/ \ $(GOBJECT_INTROSPECTION_CFLAGS) \ $(SEED_DEBUG_CFLAGS) \ $(SEED_PROFILE_CFLAGS) libseed_example_la_LDFLAGS = \ -module -avoid-version \ $(GOBJECT_INTROSPECTION_LDFLAGS) libseed_example_la_LIBADD = \ $(top_builddir)/libseed/libseed@SEED_GTK_VERSION@.la \ $(SEED_PROFILE_LIBS) endif -include $(top_srcdir)/git.mk seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/example/seed-example.c000066400000000000000000000020301303774616400244410ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #include #include SeedObject seed_module_init(SeedEngine* eng) { g_print("Hello Seed Module World\n"); return seed_make_object(eng->context, NULL, NULL); } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/ffi/000077500000000000000000000000001303774616400210425ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/ffi/Makefile.am000066400000000000000000000012041303774616400230730ustar00rootroot00000000000000if BUILD_FFI_MODULE seedlibdir = ${libdir}/seed@SEED_GTK_VERSION@ EXTRA_DIST = \ test-sin.js \ test-strcmp.js \ test-strdup.js \ test-xlib.js seedlib_LTLIBRARIES = \ libseed_ffi.la libseed_ffi_la_SOURCES = \ seed-ffi.c libseed_ffi_la_CFLAGS = \ -I@top_srcdir@/libseed/ \ -Wall \ $(GOBJECT_INTROSPECTION_CFLAGS) \ $(SEED_DEBUG_CFLAGS) \ $(SEED_PROFILE_CFLAGS) \ $(FFI_CFLAGS) libseed_ffi_la_LDFLAGS = \ -module -avoid-version \ $(GOBJECT_INTROSPECTION_LDFLAGS) \ $(FFI_LDFLAGS) libseed_ffi_la_LIBADD = \ $(top_builddir)/libseed/libseed@SEED_GTK_VERSION@.la \ $(SEED_PROFILE_LIBS) endif -include $(top_srcdir)/git.mk seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/ffi/seed-ffi.c000066400000000000000000000376401303774616400227020ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #include #include #include SeedEngine* eng; SeedObject namespace_ref; SeedClass ffi_library_class; SeedClass ffi_function_class; typedef struct _seed_ffi_function_priv { gchar* name; gpointer symbol; GType* args; gint n_args; GType ret_val; SeedObject signature_obj; SeedObject module_obj; } seed_ffi_function_priv; typedef struct _seed_ffi_library_priv { GModule* mod; GHashTable* symbols; } seed_ffi_library_priv; static ffi_type* gtype_to_ffi_type(SeedContext ctx, SeedValue value, GType otype, GArgument* garg, gpointer* arg, SeedException* exception) { ffi_type* return_type; GType type = g_type_fundamental(otype); g_assert(type != G_TYPE_INVALID); switch (type) { case G_TYPE_BOOLEAN: case G_TYPE_CHAR: case G_TYPE_INT: return_type = &ffi_type_sint; garg->v_int = seed_value_to_int(ctx, value, exception); *arg = (gpointer) garg; break; case G_TYPE_UCHAR: case G_TYPE_UINT: return_type = &ffi_type_uint; garg->v_uint = seed_value_to_uint(ctx, value, exception); *arg = (gpointer) garg; break; case G_TYPE_STRING: return_type = &ffi_type_pointer; garg->v_pointer = seed_value_to_string(ctx, value, exception); *arg = (gpointer) garg; break; case G_TYPE_OBJECT: // case G_TYPE_BOXED: case G_TYPE_POINTER: return_type = &ffi_type_pointer; garg->v_pointer = seed_pointer_get_pointer(ctx, value); *arg = (gpointer) garg; break; case G_TYPE_FLOAT: return_type = &ffi_type_float; garg->v_float = seed_value_to_float(ctx, value, exception); *arg = (gpointer) garg; break; case G_TYPE_DOUBLE: return_type = &ffi_type_double; garg->v_double = seed_value_to_double(ctx, value, exception); *arg = (gpointer) garg; break; case G_TYPE_LONG: return_type = &ffi_type_slong; garg->v_uint = seed_value_to_uint(ctx, value, exception); *arg = (gpointer) garg; break; case G_TYPE_ULONG: return_type = &ffi_type_ulong; garg->v_ulong = seed_value_to_ulong(ctx, value, exception); *arg = (gpointer) garg; break; case G_TYPE_INT64: return_type = &ffi_type_sint64; garg->v_int64 = seed_value_to_int64(ctx, value, exception); *arg = (gpointer) garg; break; case G_TYPE_UINT64: return_type = &ffi_type_uint64; garg->v_uint64 = seed_value_to_uint64(ctx, value, exception); *arg = (gpointer) garg; break; default: g_warning("Unsupported fundamental in type: %s", g_type_name(type)); return_type = &ffi_type_pointer; garg->v_pointer = NULL; *arg = (garg->v_pointer); break; } return return_type; } static ffi_type* return_type_to_ffi_type(GType otype) { GType type = g_type_fundamental(otype); g_assert(type != G_TYPE_INVALID); switch (type) { case G_TYPE_BOOLEAN: case G_TYPE_CHAR: case G_TYPE_INT: return &ffi_type_sint; break; case G_TYPE_UCHAR: case G_TYPE_UINT: return &ffi_type_uint; break; case G_TYPE_STRING: return &ffi_type_pointer; break; case G_TYPE_OBJECT: // case G_TYPE_BOXED: case G_TYPE_POINTER: return &ffi_type_pointer; break; case G_TYPE_FLOAT: return &ffi_type_float; break; case G_TYPE_DOUBLE: return &ffi_type_double; break; case G_TYPE_LONG: return &ffi_type_slong; break; case G_TYPE_ULONG: return &ffi_type_ulong; break; case G_TYPE_INT64: return &ffi_type_sint64; break; case G_TYPE_UINT64: return &ffi_type_uint64; break; default: g_warning("Unsupported fundamental out type: %s", g_type_name(type)); return &ffi_type_pointer; break; } } static SeedValue seed_ffi_get_signature(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedException* exception) { seed_ffi_function_priv* priv = seed_object_get_private(this_object); if (priv->signature_obj) return priv->signature_obj; else return seed_make_null(ctx); } static gboolean seed_ffi_build_signature(SeedContext ctx, seed_ffi_function_priv* priv, SeedObject sig, SeedException* exception) { SeedObject arguments; SeedValue ret_type_ref, length_ref; guint length, i; arguments = seed_object_get_property(ctx, sig, "arguments"); ret_type_ref = seed_object_get_property(ctx, sig, "returns"); if (!seed_value_is_object(ctx, arguments)) { seed_make_exception(ctx, exception, "FFIError", "Signature arguments member must be an " "array describing argument types"); return FALSE; } length_ref = seed_object_get_property(ctx, arguments, "length"); length = seed_value_to_uint(ctx, length_ref, exception); priv->n_args = length; priv->args = g_slice_alloc(length * sizeof(GType)); for (i = 0; i < length; i++) { SeedValue type = seed_object_get_property_at_index(ctx, arguments, i, exception); priv->args[i] = seed_value_to_int(ctx, type, exception); } priv->ret_val = seed_value_to_int(ctx, ret_type_ref, exception); priv->signature_obj = sig; seed_value_protect(ctx, sig); return TRUE; } static gboolean seed_ffi_set_signature(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedValue value, SeedException* exception) { seed_ffi_function_priv* priv = seed_object_get_private(this_object); if (priv->signature_obj) { seed_make_exception(ctx, exception, "FFIError", "Can not reset signature of function once set"); return FALSE; } else if (!seed_value_is_object(ctx, value)) { seed_make_exception(ctx, exception, "FFIError", "Signature must be an object"); return FALSE; } else { if (!seed_ffi_build_signature(ctx, priv, (SeedObject) value, exception)) return FALSE; } return TRUE; } static void seed_ffi_function_finalize(SeedObject obj) { seed_ffi_function_priv* priv = seed_object_get_private(obj); if (priv->signature_obj) { seed_value_unprotect(eng->context, priv->signature_obj); g_slice_free1(priv->n_args * sizeof(GType), priv->args); } g_free(priv->name); g_slice_free1(sizeof(seed_ffi_function_priv), priv); seed_value_unprotect(eng->context, priv->module_obj); } static SeedObject seed_ffi_make_function(SeedContext ctx, SeedObject module_obj, gpointer symbol, const gchar* name, GHashTable* symbols) { SeedValue ret; seed_ffi_function_priv* priv = g_slice_alloc0(sizeof(seed_ffi_function_priv)); priv->symbol = symbol; priv->module_obj = module_obj; priv->name = g_strdup(name); ret = seed_make_object(ctx, ffi_function_class, priv); seed_value_protect(ctx, ret); g_hash_table_insert(symbols, g_strdup(name), ret); return ret; } static SeedValue value_from_ffi_type(SeedContext ctx, GType otype, GArgument* value, SeedException* exception) { switch (g_type_fundamental(otype)) { case G_TYPE_INT: return seed_value_from_int(ctx, value->v_int, exception); break; case G_TYPE_FLOAT: return seed_value_from_float(ctx, value->v_float, exception); break; case G_TYPE_DOUBLE: return seed_value_from_double(ctx, value->v_double, exception); break; case G_TYPE_BOOLEAN: return seed_value_from_boolean(ctx, value->v_boolean, exception); break; case G_TYPE_STRING: return seed_value_from_string(ctx, value->v_pointer, exception); break; case G_TYPE_CHAR: return seed_value_from_char(ctx, value->v_int, exception); break; case G_TYPE_UCHAR: return seed_value_from_uchar(ctx, value->v_uint, exception); break; case G_TYPE_UINT: return seed_value_from_uint(ctx, value->v_uint, exception); break; case G_TYPE_POINTER: return seed_make_pointer(ctx, value->v_pointer); break; case G_TYPE_LONG: return seed_value_from_long(ctx, value->v_long, exception); break; case G_TYPE_ULONG: return seed_value_from_ulong(ctx, value->v_ulong, exception); break; case G_TYPE_INT64: return seed_value_from_int64(ctx, value->v_int64, exception); break; case G_TYPE_UINT64: return seed_value_from_uint64(ctx, value->v_uint64, exception); break; case G_TYPE_NONE: return seed_make_null(ctx); default: g_warning("Unsupported fundamental type in value_from_ffi_type: %s", g_type_name(g_type_fundamental(otype))); return seed_make_null(ctx); } } static SeedValue seed_ffi_function_call(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { GArgument rvalue; GArgument* gargs; ffi_type* rtype; ffi_type** atypes; gpointer* args; int i; ffi_cif cif; seed_ffi_function_priv* priv = seed_object_get_private(function); if (argument_count != priv->n_args) { seed_make_exception(ctx, exception, "ArgumentError", "%s expected %d arguments got %zd", priv->name, priv->n_args, argument_count); return seed_make_null(ctx); } atypes = g_alloca(sizeof(ffi_type*) * (argument_count)); args = g_alloca(sizeof(gpointer) * (argument_count)); gargs = g_alloca(sizeof(GArgument) * (argument_count)); for (i = 0; i < argument_count; i++) { atypes[i] = gtype_to_ffi_type(ctx, arguments[i], priv->args[i], &(gargs[i]), &args[i], exception); } rtype = return_type_to_ffi_type(priv->ret_val); if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, argument_count, rtype, atypes) != FFI_OK) g_assert_not_reached(); ffi_call(&cif, priv->symbol, &rvalue, args); return value_from_ffi_type(ctx, priv->ret_val, &rvalue, exception); } static SeedValue seed_ffi_library_get_property(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedException* exception) { SeedValue ret; GModule* mod; gchar* prop; gsize len = seed_string_get_maximum_size(property_name); gpointer symbol; seed_ffi_library_priv* priv; prop = g_alloca(len); seed_string_to_utf8_buffer(property_name, prop, len); priv = seed_object_get_private(this_object); mod = priv->mod; if ((ret = g_hash_table_lookup(priv->symbols, prop))) return ret; if (!g_module_symbol(mod, prop, &symbol)) { return NULL; } return seed_ffi_make_function(ctx, this_object, symbol, prop, priv->symbols); } static SeedObject seed_ffi_construct_library(SeedContext ctx, SeedObject constructor, size_t argument_count, const SeedValue arguments[], SeedException* exception) { GModule* mod; SeedObject ret; gchar* filename; seed_ffi_library_priv* priv; if (argument_count != 1 && argument_count != 0) { seed_make_exception(ctx, exception, "ArgumentError", "ffi.Library constructor expects 1 argument " "(filename, or none to use NULL GModule), got %zd", argument_count); return seed_make_null(ctx); } if (argument_count == 1) filename = seed_value_to_string(ctx, arguments[0], exception); else filename = NULL; mod = g_module_open(filename, G_MODULE_BIND_LOCAL | G_MODULE_BIND_LAZY); if (!mod) { seed_make_exception(ctx, exception, "GModuleError", "Opening module (%s) failed with: %s", filename, g_module_error()); g_free(filename); return seed_make_null(ctx); } priv = g_slice_alloc(sizeof(seed_ffi_library_priv)); priv->mod = mod; // TODO: Value destroy function. priv->symbols = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); ret = seed_make_object(ctx, ffi_library_class, priv); g_free(filename); return ret; } static void seed_ffi_library_finalize(SeedObject obj) { seed_ffi_library_priv* priv; priv = seed_object_get_private(obj); g_module_close(priv->mod); } seed_static_value ffi_function_values[] = { { "signature", seed_ffi_get_signature, seed_ffi_set_signature, SEED_PROPERTY_ATTRIBUTE_DONT_DELETE }, { NULL, NULL, NULL, 0 } }; SeedObject seed_module_init(SeedEngine* local_eng) { SeedObject library_constructor; seed_class_definition ffi_library_def = seed_empty_class; seed_class_definition ffi_function_def = seed_empty_class; ffi_library_def.class_name = "FFILibrary"; ffi_library_def.finalize = seed_ffi_library_finalize; ffi_library_def.get_property = seed_ffi_library_get_property; ffi_function_def.class_name = "FFIFunction"; ffi_function_def.finalize = seed_ffi_function_finalize; ffi_function_def.static_values = ffi_function_values; ffi_function_def.call_as_function = seed_ffi_function_call; ffi_library_class = seed_create_class(&ffi_library_def); ffi_function_class = seed_create_class(&ffi_function_def); eng = local_eng; namespace_ref = seed_make_object(eng->context, NULL, NULL); library_constructor = seed_make_constructor(eng->context, ffi_library_class, seed_ffi_construct_library); seed_object_set_property(eng->context, namespace_ref, "Library", library_constructor); return namespace_ref; } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/ffi/test-sin.js000077500000000000000000000003411303774616400231470ustar00rootroot00000000000000#!/usr/bin/env seed GObject = imports.gi.GObject; ffi = imports.ffi; var app = new ffi.Library(); var sin = app.sin; sin.signature = {arguments: [GObject.TYPE_DOUBLE], returns: GObject.TYPE_DOUBLE}; print(sin(3.14)); seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/ffi/test-strcmp.js000077500000000000000000000005011303774616400236640ustar00rootroot00000000000000#!/usr/bin/env seed GObject = imports.gi.GObject; ffi = imports.ffi; var app = new ffi.Library(); var strcmp = app.strcmp; strcmp.signature = {arguments: [GObject.TYPE_STRING, GObject.TYPE_STRING], returns: GObject.TYPE_INT}; print(strcmp("Hi", "Hi")); print(strcmp("Boo", "Foo")); print(strcmp("Foo", "Boo")); seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/ffi/test-strdup.js000077500000000000000000000003571303774616400237060ustar00rootroot00000000000000#!/usr/bin/env seed GObject = imports.gi.GObject; ffi = imports.ffi; var app = new ffi.Library(); var strdup = app.strdup; strdup.signature = {arguments: [GObject.TYPE_STRING], returns: GObject.TYPE_STRING}; print(strdup("Hi")); seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/ffi/test-xlib.js000077500000000000000000000010471303774616400233200ustar00rootroot00000000000000#!/usr/bin/env seed GObject = imports.gi.GObject; ffi = imports.ffi; signatures = { "XOpenDisplay": {arguments: [GObject.TYPE_STRING], returns: GObject.TYPE_POINTER}, "XDefaultScreen": {arguments: [GObject.TYPE_POINTER], returns: GObject.TYPE_INT} }; var XLib = new ffi.Library("/usr/lib/libX11.so"); var XOpenDisplay = XLib.XOpenDisplay; var XDefaultScreen = XLib.XDefaultScreen; for (var i in signatures){ XLib[i].signature = signatures[i]; } display = XOpenDisplay(":0.0"); print(display); print(XDefaultScreen(display)); seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/gettext/000077500000000000000000000000001303774616400217625ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/gettext/Makefile.am000066400000000000000000000010251303774616400240140ustar00rootroot00000000000000if BUILD_GETTEXT_MODULE seedlibdir = ${libdir}/seed@SEED_GTK_VERSION@ seedlib_LTLIBRARIES = \ libseed_gettext.la libseed_gettext_la_SOURCES = \ seed-gettext.c AM_CPPFLAGS = \ -I@top_srcdir@/libseed/ \ $(GOBJECT_INTROSPECTION_CFLAGS) \ $(SEED_DEBUG_CFLAGS) \ $(SEED_PROFILE_CFLAGS) libseed_gettext_la_LDFLAGS = \ -module -avoid-version \ $(GOBJECT_INTROSPECTION_LDFLAGS) libseed_gettext_la_LIBADD = \ $(top_builddir)/libseed/libseed@SEED_GTK_VERSION@.la \ $(SEED_PROFILE_LIBS) endif -include $(top_srcdir)/git.mk seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/gettext/seed-gettext.c000066400000000000000000000242171303774616400245360ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #include #include #include SeedObject ns_ref; SeedEngine* eng; static SeedValue seed_gettext_gettext(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { gchar* msgid; SeedValue ret; CHECK_ARG_COUNT("gettext.gettext", 1); msgid = seed_value_to_string(ctx, arguments[0], exception); ret = seed_value_from_string(ctx, gettext(msgid), exception); g_free(msgid); return ret; } static SeedValue seed_gettext_textdomain(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { gchar* domain_name; SeedValue ret; CHECK_ARG_COUNT("gettext.textdomain", 1); domain_name = seed_value_to_string(ctx, arguments[0], exception); ret = seed_value_from_string(ctx, textdomain(domain_name), exception); g_free(domain_name); return ret; } static SeedValue seed_gettext_bindtextdomain(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { gchar *domainname, *dirname; SeedValue ret; CHECK_ARG_COUNT("gettext.bindtextdomain", 2); domainname = seed_value_to_string(ctx, args[0], exception); dirname = seed_value_to_string(ctx, args[1], exception); ret = seed_value_from_string(ctx, bindtextdomain(domainname, dirname), exception); g_free(domainname); g_free(dirname); return ret; } static SeedValue seed_gettext_bind_textdomain_codeset(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { gchar *domainname, *codeset; SeedValue ret; CHECK_ARG_COUNT("gettext.bind_textdomain_codeset", 2); domainname = seed_value_to_string(ctx, args[0], exception); codeset = seed_value_to_string(ctx, args[1], exception); ret = seed_value_from_string(ctx, bind_textdomain_codeset(domainname, codeset), exception); g_free(domainname); g_free(codeset); return ret; } static SeedValue seed_gettext_dgettext(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { gchar *domainname, *msgid; SeedValue ret; CHECK_ARG_COUNT("gettext.dgettext", 2); domainname = seed_value_to_string(ctx, args[0], exception); msgid = seed_value_to_string(ctx, args[1], exception); ret = seed_value_from_string(ctx, dgettext(domainname, msgid), exception); g_free(domainname); g_free(msgid); return ret; } static SeedValue seed_gettext_dcgettext(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { gchar *domainname, *msgid; gint category; SeedValue ret; CHECK_ARG_COUNT("gettext.dcgettext", 3); domainname = seed_value_to_string(ctx, args[0], exception); msgid = seed_value_to_string(ctx, args[1], exception); category = seed_value_to_int(ctx, args[2], exception); ret = seed_value_from_string(ctx, dcgettext(domainname, msgid, category), exception); g_free(domainname); g_free(msgid); return ret; } static SeedValue seed_gettext_ngettext(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { gchar *msgid, *msgid_plural; guint n; SeedValue ret; CHECK_ARG_COUNT("gettext.ngettext", 3); msgid = seed_value_to_string(ctx, args[0], exception); msgid_plural = seed_value_to_string(ctx, args[1], exception); n = seed_value_to_uint(ctx, args[2], exception); ret = seed_value_from_string(ctx, ngettext(msgid, msgid_plural, n), exception); g_free(msgid); g_free(msgid_plural); return ret; } static SeedValue seed_gettext_dngettext(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { gchar *domainname, *msgid, *msgid_plural; guint n; SeedValue ret; CHECK_ARG_COUNT("gettext.dngettext", 4); domainname = seed_value_to_string(ctx, args[0], exception); msgid = seed_value_to_string(ctx, args[1], exception); msgid_plural = seed_value_to_string(ctx, args[2], exception); n = seed_value_to_uint(ctx, args[3], exception); ret = seed_value_from_string(ctx, dngettext(domainname, msgid, msgid_plural, n), exception); g_free(domainname); g_free(msgid); g_free(msgid_plural); return ret; } static SeedValue seed_gettext_dcngettext(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { gchar *domainname, *msgid, *msgid_plural; guint n; gint category; SeedValue ret; CHECK_ARG_COUNT("gettext.dcngettext", 5); domainname = seed_value_to_string(ctx, args[0], exception); msgid = seed_value_to_string(ctx, args[1], exception); msgid_plural = seed_value_to_string(ctx, args[2], exception); n = seed_value_to_uint(ctx, args[3], exception); category = seed_value_to_int(ctx, args[4], exception); ret = seed_value_from_string(ctx, dcngettext(domainname, msgid, msgid_plural, n, category), exception); g_free(domainname); g_free(msgid); g_free(msgid_plural); return ret; } static SeedValue seed_gettext_setlocale(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { gchar* locale; gint category; SeedValue ret; CHECK_ARG_COUNT("gettext.setlocale", 2); category = seed_value_to_int(ctx, args[0], exception); locale = seed_value_to_string(ctx, args[1], exception); ret = seed_value_from_string(ctx, setlocale(category, locale), exception); g_free(locale); return ret; } seed_static_function gettext_funcs[] = { { "gettext", seed_gettext_gettext, 0 }, { "textdomain", seed_gettext_textdomain, 0 }, { "bindtextdomain", seed_gettext_bindtextdomain, 0 }, { "bind_textdomain_codeset", seed_gettext_bind_textdomain_codeset, 0 }, { "dgettext", seed_gettext_dgettext, 0 }, { "dcgettext", seed_gettext_dcgettext, 0 }, { "ngettext", seed_gettext_ngettext, 0 }, { "dngettext", seed_gettext_dngettext, 0 }, { "dcngettext", seed_gettext_dcngettext, 0 }, { "setlocale", seed_gettext_setlocale, 0 }, { "gettext", seed_gettext_gettext, 0 }, { NULL, NULL, 0 } }; SeedObject seed_module_init(SeedEngine* local_eng) { SeedGlobalContext ctx = local_eng->context; seed_class_definition gettext_ns_class_def = seed_empty_class; gettext_ns_class_def.static_functions = gettext_funcs; SeedClass gettext_ns_class = seed_create_class(&gettext_ns_class_def); ns_ref = seed_make_object(ctx, gettext_ns_class, NULL); seed_value_protect(ctx, ns_ref); /* define enums for setlocale. Where to put them? */ DEFINE_ENUM_MEMBER(ns_ref, LC_CTYPE); DEFINE_ENUM_MEMBER(ns_ref, LC_NUMERIC); DEFINE_ENUM_MEMBER(ns_ref, LC_TIME); DEFINE_ENUM_MEMBER(ns_ref, LC_COLLATE); DEFINE_ENUM_MEMBER(ns_ref, LC_MONETARY); DEFINE_ENUM_MEMBER(ns_ref, LC_MESSAGES); DEFINE_ENUM_MEMBER(ns_ref, LC_ALL); /* these are gnu extensions - and not available on BSD systems */ #ifdef LC_PAPER DEFINE_ENUM_MEMBER(ns_ref, LC_PAPER); #endif #ifdef LC_NAME DEFINE_ENUM_MEMBER(ns_ref, LC_NAME); #endif #ifdef LC_ADDRESS DEFINE_ENUM_MEMBER(ns_ref, LC_ADDRESS); #endif #ifdef LC_TELEPHONE DEFINE_ENUM_MEMBER(ns_ref, LC_TELEPHONE); #endif #ifdef LC_MEASUREMENT DEFINE_ENUM_MEMBER(ns_ref, LC_MEASUREMENT); #endif #ifdef LC_IDENTIFICATION DEFINE_ENUM_MEMBER(ns_ref, LC_IDENTIFICATION); #endif DEFINE_ENUM_MEMBER(ns_ref, LC_CTYPE); return ns_ref; } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/gjs/000077500000000000000000000000001303774616400210615ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/gjs/Makefile.am000066400000000000000000000005121303774616400231130ustar00rootroot00000000000000SUBDIRS = system _gi EXTRA_DIST= cairo.js coverage.js format.js gettext.js jsUnit.js lang.js mainloop.js package.js signals.js gjs_extensiondir=$(datadir)/seed@SEED_GTK_VERSION@/gjs gjs_extension_DATA = cairo.js coverage.js format.js gettext.js jsUnit.js lang.js mainloop.js package.js signals.js -include $(top_srcdir)/git.mk seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/gjs/_gi/000077500000000000000000000000001303774616400216175ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/gjs/_gi/Makefile.am000066400000000000000000000007421303774616400236560ustar00rootroot00000000000000seedlibdir = ${libdir}/seed@SEED_GTK_VERSION@/gjs seedlib_LTLIBRARIES = \ libseed__gi.la libseed__gi_la_SOURCES = \ seed-gi.c AM_CPPFLAGS = \ -I@top_srcdir@/libseed/ \ $(GOBJECT_INTROSPECTION_CFLAGS) \ $(SEED_DEBUG_CFLAGS) \ $(SEED_PROFILE_CFLAGS) libseed__gi_la_LDFLAGS = \ -module -avoid-version \ $(GOBJECT_INTROSPECTION_LDFLAGS) libseed__gi_la_LIBADD = \ $(top_builddir)/libseed/libseed@SEED_GTK_VERSION@.la \ $(SEED_PROFILE_LIBS) -include $(top_srcdir)/git.mk seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/gjs/_gi/seed-gi.c000066400000000000000000000137461303774616400233130ustar00rootroot00000000000000/* * Copyright (c) 2015 Collabora Ltd. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #include #include #include #include #include #include #include #include #define GJS_COMPAT_VERSION (1 * 100 + 40) * 100 + 0 #define NUMARG_EXPECTED_EXCEPTION(name, argc) \ seed_make_exception(ctx, exception, "ArgumentError", \ name " expected " argc " but got %zd", argumentCount); \ return seed_make_undefined(ctx); static SeedValue gjs_override_property(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argumentCount, const SeedValue arguments[], SeedException* exception) { // TODO: to be implemented. seed_make_exception(ctx, exception, "ImplementationError", "Not implemented yet"); return seed_make_undefined(ctx); } static SeedValue gjs_register_interface(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argumentCount, const SeedValue arguments[], SeedException* exception) { // TODO: to be implemented. seed_make_exception(ctx, exception, "ImplementationError", "Not implemented yet"); return seed_make_undefined(ctx); } static SeedValue gjs_register_type(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argumentCount, const SeedValue arguments[], SeedException* exception) { // TODO: to be implemented. seed_make_exception(ctx, exception, "ImplementationError", "Not implemented yet"); return seed_make_undefined(ctx); } static SeedValue gjs_add_interface(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argumentCount, const SeedValue arguments[], SeedException* exception) { // TODO: to be implemented. seed_make_exception(ctx, exception, "ImplementationError", "Not implemented yet"); return seed_make_undefined(ctx); } static SeedValue gjs_hook_up_vfunc(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argumentCount, const SeedValue arguments[], SeedException* exception) { // TODO: to be implemented. seed_make_exception(ctx, exception, "ImplementationError", "Not implemented yet"); return seed_make_undefined(ctx); } static SeedValue gjs_signal_new(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argumentCount, const SeedValue arguments[], SeedException* exception) { // TODO: to be implemented. seed_make_exception(ctx, exception, "ImplementationError", "Not implemented yet"); return seed_make_undefined(ctx); } static seed_static_function module_funcs[] = { { "override_property", gjs_override_property, 0 }, { "register_interface", gjs_register_interface, 0 }, { "register_type", gjs_register_type, 0 }, { "add_interface", gjs_add_interface, 0 }, { "hook_up_vfunc", gjs_hook_up_vfunc, 0 }, { "signal_new", gjs_signal_new, 0 }, { 0, 0, 0 } }; static seed_class_definition system_def = { 0, /* Version, always 0 */ SEED_CLASS_ATTRIBUTE_NO_SHARED_PROTOTYPE, /* JSClassAttributes */ "_gi", /* Class Name */ NULL, /* Parent Class */ NULL, /* Static Values */ module_funcs, /* Static Functions */ NULL, NULL, /* Finalize */ NULL, /* Has Property */ NULL, /* Get Property */ NULL, /* Set Property */ NULL, /* Delete Property */ NULL, /* Get Property Names */ NULL, /* Call As Function */ NULL, /* Call As Constructor */ NULL, /* Has Instance */ NULL /* Convert To Type */ }; SeedObject gjs_compat_define_gi_stuff(SeedEngine* eng) { SeedContext context = eng->context; SeedObject module; gboolean ret; module = seed_make_object(context, seed_create_class(&system_def), NULL); SeedValue seed = seed_object_get_property(context, eng->global, "Seed"); SeedValue argv = seed_object_get_property(context, seed, "argv"); ret = seed_object_set_property( context, module, "version", (SeedValue) seed_value_from_int(context, GJS_COMPAT_VERSION, NULL)); return module; } SeedObject seed_module_init(SeedEngine* eng) { return gjs_compat_define_gi_stuff(eng); } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/gjs/cairo.js000066400000000000000000000055471303774616400225270ustar00rootroot00000000000000// Copyright 2010 litl, LLC. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. const Lang = imports.lang; const Antialias = { DEFAULT: 0, NONE: 1, GRAY: 2, SUBPIXEL: 3 }; const Content = { COLOR : 0x1000, ALPHA : 0x2000, COLOR_ALPHA : 0x3000 }; const Extend = { NONE : 0, REPEAT : 1, REFLECT : 2, PAD : 3 }; const FillRule = { WINDING: 0, EVEN_ODD: 1 }; const Filter = { FAST : 0, GOOD : 1, BEST : 2, NEAREST : 3, BILINEAR : 4, GAUSSIAN : 5 }; const FontSlant = { NORMAL: 0, ITALIC: 1, OBLIQUE: 2 }; const FontWeight = { NORMAL : 0, BOLD : 1 }; const Format = { ARGB32 : 0, RGB24 : 1, A8 : 2, A1 : 3, // The value of 4 is reserved by a deprecated enum value RGB16_565: 5 }; const LineCap = { BUTT: 0, ROUND: 1, SQUASH: 2 }; const LineJoin = { MITER: 0, ROUND: 1, BEVEL: 2 }; const Operator = { CLEAR: 0, SOURCE: 1, OVER: 2, IN : 3, OUT : 4, ATOP : 5, DEST : 6, DEST_OVER : 7, DEST_IN : 8, DEST_OUT : 9, DEST_ATOP : 10, XOR : 11, ADD : 12, SATURATE : 13, MULTIPLY : 14, SCREEN : 15, OVERLAY : 16, DARKEN : 17, LIGHTEN : 18, COLOR_DODGE : 19, COLOR_BURN : 20, HARD_LIGHT : 21, SOFT_LIGHT : 22, DIFFERENCE : 23, EXCLUSION : 24, HSL_HUE : 25, HSL_SATURATION : 26, HSL_COLOR : 27, HSL_LUMINOSITY : 28 }; const PatternType = { SOLID : 0, SURFACE : 1, LINEAR : 2, RADIAL : 3 }; const SurfaceType = { IMAGE : 0, PDF : 1, PS : 2, XLIB : 3, XCB : 4, GLITZ : 5, QUARTZ : 6, WIN32 : 7, BEOS : 8, DIRECTFB : 9, SVG : 10, OS2 : 11, WIN32_PRINTING : 12, QUARTZ_IMAGE : 13 }; // Merge stuff defined in native code Lang.copyProperties(imports.cairoNative, this); seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/gjs/coverage.js000066400000000000000000001033321303774616400232140ustar00rootroot00000000000000/* * Copyright (c) 2014 Endless Mobile, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authored By: Sam Spilsbury */ function getSubNodesForNode(node) { let subNodes = []; switch (node.type) { /* These statements have a single body */ case 'LabelledStatement': case 'WithStatement': case 'FunctionDeclaration': case 'FunctionExpression': case 'CatchClause': subNodes.push(node.body); break; case 'LetStatement': Array.prototype.push.apply(subNodes, node.head); subNodes.push(node.body); break; case 'WhileStatement': case 'DoWhileStatement': subNodes.push(node.body); subNodes.push(node.test); break; case 'ForStatement': if (node.init !== null) subNodes.push(node.init); if (node.test !== null) subNodes.push(node.test); if (node.update !== null) subNodes.push(node.update); subNodes.push(node.body); break; case 'ForInStatement': if (node.each) subNodes.push(node.left); subNodes.push(node.right, node.body); break; case 'ForOfStatement': subNodes.push(node.left, node.right, node.body); break; case 'BlockStatement': Array.prototype.push.apply(subNodes, node.body); break; case 'ThrowStatement': case 'ReturnStatement': case 'YieldExpression': if (node.argument !== null) subNodes.push(node.argument); break; case 'ExpressionStatement': subNodes.push(node.expression); break; case 'AssignmentExpression': case 'BinaryExpression': case 'LogicalExpression': subNodes.push(node.left, node.right); break; case 'ConditionalExpression': subNodes.push(node.test, node.consequent, node.alternate); break; case 'ObjectExpression': node.properties.forEach(function(prop) { subNodes.push(prop.value); }); break; case 'ArrayExpression': node.elements.forEach(function(elem) { if (elem !== null) subNodes.push(elem); }); break; case 'ArrowExpression': Array.prototype.push.apply(subNodes, node.defaults); subNodes.push(node.body); break; case 'SequenceExpression': Array.prototype.push.apply(subNodes, node.expressions); break; case 'UnaryExpression': case 'UpdateExpression': subNodes.push(node.argument); break; case 'ComprehensionExpression': case 'GeneratorExpression': subNodes.push(node.body); Array.prototype.push.apply(subNodes, node.blocks); if (node.filter !== null) subNodes.push(node.filter); break; case 'ComprehensionBlock': subNodes.push(node.right); break; /* It is very possible that there might be something * interesting in the function arguments, so we need to * walk them too */ case 'NewExpression': case 'CallExpression': Array.prototype.push.apply(subNodes, node.arguments); subNodes.push(node.callee); break; /* These statements might have multiple different bodies * depending on whether or not they were entered */ case 'IfStatement': subNodes = [node.test, node.consequent]; if (node.alternate !== null) subNodes.push(node.alternate); break; case 'TryStatement': subNodes = [node.block]; if (node.handler !== null) subNodes.push(node.handler); if (node.finalizer !== null) subNodes.push(node.finalizer); break; case 'SwitchStatement': for (let caseClause of node.cases) { caseClause.consequent.forEach(function(expression) { subNodes.push(expression); }); } break; case 'VariableDeclaration': Array.prototype.push.apply(subNodes, node.declarations); break; case 'VariableDeclarator': if (node.init !== null) subNodes.push(node.init); break; case 'MemberExpression': subNodes.push(node.object); if (node.computed) subNodes.push(node.property); break; } return subNodes; } function collectForSubNodes(subNodes, collector) { let result = []; if (subNodes !== undefined && subNodes.length > 0) { subNodes.forEach(function(node) { let nodeResult = collector(node); if (nodeResult !== undefined) Array.prototype.push.apply(result, nodeResult); let subNodeResults = collectForSubNodes(getSubNodesForNode(node), collector); Array.prototype.push.apply(result, subNodeResults); }); } return result; } function _getFunctionKeyFromReflectedFunction(node) { let name = node.id !== null ? node.id.name : '(anonymous)'; let line = node.loc.start.line; let n_params = node.params.length; return [name, line, n_params].join(':'); } /* Unfortunately, the Reflect API doesn't give us enough information to * uniquely identify a function. A function might be anonymous, in which * case the JS engine uses some heurisitics to get a unique string identifier * but that isn't available to us here. * * There's also the edge-case where functions with the same name might be * defined within the same scope, or multiple anonymous functions might * be defined on the same line. In that case, it will look like we entered * the same function multiple times since we can't get column information * from the engine-side. * * For instance: * * 1. function f() { * function f() { * } * } * * 2. let a = function() { function(a, b) {} }; * * 3. let a = function() { function () {} } * * We can work-around case 1 by using the line numbers to get a unique identifier. * We can work-around case 2 by using the arguments length to get a unique identifier * We can't work-around case 3. The best thing we can do is warn that coverage * reports might be inaccurate as a result */ function functionsForNode(node) { let functionNames = []; switch (node.type) { case 'FunctionDeclaration': case 'FunctionExpression': case 'ArrowExpression': functionNames.push({ key: _getFunctionKeyFromReflectedFunction(node), line: node.loc.start.line, n_params: node.params.length }); } return functionNames; } function functionsForAST(ast) { return collectForSubNodes(ast.body, functionsForNode); } /* If a branch' consequent is a block statement, there's * a chance that it could start on the same line, although * that's not where execution really starts. If it is * a block statement then handle the case and go * to the first line where execution starts */ function getBranchExitStartLine(branchBodyNode) { switch (branchBodyNode.type) { case 'BlockStatement': /* Hit a block statement, but nothing inside, can never * be executed, tell the upper level to move on to the next * statement */ if (branchBodyNode.body.length === 0) return -1; /* Handle the case where we have nested block statements * that never actually get to executable code by handling * all statements within a block */ for (let statement of branchBodyNode.body) { let startLine = getBranchExitStartLine(statement); if (startLine !== -1) return startLine; } /* Couldn't find an executable line inside this block */ return -1; case 'SwitchCase': /* Hit a switch, but nothing inside, can never * be executed, tell the upper level to move on to the next * statement */ if (branchBodyNode.consequent.length === 0) return -1; /* Handle the case where we have nested block statements * that never actually get to executable code by handling * all statements within a block */ for (let statement of branchBodyNode.consequent) { let startLine = getBranchExitStartLine(statement); if (startLine !== -1) { return startLine; } } /* Couldn't find an executable line inside this block */ return -1; /* These types of statements are never executable */ case 'EmptyStatement': case 'LabelledStatement': return -1; default: break; } return branchBodyNode.loc.start.line; } function branchesForNode(node) { let branches = []; let branchExitNodes = []; switch (node.type) { case 'IfStatement': branchExitNodes.push(node.consequent); if (node.alternate !== null) branchExitNodes.push(node.alternate); break; case 'WhileStatement': case 'DoWhileStatement': branchExitNodes.push(node.body); break; case 'SwitchStatement': /* The case clauses by themselves are never executable * so find the actual exits */ Array.prototype.push.apply(branchExitNodes, node.cases); break; default: break; } let branchExitStartLines = branchExitNodes.map(getBranchExitStartLine); branchExitStartLines = branchExitStartLines.filter(function(line) { return line !== -1; }); /* Branch must have at least one exit */ if (branchExitStartLines.length) { branches.push({ point: node.loc.start.line, exits: branchExitStartLines }); } return branches; } function branchesForAST(ast) { return collectForSubNodes(ast.body, branchesForNode); } function expressionLinesForNode(statement) { let expressionLines = []; let expressionNodeTypes = ['Expression', 'Declaration', 'Statement', 'Clause', 'Literal', 'Identifier']; if (expressionNodeTypes.some(function(type) { return statement.type.indexOf(type) !== -1; })) { /* These expressions aren't executable on their own */ switch (statement.type) { case 'FunctionDeclaration': case 'LiteralExpression': break; /* Perplexingly, an empty block statement is actually executable, * push it if it is */ case 'BlockStatement': if (statement.body.length !== 0) break; expressionLines.push(statement.loc.start.line); break; default: expressionLines.push(statement.loc.start.line); break; } } return expressionLines; } function deduplicate(list) { return list.filter(function(elem, pos, self) { return self.indexOf(elem) === pos; }); } function expressionLinesForAST(ast) { let allExpressions = collectForSubNodes(ast.body, expressionLinesForNode); allExpressions = deduplicate(allExpressions); return allExpressions; } function _getNumberOfLinesForScript(scriptContents) { let scriptLines = scriptContents.split("\n"); let scriptLineCount = scriptLines.length; return scriptLineCount; } /* * The created array is a 1-1 representation of the hitcount in the filename. Each * element refers to an individual line. In order to avoid confusion, our array * is zero indexed, but the zero'th line is always ignored and the first element * refers to the first line of the file. * * A value of undefined for an element means that the line is non-executable and never actually * reached. A value of 0 means that it was executable but never reached. A positive value * indicates the hit count. * * We care about non-executable lines because we don't want to report coverage misses for * lines that could have never been executed anyways. * * The reason for using a 1-1 mapping as opposed to an array of key-value pairs for executable * lines is: * 1. Lookup speed is O(1) instead of O(log(n)) * 2. There's a possibility we might hit a line which we thought was non-executable, in which * case we can neatly handle the error by marking that line executable. A hit on a line * we thought was non-executable is not as much of a problem as noise generated by * ostensible "misses" which could in fact never be executed. * */ function _expressionLinesToCounters(expressionLines, nLines) { expressionLines.sort(function(left, right) { return left - right; }); let expressionLinesIndex = 0; let counters = new Array(nLines + 1); if (expressionLines.length === 0) return counters; for (let i = 1; i < counters.length; i++) { if (expressionLines[expressionLinesIndex] == i) { counters[i] = 0; expressionLinesIndex++; } } return counters; } /* As above, we are creating a 1-1 representation of script lines to potential branches * where each element refers to a 1-index line (with the zero'th ignored). * * Each element is a GjsCoverageBranchData which, if the line at the element * position describes a branch, will be populated with a GjsReflectedScriptBranchInfo * and an array of unsigned each specifying the hit-count for each potential branch * in the branch info */ function _branchesToBranchCounters(branches, nLines) { branches.sort(function(left, right) { return left.point - right.point; }); let branchIndex = 0; let counters = new Array(nLines + 1); if (branches.length === 0) return counters; for (let i = 1; i < counters.length; i++) { let branch = branches[branchIndex]; let branchPoint = branch.point; if (branchPoint == i) { counters[i] = { point: branchPoint, exits: branch.exits.map(function(exit) { return { line: exit, hitCount: 0 }; }), lastExit: (function() { let lastExitLine = 0; for (let exit of branch.exits) { if (lastExitLine < exit) lastExitLine = exit; } return lastExitLine; })(), hit: false }; if (++branchIndex >= branches.length) break; } } return counters; } function _functionsToFunctionCounters(script, functions) { let functionCounters = {}; functions.forEach(function(func) { let [name, line, args] = func.key.split(':'); if (functionCounters[name] === undefined) { functionCounters[name] = {}; } if (functionCounters[name][line] === undefined) { functionCounters[name][line] = {}; } if (functionCounters[name][line][args] === undefined) { functionCounters[name][line][args] = { hitCount: 0 }; } else { log(script + ':' + line + ' Function identified as ' + func.key + ' already seen in this file. Function coverage ' + 'will be incomplete.'); } }); return functionCounters; } function _populateKnownFunctions(functions, nLines) { let knownFunctions = new Array(nLines + 1); functions.forEach(function(func) { knownFunctions[func.line] = true; }); return knownFunctions; } function _identifyFunctionCounterInLinePartForDescription(linePart, nArgs) { /* There is only one potential option for this line. We might have been * called with the wrong number of arguments, but it doesn't matter. */ if (Object.getOwnPropertyNames(linePart).length === 1) return linePart[Object.getOwnPropertyNames(linePart)[0]]; /* Have to disambiguate using nArgs and we have an exact match. */ if (linePart[nArgs] !== undefined) return linePart[nArgs]; /* There are multiple options on this line. Pick the one where * we satisfy the number of arguments exactly, or failing that, * go through each and pick the closest. */ let allNArgsOptions = Object.keys(linePart).map(function(key) { return parseInt(key); }); let closest = allNArgsOptions.reduce(function(prev, current, index, array) { let nArgsOption = array[index]; if (Math.abs(nArgsOption - nArgs) < Math.abs(current - nArgs)) { return nArgsOption; } return current; }); return linePart[String(closest)]; } function _identifyFunctionCounterForDescription(functionCounters, name, line, nArgs) { let candidateCounter = functionCounters[name]; if (candidateCounter === undefined) return null; if (Object.getOwnPropertyNames(candidateCounter).length === 1) { let linePart = candidateCounter[Object.getOwnPropertyNames(candidateCounter)[0]]; return _identifyFunctionCounterInLinePartForDescription(linePart, nArgs); } let linePart = functionCounters[name][line]; if (linePart === undefined) { return null; } return _identifyFunctionCounterInLinePartForDescription(linePart, nArgs); } /** * _incrementFunctionCounters * * functionCounters: An object which is a key-value pair with the following schema: * { * "key" : { line, hitCount } * } * linesWithKnownFunctions: An array of either "true" or undefined, with true set to * each element corresponding to a line that we know has a function on it. * name: The name of the function or "(anonymous)" if it has no name * line: The line at which execution first started on this function. * nArgs: The number of arguments this function has. */ function _incrementFunctionCounters(functionCounters, linesWithKnownFunctions, name, line, nArgs) { let functionCountersForKey = _identifyFunctionCounterForDescription(functionCounters, name, line, nArgs); /* Its possible that the JS Engine might enter a funciton * at an executable line which is a little bit past the * actual definition. Roll backwards until we reach the * last known function definition line which we kept * track of earlier to see if we can find this function first */ if (functionCountersForKey === null) { do { --line; functionCountersForKey = _identifyFunctionCounterForDescription(functionCounters, name, line, nArgs); } while (linesWithKnownFunctions[line] !== true && line > 0); } if (functionCountersForKey !== null) { functionCountersForKey.hitCount++; } else { let functionKey = [name, line, nArgs].join(':'); throw new Error("expected Reflect to find function " + functionKey); } } /** * _incrementExpressionCounters * * expressonCounters: An array of either a hit count for a found * executable line or undefined for a known non-executable line. * line: an executed line */ function _incrementExpressionCounters(expressionCounters, script, offsetLine) { let expressionCountersLen = expressionCounters.length; if (offsetLine >= expressionCountersLen) throw new Error("Executed line " + offsetLine + " which was past the highest-found line " + expressionCountersLen); /* If this happens it is not a huge problem - though it does * mean that the reflection machinery is not doing its job, so we should * print a debug message about it in case someone is interested. * * The reason why we don't have a proper log is because it * is difficult to determine what the SpiderMonkey program counter * will actually pass over, especially function declarations for some * reason: * * function f(a,b) { * a = 1; * } * * In some cases, the declaration itself will be executed * but in other cases it won't be. Reflect.parse tells us that * the only two expressions on that line are a FunctionDeclaration * and BlockStatement, neither of which would ordinarily be * executed */ if (expressionCounters[offsetLine] === undefined) { log(script + ':' + offsetLine + ' Executed line previously marked ' + 'non-executable by Reflect'); expressionCounters[offsetLine] = 0; } expressionCounters[offsetLine]++; } function _BranchTracker(branchCounters) { this._branchCounters = branchCounters; this._activeBranch = undefined; this.incrementBranchCounters = function(offsetLine) { /* Set branch exits or find a new active branch */ let activeBranch = this._activeBranch; if (activeBranch !== undefined) { activeBranch.exits.forEach(function(exit) { if (exit.line === offsetLine) { exit.hitCount++; } }); /* Only set the active branch to undefined once we're * completely outside of it, since we might be in a case statement where * we need to check every possible option before jumping to an * exit */ if (offsetLine >= activeBranch.lastExit) this._activeBranch = undefined; } let nextActiveBranch = branchCounters[offsetLine]; if (nextActiveBranch !== undefined) { this._activeBranch = nextActiveBranch; this._activeBranch.hit = true; } }; } function _convertFunctionCountersToArray(functionCounters) { let arrayReturn = []; /* functionCounters is an object so explore it to create a * set of function keys and then convert it to * an array-of-object using the key as a property * of that object */ for (let name of Object.getOwnPropertyNames(functionCounters)) { let namePart = functionCounters[name]; for (let line of Object.getOwnPropertyNames(namePart)) { let linePart = functionCounters[name][line]; for (let nArgs of Object.getOwnPropertyNames(linePart)) { let functionKey = [name, line, nArgs].join(':'); arrayReturn.push({ name: functionKey, line: Number(line), nArgs: nArgs, hitCount: linePart[nArgs].hitCount }); } } } arrayReturn.sort(function(left, right) { if (left.name < right.name) return -1; else if (left.name > right.name) return 1; else return 0; }); return arrayReturn; } /* Looks up filename in cache and fetches statistics * directly from the cache */ function _fetchCountersFromCache(filename, cache, nLines) { if (!cache) return null; if (Object.keys(cache).indexOf(filename) !== -1) { let cache_for_file = cache[filename]; if (cache_for_file.mtime) { let mtime = getFileModificationTime(filename); if (mtime[0] != cache[filename].mtime[0] || mtime[1] != cache[filename].mtime[1]) return null; } else { let checksum = getFileChecksum(filename); if (checksum != cache[filename].checksum) return null; } let functions = cache_for_file.functions; return { expressionCounters: _expressionLinesToCounters(cache_for_file.lines, nLines), branchCounters: _branchesToBranchCounters(cache_for_file.branches, nLines), functionCounters: _functionsToFunctionCounters(filename, functions), linesWithKnownFunctions: _populateKnownFunctions(functions, nLines), nLines: nLines }; } return null; } function _fetchCountersFromReflection(filename, contents, nLines) { let reflection = Reflect.parse(contents); let functions = functionsForAST(reflection); return { expressionCounters: _expressionLinesToCounters(expressionLinesForAST(reflection), nLines), branchCounters: _branchesToBranchCounters(branchesForAST(reflection), nLines), functionCounters: _functionsToFunctionCounters(filename, functions), linesWithKnownFunctions: _populateKnownFunctions(functions, nLines), nLines: nLines }; } function CoverageStatisticsContainer(prefixes, cache) { /* Copy the files array, so that it can be re-used in the tests */ let cachedASTs = cache !== undefined ? JSON.parse(cache) : null; let coveredFiles = {}; let cacheMisses = 0; function wantsStatisticsFor(filename) { return prefixes.some(function(prefix) { return filename.startsWith(prefix); }); } function createStatisticsFor(filename) { let contents = getFileContents(filename); let nLines = _getNumberOfLinesForScript(contents); let counters = _fetchCountersFromCache(filename, cachedASTs, nLines); if (counters === null) { cacheMisses++; counters = _fetchCountersFromReflection(filename, contents, nLines); } if (counters === null) throw new Error('Failed to parse and reflect file ' + filename); /* Set contents here as we don't pass it to _fetchCountersFromCache. */ counters.contents = contents; return counters; } function ensureStatisticsFor(filename) { let wantStatistics = wantsStatisticsFor(filename); let haveStatistics = !!coveredFiles[filename]; if (wantStatistics && !haveStatistics) coveredFiles[filename] = createStatisticsFor(filename); return coveredFiles[filename]; } this.stringify = function() { let cache_data = {}; Object.keys(coveredFiles).forEach(function(filename) { let statisticsForFilename = coveredFiles[filename]; let mtime = getFileModificationTime(filename); let cacheDataForFilename = { mtime: mtime, checksum: mtime === null ? getFileChecksum(filename) : null, lines: [], branches: [], functions: _convertFunctionCountersToArray(statisticsForFilename.functionCounters).map(function(func) { return { key: func.name, line: func.line }; }) }; /* We're using a index based loop here since we need access to the * index, since it actually represents the current line number * on the file (see _expressionLinesToCounters). */ for (let line_index = 0; line_index < statisticsForFilename.expressionCounters.length; ++line_index) { if (statisticsForFilename.expressionCounters[line_index] !== undefined) cacheDataForFilename.lines.push(line_index); if (statisticsForFilename.branchCounters[line_index] !== undefined) { let branchCounters = statisticsForFilename.branchCounters[line_index]; cacheDataForFilename.branches.push({ point: statisticsForFilename.branchCounters[line_index].point, exits: statisticsForFilename.branchCounters[line_index].exits.map(function(exit) { return exit.line; }) }); } } cache_data[filename] = cacheDataForFilename; }); return JSON.stringify(cache_data); }; this.getCoveredFiles = function() { return Object.keys(coveredFiles); }; this.fetchStatistics = function(filename) { return ensureStatisticsFor(filename); }; this.staleCache = function() { return cacheMisses > 0; }; this.deleteStatistics = function(filename) { coveredFiles[filename] = undefined; }; } /** * Main class tying together the Debugger object and CoverageStatisticsContainer. * * It isn't poissible to unit test this class because it depends on running * Debugger which in turn depends on objects injected in from another compartment */ function CoverageStatistics(prefixes, cache) { this.container = new CoverageStatisticsContainer(prefixes, cache); let fetchStatistics = this.container.fetchStatistics.bind(this.container); let deleteStatistics = this.container.deleteStatistics.bind(this.container); /* 'debuggee' comes from the invocation from * a separate compartment inside of coverage.cpp */ this.dbg = new Debugger(debuggee); this.getCoveredFiles = function() { return this.container.getCoveredFiles(); }; this.getNumberOfLinesFor = function(filename) { return fetchStatistics(filename).nLines; }; this.getExecutedLinesFor = function(filename) { return fetchStatistics(filename).expressionCounters; }; this.getBranchesFor = function(filename) { return fetchStatistics(filename).branchCounters; }; this.getFunctionsFor = function(filename) { let functionCounters = fetchStatistics(filename).functionCounters; return _convertFunctionCountersToArray(functionCounters); }; this.dbg.onEnterFrame = function(frame) { let statistics; try { statistics = fetchStatistics(frame.script.url); if (!statistics) { return undefined; } } catch (e) { /* We don't care about this frame, return */ log(e.message + " " + e.stack); return undefined; } function _logExceptionAndReset(exception, callee, line) { log(exception.fileName + ":" + exception.lineNumber + " (processing " + frame.script.url + ":" + callee + ":" + line + ") - " + exception.message); log("Will not log statistics for this file"); frame.onStep = undefined; frame._branchTracker = undefined; deleteStatistics(frame.script.url); } /* Log function calls */ if (frame.callee !== null && frame.callee.callable) { let name = frame.callee.name ? frame.callee.name : "(anonymous)"; let line = frame.script.getOffsetLine(frame.offset); let nArgs = frame.callee.parameterNames.length; try { _incrementFunctionCounters(statistics.functionCounters, statistics.linesWithKnownFunctions, name, line, nArgs); } catch (e) { /* Something bad happened. Log the exception and delete * statistics for this file */ _logExceptionAndReset(e, name, line); return undefined; } } /* Upon entering the frame, the active branch is always inactive */ frame._branchTracker = new _BranchTracker(statistics.branchCounters); /* Set single-step hook */ frame.onStep = function() { /* Line counts */ let offset = this.offset; let offsetLine = this.script.getOffsetLine(offset); try { _incrementExpressionCounters(statistics.expressionCounters, frame.script.url, offsetLine); this._branchTracker.incrementBranchCounters(offsetLine); } catch (e) { /* Something bad happened. Log the exception and delete * statistics for this file */ _logExceptionAndReset(e, frame.callee, offsetLine); } }; return undefined; }; this.deactivate = function() { /* This property is designed to be a one-stop-shop to * disable the debugger for this debugee, without having * to traverse all its scripts or frames */ this.dbg.enabled = false; }; this.staleCache = this.container.staleCache.bind(this.container); this.stringify = this.container.stringify.bind(this.container); } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/gjs/format.js000066400000000000000000000056211303774616400227130ustar00rootroot00000000000000// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- const GjsPrivate = imports.gi.GjsPrivate; function vprintf(str, args) { let i = 0; let usePos = false; return str.replace(/%(?:([1-9][0-9]*)\$)?(I+)?([0-9]+)?(?:\.([0-9]+))?(.)/g, function (str, posGroup, flagsGroup, widthGroup, precisionGroup, genericGroup) { if (precisionGroup != '' && genericGroup != 'f') throw new Error("Precision can only be specified for 'f'"); let hasAlternativeIntFlag = (flagsGroup.indexOf('I') != -1); if (hasAlternativeIntFlag && genericGroup != 'd') throw new Error("Alternative output digits can only be specfied for 'd'"); let pos = parseInt(posGroup, 10) || 0; if (usePos == false && i == 0) usePos = pos > 0; if (usePos && pos == 0 || !usePos && pos > 0) throw new Error("Numbered and unnumbered conversion specifications cannot be mixed"); let fillChar = (widthGroup[0] == '0') ? '0' : ' '; let width = parseInt(widthGroup, 10) || 0; function fillWidth(s, c, w) { let fill = ''; for (let i = 0; i < w; i++) fill += c; return fill.substr(s.length) + s; } function getArg() { return usePos ? args[pos - 1] : args[i++]; } let s = ''; switch (genericGroup) { case '%': return '%'; break; case 's': s = String(getArg()); break; case 'd': let intV = parseInt(getArg()); if (hasAlternativeIntFlag) s = GjsPrivate.format_int_alternative_output(intV); else s = intV.toString(); break; case 'x': s = parseInt(getArg()).toString(16); break; case 'f': if (precisionGroup == '') s = parseFloat(getArg()).toString(); else s = parseFloat(getArg()).toFixed(parseInt(precisionGroup)); break; default: throw new Error('Unsupported conversion character %' + genericGroup); } return fillWidth(s, fillChar, width); }); } function printf() { let args = Array.prototype.slice.call(arguments); let fmt = args.shift(); print(vprintf(fmt, args)); } /* * This function is intended to extend the String object and provide * an String.format API for string formatting. * It has to be set up using String.prototype.format = Format.format; * Usage: * "somestring %s %d".format('hello', 5); * It supports %s, %d, %x and %f, for %f it also support precisions like * "%.2f".format(1.526). All specifiers can be prefixed with a minimum * field width, e.g. "%5s".format("foo"). Unless the width is prefixed * with '0', the formatted string will be padded with spaces. */ function format() { return vprintf(this, arguments); } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/gjs/gettext.js000066400000000000000000000061151303774616400231060ustar00rootroot00000000000000// Copyright 2009 Red Hat, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. /** * This module provides a convenience layer for the "gettext" family of functions, * relying on GLib for the actual implementation. * * Usage: * * const Gettext = imports.gettext; * * Gettext.textdomain("myapp"); * Gettext.bindtextdomain("myapp", "/usr/share/locale"); * * let translated = Gettext.gettext("Hello world!"); */ const GLib = imports.gi.GLib; const GjsPrivate = imports.gi.GjsPrivate; const LocaleCategory = GjsPrivate.LocaleCategory; function setlocale(category, locale) { return GjsPrivate.setlocale(category, locale); } function textdomain(domain) { return GjsPrivate.textdomain(domain); } function bindtextdomain(domain, location) { return GjsPrivate.bindtextdomain(domain, location); } function gettext(msgid) { return GLib.dgettext(null, msgid); } function dgettext(domain, msgid) { return GLib.dgettext(domain, msgid); } function dcgettext(domain, msgid, category) { return GLib.dcgettext(domain, msgid, category); } function ngettext(msgid1, msgid2, n) { return GLib.dngettext(null, msgid1, msgid2, n); } function dngettext(domain, msgid1, msgid2, n) { return GLib.dngettext(domain, msgid1, msgid2, n); } // FIXME: missing dcngettext ? function pgettext(context, msgid) { return GLib.dpgettext2(null, context, msgid); } function dpgettext(domain, context, msgid) { return GLib.dpgettext2(domain, context, msgid); } /** * Create an object with bindings for gettext, ngettext, * and pgettext bound to a particular translation domain. * * @param domainName Translation domain string * @returns: an object with gettext bindings * @type: function */ var domain = function(domainName) { return { gettext: function(msgid) { return GLib.dgettext(domainName, msgid); }, ngettext: function(msgid1, msgid2, n) { return GLib.dngettext(domainName, msgid1, msgid2, n); }, pgettext: function(context, msgid) { return GLib.dpgettext2(domainName, context, msgid); } }; }; seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/gjs/jsUnit.js000066400000000000000000000352071303774616400227020ustar00rootroot00000000000000/* @author Edward Hieatt, edward@jsunit.net */ /* - JsUnit - Copyright (C) 2001-4 Edward Hieatt, edward@jsunit.net - Copyright (C) 2008 litl, LLC - - Version: MPL 1.1/GPL 2.0/LGPL 2.1 - - The contents of this file are subject to the Mozilla Public License Version - 1.1 (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" basis, - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - for the specific language governing rights and limitations under the - License. - - The Original Code is Edward Hieatt code. - - The Initial Developer of the Original Code is - Edward Hieatt, edward@jsunit.net. - Portions created by the Initial Developer are Copyright (C) 2003 - the Initial Developer. All Rights Reserved. - - Author Edward Hieatt, edward@jsunit.net - - Alternatively, the contents of this file may be used under the terms of - either the GNU General Public License Version 2 or later (the "GPL"), or - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - in which case the provisions of the GPL or the LGPL are applicable instead - of those above. If you wish to allow use of your version of this file only - under the terms of either the GPL or the LGPL, and not to allow others to - use your version of this file under the terms of the MPL, indicate your - decision by deleting the provisions above and replace them with the notice - and other provisions required by the LGPL or the GPL. If you do not delete - the provisions above, a recipient may use your version of this file under - the terms of any one of the MPL, the GPL or the LGPL. */ var JSUNIT_UNDEFINED_VALUE; var JSUNIT_VERSION="2.1"; var isTestPageLoaded = false; // GJS: introduce implicit variable to avoid exceptions var top = null; //hack for NS62 bug function jsUnitFixTop() { var tempTop = top; if (!tempTop) { tempTop = window; while (tempTop.parent) { tempTop = tempTop.parent; if (tempTop.top && tempTop.top.jsUnitTestSuite) { tempTop = tempTop.top; break; } } } top = tempTop; } jsUnitFixTop(); function _displayStringForValue(aVar) { if (aVar === null) return 'null'; if (aVar === top.JSUNIT_UNDEFINED_VALUE) return 'undefined'; return aVar; } function fail(failureMessage) { throw new JsUnitException(null, failureMessage); } function error(errorMessage) { throw new Error(errorMessage); } function argumentsIncludeComments(expectedNumberOfNonCommentArgs, args) { return args.length == expectedNumberOfNonCommentArgs + 1; } function commentArg(expectedNumberOfNonCommentArgs, args) { if (argumentsIncludeComments(expectedNumberOfNonCommentArgs, args)) return args[0]; return null; } function nonCommentArg(desiredNonCommentArgIndex, expectedNumberOfNonCommentArgs, args) { return argumentsIncludeComments(expectedNumberOfNonCommentArgs, args) ? args[desiredNonCommentArgIndex] : args[desiredNonCommentArgIndex - 1]; } function _validateArguments(expectedNumberOfNonCommentArgs, args) { if (!( args.length == expectedNumberOfNonCommentArgs || (args.length == expectedNumberOfNonCommentArgs + 1 && typeof(args[0]) == 'string') )) error('Incorrect arguments passed to assert function'); } function _assert(comment, booleanValue, failureMessage) { if (!booleanValue) throw new JsUnitException(comment, failureMessage); } function assert() { _validateArguments(1, arguments); var booleanValue=nonCommentArg(1, 1, arguments); if (typeof(booleanValue) != 'boolean') error('Bad argument to assert(boolean)'); _assert(commentArg(1, arguments), booleanValue === true, 'Call to assert(boolean) with false'); } function assertTrue() { _validateArguments(1, arguments); var booleanValue=nonCommentArg(1, 1, arguments); if (typeof(booleanValue) != 'boolean') error('Bad argument to assertTrue(boolean)'); _assert(commentArg(1, arguments), booleanValue === true, 'Call to assertTrue(boolean) with false'); } function assertFalse() { _validateArguments(1, arguments); var booleanValue=nonCommentArg(1, 1, arguments); if (typeof(booleanValue) != 'boolean') error('Bad argument to assertFalse(boolean)'); _assert(commentArg(1, arguments), booleanValue === false, 'Call to assertFalse(boolean) with true'); } function assertEquals() { _validateArguments(2, arguments); var var1=nonCommentArg(1, 2, arguments); var var2=nonCommentArg(2, 2, arguments); _assert(commentArg(2, arguments), var1 === var2, 'Expected ' + var1 + ' (' + typeof(var1) + ') but was ' + _displayStringForValue(var2) + ' (' + typeof(var2) + ')'); } function assertNotEquals() { _validateArguments(2, arguments); var var1=nonCommentArg(1, 2, arguments); var var2=nonCommentArg(2, 2, arguments); _assert(commentArg(2, arguments), var1 !== var2, 'Expected not to be ' + _displayStringForValue(var2)); } function assertNull() { _validateArguments(1, arguments); var aVar=nonCommentArg(1, 1, arguments); _assert(commentArg(1, arguments), aVar === null, 'Expected null but was ' + _displayStringForValue(aVar)); } function assertNotNull() { _validateArguments(1, arguments); var aVar=nonCommentArg(1, 1, arguments); _assert(commentArg(1, arguments), aVar !== null, 'Expected not to be null'); } function assertUndefined() { _validateArguments(1, arguments); var aVar=nonCommentArg(1, 1, arguments); _assert(commentArg(1, arguments), aVar === top.JSUNIT_UNDEFINED_VALUE, 'Expected undefined but was ' + _displayStringForValue(aVar)); } function assertNotUndefined() { _validateArguments(1, arguments); var aVar=nonCommentArg(1, 1, arguments); _assert(commentArg(1, arguments), aVar !== top.JSUNIT_UNDEFINED_VALUE, 'Expected not to be undefined'); } function assertNaN() { _validateArguments(1, arguments); var aVar=nonCommentArg(1, 1, arguments); _assert(commentArg(1, arguments), isNaN(aVar), 'Expected NaN'); } function assertNotNaN() { _validateArguments(1, arguments); var aVar=nonCommentArg(1, 1, arguments); _assert(commentArg(1, arguments), !isNaN(aVar), 'Expected not NaN'); } // GJS: assertRaises(function) function assertRaises() { _validateArguments(1, arguments); var fun=nonCommentArg(1, 1, arguments); var exception; if (typeof(fun) != 'function') error("Bad argument to assertRaises(function)"); var retval; try { retval = fun(); } catch (e) { exception = e; } _assert(commentArg(1, arguments), exception !== top.JSUNIT_UNDEFINED_VALUE, "Call to assertRaises(function) did not raise an exception. Return value was " + _displayStringForValue(retval) + ' (' + typeof(retval) + ')'); } function isLoaded() { return isTestPageLoaded; } function setUp() { } function tearDown() { } function getFunctionName(aFunction) { var name = aFunction.toString().match(/function (\w*)/)[1]; if ((name == null) || (name.length == 0)) name = 'anonymous'; return name; } function parseErrorStack(excp) { var stack = []; var name; if (!excp || !excp.stack) { return stack; } var stacklist = excp.stack.split('\n'); for (var i = 0; i < stacklist.length - 1; i++) { var framedata = stacklist[i]; name = framedata.match(/^(\w*)/)[1]; if (!name) { name = 'anonymous'; } var line = framedata.match(/(:\d+)$/)[1]; if (line) { name += line; } stack[stack.length] = name; } // remove top level anonymous functions to match IE while (stack.length && stack[stack.length - 1] == 'anonymous') { stack.length = stack.length - 1; } return stack; } function JsUnitException(comment, message) { this.isJsUnitException = true; this.comment = comment; this.message = message; this.stack = (new Error()).stack; } JsUnitException.prototype = Object.create(Error.prototype, {}); function warn() { if (top.tracer != null) top.tracer.warn(arguments[0], arguments[1]); } function inform() { if (top.tracer != null) top.tracer.inform(arguments[0], arguments[1]); } function info() { inform(arguments[0], arguments[1]); } function debug() { if (top.tracer != null) top.tracer.debug(arguments[0], arguments[1]); } function setjsUnitTracer(ajsUnitTracer) { top.tracer=ajsUnitTracer; } function trim(str) { if (str == null) return null; var startingIndex = 0; var endingIndex = str.length-1; while (str.substring(startingIndex, startingIndex+1) == ' ') startingIndex++; while (str.substring(endingIndex, endingIndex+1) == ' ') endingIndex--; if (endingIndex < startingIndex) return ''; return str.substring(startingIndex, endingIndex+1); } function isBlank(str) { return trim(str) == ''; } // the functions push(anArray, anObject) and pop(anArray) // exist because the JavaScript Array.push(anObject) and Array.pop() // functions are not available in IE 5.0 function push(anArray, anObject) { anArray[anArray.length]=anObject; } function pop(anArray) { if (anArray.length>=1) { delete anArray[anArray.length - 1]; anArray.length--; } } // safe, strict access to jsUnitParmHash function jsUnitGetParm(name) { if (typeof(top.jsUnitParmHash[name]) != 'undefined') { return top.jsUnitParmHash[name]; } return null; } if (top && typeof(top.xbDEBUG) != 'undefined' && top.xbDEBUG.on && top.testManager) { top.xbDebugTraceObject('top.testManager.containerTestFrame', 'JSUnitException'); // asserts top.xbDebugTraceFunction('top.testManager.containerTestFrame', '_displayStringForValue'); top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'error'); top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'argumentsIncludeComments'); top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'commentArg'); top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'nonCommentArg'); top.xbDebugTraceFunction('top.testManager.containerTestFrame', '_validateArguments'); top.xbDebugTraceFunction('top.testManager.containerTestFrame', '_assert'); top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assert'); top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertTrue'); top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertEquals'); top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertNotEquals'); top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertNull'); top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertNotNull'); top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertUndefined'); top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertNotUndefined'); top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertNaN'); top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertNotNaN'); top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'isLoaded'); top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'setUp'); top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'tearDown'); top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'getFunctionName'); top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'warn'); top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'inform'); top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'debug'); top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'setjsUnitTracer'); top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'trim'); top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'isBlank'); top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'newOnLoadEvent'); top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'push'); top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'pop'); } function newOnLoadEvent() { isTestPageLoaded = true; } function jsUnitSetOnLoad(windowRef, onloadHandler) { var isKonqueror = navigator.userAgent.indexOf('Konqueror/') != -1 || navigator.userAgent.indexOf('Safari/') != -1; if (typeof(windowRef.attachEvent) != 'undefined') { // Internet Explorer, Opera windowRef.attachEvent("onload", onloadHandler); } else if (typeof(windowRef.addEventListener) != 'undefined' && !isKonqueror){ // Mozilla, Konqueror // exclude Konqueror due to load issues windowRef.addEventListener("load", onloadHandler, false); } else if (typeof(windowRef.document.addEventListener) != 'undefined' && !isKonqueror) { // DOM 2 Events // exclude Mozilla, Konqueror due to load issues windowRef.document.addEventListener("load", onloadHandler, false); } else if (typeof(windowRef.onload) != 'undefined' && windowRef.onload) { windowRef.jsunit_original_onload = windowRef.onload; windowRef.onload = function() { windowRef.jsunit_original_onload(); onloadHandler(); }; } else { // browsers that do not support windowRef.attachEvent or // windowRef.addEventListener will override a page's own onload event windowRef.onload=onloadHandler; } } // GJS: comment out as isLoaded() isn't terribly useful for us //jsUnitSetOnLoad(window, newOnLoadEvent); // GJS: entry point to run all functions named as test*, surrounded by // calls to setUp() and tearDown() function gjstestRun(window_, setUp, tearDown) { var propName; var rv = 0; var failures = []; if (!window_) window_ = window; if (!setUp) setUp = window_.setUp; if (!tearDown) tearDown = window_.tearDown; for (propName in window_) { if (!propName.match(/^test\w+/)) continue; var testFunction = window_[propName]; if (typeof(testFunction) != 'function') continue; log("running test " + propName); setUp(); try { testFunction(); } catch (e) { var result = null; if (typeof(e.isJsUnitException) != 'undefined' && e.isJsUnitException) { result = ''; if (e.comment != null) result += ('"' + e.comment + '"\n'); result += e.message; if (e.stack) result += '\n\nStack trace follows:\n' + e.stack; // assertion failure, kind of expected so just log it and flag the // whole test as failed log(result); rv = 1; failures.push(propName); } else { // unexpected error, let the shell handle it throw e; } } tearDown(); } if (failures.length > 0) { log(failures.length + " tests failed in this file"); log("Failures were: " + failures.join(", ")); } // if gjstestRun() is the last call in a file, this becomes the // exit code of the test program, so 0 = success, 1 = failed return rv; } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/gjs/lang.js000066400000000000000000000415321303774616400223450ustar00rootroot00000000000000/* -*- mode: js; indent-tabs-mode: nil; -*- */ // Copyright (c) 2008 litl, LLC // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. // Utilities that are "meta-language" things like manipulating object props const Gi = imports._gi; function countProperties(obj) { let count = 0; for (let property in obj) { count += 1; } return count; } function getPropertyDescriptor(obj, property) { if (obj.hasOwnProperty(property)) return Object.getOwnPropertyDescriptor(obj, property); return getPropertyDescriptor(Object.getPrototypeOf(obj), property); } function _copyProperty(source, dest, property) { let descriptor = getPropertyDescriptor(source, property); Object.defineProperty(dest, property, descriptor); } function copyProperties(source, dest) { for (let property in source) { _copyProperty(source, dest, property); } } function copyPublicProperties(source, dest) { for (let property in source) { if (typeof(property) == 'string' && property.substring(0, 1) == '_') { continue; } else { _copyProperty(source, dest, property); } } } /** * Binds obj to callback. Makes it possible to refer to "obj" * using this within the callback. * @param {object} obj the object to bind * @param {function} callback callback to bind obj in * @param arguments additional arguments to the callback * @returns: a new callback * @type: function */ function bind(obj, callback) { if (typeof(obj) != 'object') { throw new Error( "first argument to Lang.bind() must be an object, not " + typeof(obj)); } if (typeof(callback) != 'function') { throw new Error( "second argument to Lang.bind() must be a function, not " + typeof(callback)); } // Use ES5 Function.prototype.bind, but only if not passing any bindArguments, // because ES5 has them at the beginning, not at the end if (arguments.length == 2) return callback.bind(obj); let me = obj; let bindArguments = Array.prototype.slice.call(arguments, 2); return function() { let args = Array.prototype.slice.call(arguments); args = args.concat(bindArguments); return callback.apply(me, args); }; } // Class magic // Adapted from MooTools, MIT license // https://github.com/mootools/mootools-core function _Base() { throw new TypeError('Cannot instantiate abstract class _Base'); } _Base.__super__ = null; _Base.prototype._init = function() { }; _Base.prototype._construct = function() { this._init.apply(this, arguments); return this; }; _Base.prototype.__name__ = '_Base'; _Base.prototype.toString = function() { return '[object ' + this.__name__ + ']'; }; function _parent() { if (!this.__caller__) throw new TypeError("The method 'parent' cannot be called"); let caller = this.__caller__; let name = caller._name; let parent = caller._owner.__super__; let previous = parent ? parent.prototype[name] : undefined; if (!previous) throw new TypeError("The method '" + name + "' is not on the superclass"); return previous.apply(this, arguments); } function _interfacePresent(required, proto) { if (!proto.__interfaces__) return false; if (proto.__interfaces__.indexOf(required) !== -1) return true; // implemented here // Might be implemented on a parent class return _interfacePresent(required, proto.constructor.__super__.prototype); } function getMetaClass(params) { if (params.MetaClass) return params.MetaClass; if (params.Extends && params.Extends.prototype.__metaclass__) return params.Extends.prototype.__metaclass__; return null; } function Class(params) { let metaClass = getMetaClass(params); if (metaClass && metaClass != this.constructor) { // Trick to apply variadic arguments to constructors -- // bind the arguments into the constructor function. let args = Array.prototype.slice.call(arguments); let curried = Function.prototype.bind.apply(metaClass, [,].concat(args)); return new curried(); } else { return this._construct.apply(this, arguments); } } Class.__super__ = _Base; Class.prototype = Object.create(_Base.prototype); Class.prototype.constructor = Class; Class.prototype.__name__ = 'Class'; Class.prototype.wrapFunction = function(name, meth) { if (meth._origin) meth = meth._origin; function wrapper() { let prevCaller = this.__caller__; this.__caller__ = wrapper; let result = meth.apply(this, arguments); this.__caller__ = prevCaller; return result; } wrapper._origin = meth; wrapper._name = name; wrapper._owner = this; return wrapper; } Class.prototype.toString = function() { return '[object ' + this.__name__ + ' for ' + this.prototype.__name__ + ']'; }; Class.prototype._construct = function(params) { if (!params.Name) { throw new TypeError("Classes require an explicit 'Name' parameter."); } let name = params.Name; let parent = params.Extends; if (!parent) parent = _Base; let newClass; if (params.Abstract) { newClass = function() { throw new TypeError('Cannot instantiate abstract class ' + name); }; } else { newClass = function() { this.__caller__ = null; return this._construct.apply(this, arguments); }; } // Since it's not possible to create a constructor with // a custom [[Prototype]], we have to do this to make // "newClass instanceof Class" work, and so we can inherit // methods/properties of Class.prototype, like wrapFunction. newClass.__proto__ = this.constructor.prototype; newClass.__super__ = parent; newClass.prototype = Object.create(parent.prototype); newClass.prototype.constructor = newClass; newClass._init.apply(newClass, arguments); let interfaces = params.Implements || []; // If the parent already implements an interface, then we do too if (parent instanceof Class) interfaces = interfaces.filter((iface) => !parent.implements(iface)); Object.defineProperties(newClass.prototype, { '__metaclass__': { writable: false, configurable: false, enumerable: false, value: this.constructor }, '__interfaces__': { writable: false, configurable: false, enumerable: false, value: interfaces } }); interfaces.forEach((iface) => { iface._check(newClass.prototype); }); return newClass; }; /** * Check whether this class conforms to the interface "iface". * @param {object} iface a Lang.Interface * @returns: whether this class implements iface * @type: boolean */ Class.prototype.implements = function (iface) { if (_interfacePresent(iface, this.prototype)) return true; if (this.__super__ instanceof Class) return this.__super__.implements(iface); return false; }; Class.prototype._init = function(params) { let name = params.Name; let propertyObj = { }; let interfaces = params.Implements || []; interfaces.forEach((iface) => { Object.getOwnPropertyNames(iface.prototype) .filter((name) => !name.startsWith('__') && name !== 'constructor') .forEach((name) => { let descriptor = Object.getOwnPropertyDescriptor(iface.prototype, name); // writable and enumerable are inherited, see note below descriptor.configurable = false; propertyObj[name] = descriptor; }); }); Object.getOwnPropertyNames(params).forEach(function(name) { if (['Name', 'Extends', 'Abstract', 'Implements'].indexOf(name) !== -1) return; let descriptor = Object.getOwnPropertyDescriptor(params, name); if (typeof descriptor.value === 'function') descriptor.value = this.wrapFunction(name, descriptor.value); // we inherit writable and enumerable from the property // descriptor of params (they're both true if created from an // object literal) descriptor.configurable = false; propertyObj[name] = descriptor; }.bind(this)); Object.defineProperties(this.prototype, propertyObj); Object.defineProperties(this.prototype, { '__name__': { writable: false, configurable: false, enumerable: false, value: name }, 'parent': { writable: false, configurable: false, enumerable: false, value: _parent }}); }; // This introduces the concept of a "meta-interface" which is given by the // MetaInterface property on an object's metaclass. For objects whose metaclass // is Lang.Class, the meta-interface is Lang.Interface. Subclasses of Lang.Class // such as GObject.Class supply their own meta-interface. // This is in order to enable creating GObject interfaces with Lang.Interface, // much as you can create GObject classes with Lang.Class. function _getMetaInterface(params) { if (!params.Requires || params.Requires.length === 0) return null; let metaInterface = params.Requires.map((req) => { if (req instanceof Interface) return req.__super__; for (let metaclass = req.prototype.__metaclass__; metaclass; metaclass = metaclass.__super__) { if (metaclass.hasOwnProperty('MetaInterface')) return metaclass.MetaInterface; } return null; }) .reduce((best, candidate) => { // This function reduces to the "most derived" meta interface in the list. if (best === null) return candidate; if (candidate === null) return best; for (let sup = candidate; sup; sup = sup.__super__) { if (sup === best) return candidate; } return best; }, null); // If we reach this point and we don't know the meta-interface, then it's // most likely because there were only pure-C interfaces listed in Requires // (and those don't have our magic properties.) However, all pure-C // interfaces should require GObject.Object anyway. if (metaInterface === null) throw new Error('Did you forget to include GObject.Object in Requires?'); return metaInterface; } function Interface(params) { let metaInterface = _getMetaInterface(params); if (metaInterface && metaInterface !== this.constructor) { // Trick to apply variadic arguments to constructors -- // bind the arguments into the constructor function. let args = Array.prototype.slice.call(arguments); let curried = Function.prototype.bind.apply(metaInterface, [,].concat(args)); return new curried(); } return this._construct.apply(this, arguments); } Class.MetaInterface = Interface; /** * Use this to signify a function that must be overridden in an implementation * of the interface. Creating a class that doesn't override the function will * throw an error. */ Interface.UNIMPLEMENTED = function () { throw new Error('Not implemented'); }; Interface.__super__ = _Base; Interface.prototype = Object.create(_Base.prototype); Interface.prototype.constructor = Interface; Interface.prototype.__name__ = 'Interface'; Interface.prototype._construct = function (params) { if (!params.Name) throw new TypeError("Interfaces require an explicit 'Name' parameter."); let name = params.Name; let newInterface = function () { throw new TypeError('Cannot instantiate interface ' + name); }; // See note in Class._construct(); this makes "newInterface instanceof // Interface" work, and allows inheritance. newInterface.__proto__ = this.constructor.prototype; newInterface.__super__ = Interface; newInterface.prototype = Object.create(Interface.prototype); newInterface.prototype.constructor = newInterface; newInterface._init.apply(newInterface, arguments); Object.defineProperty(newInterface.prototype, '__metaclass__', { writable: false, configurable: false, enumerable: false, value: this.constructor }); return newInterface; }; Interface.prototype._check = function (proto) { // Check that proto implements all of this interface's required interfaces. // "proto" refers to the object's prototype (which implements the interface) // whereas "this.prototype" is the interface's prototype (which may still // contain unimplemented methods.) let unfulfilledReqs = this.prototype.__requires__.filter((required) => { // Either the interface is not present or it is not listed before the // interface that requires it or the class does not inherit it. This is // so that required interfaces don't copy over properties from other // interfaces that require them. let interfaces = proto.__interfaces__; return ((!_interfacePresent(required, proto) || interfaces.indexOf(required) > interfaces.indexOf(this)) && !(proto instanceof required)); }).map((required) => // __name__ is only present on GJS-created classes and will be the most // accurate name. required.name will be present on introspected GObjects // but is not preferred because it will be the C name. The last option // is just so that we print something if there is garbage in Requires. required.prototype.__name__ || required.name || required); if (unfulfilledReqs.length > 0) { throw new Error('The following interfaces must be implemented before ' + this.prototype.__name__ + ': ' + unfulfilledReqs.join(', ')); } // Check that this interface's required methods are implemented let unimplementedFns = Object.getOwnPropertyNames(this.prototype) .filter((p) => this.prototype[p] === Interface.UNIMPLEMENTED) .filter((p) => !(p in proto) || proto[p] === Interface.UNIMPLEMENTED); if (unimplementedFns.length > 0) throw new Error('The following members of ' + this.prototype.__name__ + ' are not implemented yet: ' + unimplementedFns.join(', ')); }; Interface.prototype.toString = function () { return '[interface ' + this.__name__ + ' for ' + this.prototype.__name__ + ']'; }; Interface.prototype._init = function (params) { let name = params.Name; let propertyObj = {}; Object.getOwnPropertyNames(params) .filter((name) => ['Name', 'Requires'].indexOf(name) === -1) .forEach((name) => { let descriptor = Object.getOwnPropertyDescriptor(params, name); // Create wrappers on the interface object so that generics work (e.g. // SomeInterface.some_function(this, blah) instead of // SomeInterface.prototype.some_function.call(this, blah) if (typeof descriptor.value === 'function') { let interfaceProto = this.prototype; // capture in closure this[name] = function () { return interfaceProto[name].call.apply(interfaceProto[name], arguments); }; } // writable and enumerable are inherited, see note in Class._init() descriptor.configurable = false; propertyObj[name] = descriptor; }); Object.defineProperties(this.prototype, propertyObj); Object.defineProperties(this.prototype, { '__name__': { writable: false, configurable: false, enumerable: false, value: name }, '__requires__': { writable: false, configurable: false, enumerable: false, value: params.Requires || [] } }); }; seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/gjs/mainloop.js000066400000000000000000000054571303774616400232500ustar00rootroot00000000000000/* -*- mode: js; indent-tabs-mode: nil; -*- */ // Copyright (c) 2012 Giovanni Campagna // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. // A layer of convenience and backwards-compatibility over GLib MainLoop facilities const GLib = imports.gi.GLib; const GObject = imports.gi.GObject; var _mainLoops = {}; function run(name) { if (!_mainLoops[name]) _mainLoops[name] = GLib.MainLoop.new(null, false); _mainLoops[name].run(); } function quit(name) { if (!_mainLoops[name]) throw new Error("No main loop with this id"); let loop = _mainLoops[name]; delete _mainLoops[name]; if (!loop.is_running()) throw new Error("Main loop was stopped already"); loop.quit(); } function idle_source(handler, priority) { let s = GLib.idle_source_new(); GObject.source_set_closure(s, handler); if (priority !== undefined) s.set_priority(priority); return s; } function idle_add(handler, priority) { return idle_source(handler, priority).attach(null); } function timeout_source(timeout, handler, priority) { let s = GLib.timeout_source_new(timeout); GObject.source_set_closure(s, handler); if (priority !== undefined) s.set_priority(priority); return s; } function timeout_seconds_source(timeout, handler, priority) { let s = GLib.timeout_source_new_seconds(timeout); GObject.source_set_closure(s, handler); if (priority !== undefined) s.set_priority(priority); return s; } function timeout_add(timeout, handler, priority) { return timeout_source(timeout, handler, priority).attach(null); } function timeout_add_seconds(timeout, handler, priority) { return timeout_seconds_source(timeout, handler, priority).attach(null); } function source_remove(id) { return GLib.source_remove(id); } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/gjs/package.js000066400000000000000000000201471303774616400230160ustar00rootroot00000000000000// Copyright 2012 Giovanni Campagna // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. /** * This module provides a set of convenience APIs for building packaged * applications. */ const GLib = imports.gi.GLib; const GIRepository = imports.gi.GIRepository; const Gio = imports.gi.Gio; const System = imports.system; const Gettext = imports.gettext; /*< public >*/ var name; var version; var prefix; var datadir; var libdir; var pkgdatadir; var pkglibdir; var moduledir; var localedir; /*< private >*/ let _pkgname; let _base; function _findEffectiveEntryPointName() { let entryPoint = System.programInvocationName; while (GLib.file_test(entryPoint, GLib.FileTest.IS_SYMLINK)) entryPoint = GLib.file_read_link(entryPoint); return GLib.path_get_basename(entryPoint); } function _runningFromSource() { let binary = Gio.File.new_for_path(System.programInvocationName); let sourceBinary = Gio.File.new_for_path('./src/' + name); return binary.equal(sourceBinary); } function _makeNamePath(name) { return '/' + name.replace('.', '/', 'g'); } /** * init: * @params: package parameters * * Initialize directories and global variables. Must be called * before any of other API in Package is used. * @params must be an object with at least the following keys: * - name: the package name ($(PACKAGE_NAME) in autotools, * eg. org.foo.Bar) * - version: the package version * - prefix: the installation prefix * * init() will take care to check if the program is running from * the source directory or not, by looking for a 'src' directory. * * At the end, the global variable 'pkg' will contain the * Package module (imports.package). Additionally, the following * module variables will be available: * - name: the base name of the entry point (eg. org.foo.Bar.App) * - version: same as in @params * - prefix: the installation prefix (as passed in @params) * - datadir, libdir: the final datadir and libdir when installed; * usually, these would be prefix + '/share' and * and prefix + '/lib' (or '/lib64') * - pkgdatadir: the directory to look for private data files, such as * images, stylesheets and UI definitions; * this will be datadir + name when installed and * './data' when running from the source tree * - pkglibdir: the directory to look for private typelibs and C * libraries; * this will be libdir + name when installed and * './lib' when running from the source tree * - moduledir: the directory to look for JS modules; * this will be pkglibdir when installed and * './src' when running from the source tree * - localedir: the directory containing gettext translation files; * this will be datadir + '/locale' when installed * and './po' in the source tree * * All paths are absolute and will not end with '/'. * * As a side effect, init() calls GLib.set_prgname(). */ function init(params) { window.pkg = imports.package; _pkgname = params.name; name = _findEffectiveEntryPointName(); version = params.version; // Must call it first, because it can only be called // once, and other library calls might have it as a // side effect GLib.set_prgname(name); prefix = params.prefix; libdir = params.libdir; datadir = GLib.build_filenamev([prefix, 'share']); let libpath, girpath; if (_runningFromSource()) { log('Running from source tree, using local files'); // Running from source directory _base = GLib.get_current_dir(); pkglibdir = GLib.build_filenamev([_base, 'lib']); libpath = GLib.build_filenamev([pkglibdir, '.libs']); girpath = pkglibdir; pkgdatadir = GLib.build_filenamev([_base, 'data']); localedir = GLib.build_filenamev([_base, 'po']); moduledir = GLib.build_filenamev([_base, 'src']); } else { _base = prefix; pkglibdir = GLib.build_filenamev([libdir, _pkgname]); libpath = pkglibdir; girpath = GLib.build_filenamev([pkglibdir, 'girepository-1.0']); pkgdatadir = GLib.build_filenamev([datadir, _pkgname]); localedir = GLib.build_filenamev([datadir, 'locale']); try { let resource = Gio.Resource.load(GLib.build_filenamev([pkgdatadir, name + '.src.gresource'])); resource._register(); moduledir = 'resource://' + _makeNamePath(name) + '/js'; } catch(e) { moduledir = pkgdatadir; } } imports.searchPath.unshift(moduledir); GIRepository.Repository.prepend_search_path(girpath); GIRepository.Repository.prepend_library_path(libpath); try { let resource = Gio.Resource.load(GLib.build_filenamev([pkgdatadir, name + '.data.gresource'])); resource._register(); } catch(e) { } } /** * start: * @params: see init() * * This is a convenience function if your package has a * single entry point. * You must define a main(ARGV) function inside a main.js * module in moduledir. */ function start(params) { init(params); run(imports.main); } /** * run: * @module: the module to run * * This is the function to use if you want to have multiple * entry points in one package. * You must define a main(ARGV) function inside the passed * in module, and then the launcher would be * * imports.package.init(...); * imports.package.run(imports.entrypoint); */ function run(module) { return module.main([System.programInvocationName].concat(ARGV)); } /** * require: * @libs: the external dependencies to import * * Mark a dependency on a specific version of one or more * external GI typelibs. * @libs must be an object whose keys are a typelib name, * and values are the respective version. The empty string * indicates any version. */ function require(libs) { for (let l in libs) { let version = libs[l]; if (version != '') imports.gi.versions[l] = version; try { imports.gi[l]; } catch(e) { printerr('Unsatisfied dependency: ' + e.message); System.exit(1); } } } function initGettext() { Gettext.bindtextdomain(_pkgname, localedir); Gettext.textdomain(_pkgname); let gettext = imports.gettext; window._ = gettext.gettext; window.C_ = gettext.pgettext; window.N_ = function(x) { return x; } } function initFormat() { let format = imports.format; String.prototype.format = format.format; } function initSubmodule(name) { if (moduledir != pkgdatadir) { // Running from source tree, add './name' to search paths let submoduledir = GLib.build_filenamev([_base, name]); let libpath = GLib.build_filenamev([submoduledir, '.libs']); GIRepository.Repository.prepend_search_path(submoduledir); GIRepository.Repository.prepend_library_path(libpath); } else { // Running installed, submodule is in $(pkglibdir), nothing to do } } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/gjs/signals.js000066400000000000000000000125671303774616400230720ustar00rootroot00000000000000/* * Copyright (c) 2008 litl, LLC * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ // A couple principals of this simple signal system: // 1) should look just like our GObject signal binding // 2) memory and safety matter more than speed of connect/disconnect/emit // 3) the expectation is that a given object will have a very small number of // connections, but they may be to different signal names function _connect(name, callback) { // be paranoid about callback arg since we'd start to throw from emit() // if it was messed up if (typeof(callback) != 'function') throw new Error("When connecting signal must give a callback that is a function"); // we instantiate the "signal machinery" only on-demand if anything // gets connected. if (!('_signalConnections' in this)) { this._signalConnections = []; this._nextConnectionId = 1; } let id = this._nextConnectionId; this._nextConnectionId += 1; // this makes it O(n) in total connections to emit, but I think // it's right to optimize for low memory and reentrancy-safety // rather than speed this._signalConnections.push({ 'id' : id, 'name' : name, 'callback' : callback, 'disconnected' : false }); return id; } function _disconnect(id) { if ('_signalConnections' in this) { let i; let length = this._signalConnections.length; for (i = 0; i < length; ++i) { let connection = this._signalConnections[i]; if (connection.id == id) { if (connection.disconnected) throw new Error("Signal handler id " + id + " already disconnected"); // set a flag to deal with removal during emission connection.disconnected = true; this._signalConnections.splice(i, 1); return; } } } throw new Error("No signal connection " + id + " found"); } function _disconnectAll() { if ('_signalConnections' in this) { while (this._signalConnections.length > 0) { _disconnect.call(this, this._signalConnections[0].id); } } } function _emit(name /* , arg1, arg2 */) { // may not be any signal handlers at all, if not then return if (!('_signalConnections' in this)) return; // To deal with re-entrancy (removal/addition while // emitting), we copy out a list of what was connected // at emission start; and just before invoking each // handler we check its disconnected flag. let handlers = []; let i; let length = this._signalConnections.length; for (i = 0; i < length; ++i) { let connection = this._signalConnections[i]; if (connection.name == name) { handlers.push(connection); } } // create arg array which is emitter + everything passed in except // signal name. Would be more convenient not to pass emitter to // the callback, but trying to be 100% consistent with GObject // which does pass it in. Also if we pass in the emitter here, // people don't create closures with the emitter in them, // which would be a cycle. let arg_array = [ this ]; // arguments[0] should be signal name so skip it length = arguments.length; for (i = 1; i < length; ++i) { arg_array.push(arguments[i]); } length = handlers.length; for (i = 0; i < length; ++i) { let connection = handlers[i]; if (!connection.disconnected) { try { // since we pass "null" for this, the global object will be used. let ret = connection.callback.apply(null, arg_array); // if the callback returns true, we don't call the next // signal handlers if (ret === true) { break; } } catch(e) { // just log any exceptions so that callbacks can't disrupt // signal emission logError(e, "Exception in callback for signal: "+name); } } } } function addSignalMethods(proto) { proto.connect = _connect; proto.disconnect = _disconnect; proto.emit = _emit; // this one is not in GObject, but useful proto.disconnectAll = _disconnectAll; } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/gjs/system/000077500000000000000000000000001303774616400224055ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/gjs/system/Makefile.am000066400000000000000000000007621303774616400244460ustar00rootroot00000000000000seedlibdir = ${libdir}/seed@SEED_GTK_VERSION@/gjs seedlib_LTLIBRARIES = \ libseed_system.la libseed_system_la_SOURCES = \ seed-system.c AM_CPPFLAGS = \ -I@top_srcdir@/libseed/ \ $(GOBJECT_INTROSPECTION_CFLAGS) \ $(SEED_DEBUG_CFLAGS) \ $(SEED_PROFILE_CFLAGS) libseed_system_la_LDFLAGS = \ -module -avoid-version \ $(GOBJECT_INTROSPECTION_LDFLAGS) libseed_system_la_LIBADD = \ $(top_builddir)/libseed/libseed@SEED_GTK_VERSION@.la \ $(SEED_PROFILE_LIBS) -include $(top_srcdir)/git.mk seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/gjs/system/seed-system.c000066400000000000000000000160571303774616400250240ustar00rootroot00000000000000/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ /* * Copyright (c) 2008 litl, LLC * Copyright (c) 2012 Red Hat, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #include #include #include #include #include #include #include #include #define GJS_COMPAT_VERSION (1 * 100 + 40) * 100 + 0 #define NUMARG_EXPECTED_EXCEPTION(name, argc) \ seed_make_exception(ctx, exception, "ArgumentError", \ name " expected " argc " but got %zd", argumentCount); \ return seed_make_undefined(ctx); static SeedValue gjs_address_of(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argumentCount, const SeedValue arguments[], SeedException* exception) { if (argumentCount != 1) { NUMARG_EXPECTED_EXCEPTION("addressOf", "1 argument") } SeedValue targetValue = arguments[0]; if (!seed_value_is_object(ctx, targetValue)) { seed_make_exception(ctx, exception, "ArgumentError", "addressOf expects an object"); return seed_make_undefined(ctx); } char* pointer_string = g_strdup_printf("%p", targetValue); SeedValue ret = seed_value_from_string(ctx, pointer_string, exception); g_free(pointer_string); return ret; } static SeedValue gjs_refcount(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argumentCount, const SeedValue arguments[], SeedException* exception) { if (argumentCount != 1) { NUMARG_EXPECTED_EXCEPTION("refcount", "1 argument"); } SeedValue targetValue = arguments[0]; GObject* object = seed_value_to_object(ctx, targetValue, exception); if (!object) return seed_make_undefined(ctx); SeedValue ret = seed_value_from_uint64(ctx, object->ref_count, exception); return ret; } static SeedValue gjs_breakpoint(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argumentCount, const SeedValue arguments[], SeedException* exception) { if (argumentCount != 0) { NUMARG_EXPECTED_EXCEPTION("breakpoint", "0 arguments"); } G_BREAKPOINT(); return seed_make_undefined(ctx); } static SeedValue gjs_gc(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argumentCount, const SeedValue arguments[], SeedException* exception) { if (argumentCount != 0) { NUMARG_EXPECTED_EXCEPTION("gc", "0 arguments"); } seed_context_collect(ctx); return seed_make_undefined(ctx); } static SeedValue gjs_exit(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argumentCount, const SeedValue arguments[], SeedException* exception) { gint32 ret = EXIT_SUCCESS; if (argumentCount > 1) { NUMARG_EXPECTED_EXCEPTION("exit", "none or 1 argument"); } if (argumentCount == 1) { SeedValue target = arguments[0]; if (seed_value_is_number(ctx, target)) { ret = seed_value_to_int(ctx, target, exception); } else { seed_make_exception(ctx, exception, "ArgumentError", "exit expects a number argument"); ret = EXIT_FAILURE; } } exit(ret); } static SeedValue gjs_clear_date_caches(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argumentCount, const SeedValue arguments[], SeedException* exception) { // This is provided just for compatibility as javascriptcore doesn't provide // the same // feature. // I'm not even sure that this is needed for webkit. seed_make_exception(ctx, exception, "ImplementationError", "clearDateCache is not implemented."); return seed_make_undefined(ctx); } static seed_static_function module_funcs[] = { { "addressOf", gjs_address_of, 0 }, { "refcount", gjs_refcount, 0 }, { "breakpoint", gjs_breakpoint, 0 }, { "gc", gjs_gc, 0 }, { "exit", gjs_exit, 0 }, { "clearDateCaches", gjs_clear_date_caches, 0 }, { 0, 0, 0 } }; static seed_class_definition system_def = { 0, /* Version, always 0 */ SEED_CLASS_ATTRIBUTE_NO_SHARED_PROTOTYPE, /* JSClassAttributes */ "System", /* Class Name */ NULL, /* Parent Class */ NULL, /* Static Values */ module_funcs, /* Static Functions */ NULL, NULL, /* Finalize */ NULL, /* Has Property */ NULL, /* Get Property */ NULL, /* Set Property */ NULL, /* Delete Property */ NULL, /* Get Property Names */ NULL, /* Call As Function */ NULL, /* Call As Constructor */ NULL, /* Has Instance */ NULL /* Convert To Type */ }; SeedObject gjs_compat_define_system_stuff(SeedEngine* eng) { SeedContext context = eng->context; SeedObject module; gboolean ret; module = seed_make_object(context, seed_create_class(&system_def), NULL); SeedValue seed = seed_object_get_property(context, eng->global, "Seed"); SeedValue argv = seed_object_get_property(context, seed, "argv"); /* The name is modeled after program_invocation_name, part of the glibc */ ret = seed_object_set_property( context, module, "programInvocationName", (SeedValue) seed_value_from_string(context, eng->program_name, NULL)); ret = seed_object_set_property( context, module, "version", (SeedValue) seed_value_from_int(context, GJS_COMPAT_VERSION, NULL)); return module; } SeedObject seed_module_init(SeedEngine* eng) { return gjs_compat_define_system_stuff(eng); } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/gtkbuilder/000077500000000000000000000000001303774616400224325ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/gtkbuilder/Makefile.am000066400000000000000000000011321303774616400244630ustar00rootroot00000000000000if BUILD_GTKBUILDER_MODULE seedlibdir = ${libdir}/seed@SEED_GTK_VERSION@ seedlib_LTLIBRARIES = \ libseed_gtkbuilder.la libseed_gtkbuilder_la_SOURCES = \ seed-gtkbuilder.c AM_CPPFLAGS = \ -I@top_srcdir@/libseed/ \ $(GOBJECT_INTROSPECTION_CFLAGS) \ $(GTK_CFLAGS) \ $(SEED_DEBUG_CFLAGS) \ $(SEED_PROFILE_CFLAGS) libseed_gtkbuilder_la_LDFLAGS = \ -module -avoid-version \ $(GTK_LDFLAGS) \ $(GOBJECT_INTROSPECTION_LDFLAGS) libseed_gtkbuilder_la_LIBADD = \ $(top_builddir)/libseed/libseed@SEED_GTK_VERSION@.la \ $(GTK_LIBS) \ $(SEED_PROFILE_LIBS) endif -include $(top_srcdir)/git.mk seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/gtkbuilder/seed-gtkbuilder.c000066400000000000000000000065101303774616400256520ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #include #include typedef struct _builder_ud { SeedContext ctx; SeedObject obj; SeedObject user_data; } builder_ud; static void seed_builder_connect_func(GtkBuilder* builder, GObject* object, const gchar* signal_name, const gchar* handler_name, GObject* connect_object, GConnectFlags flags, gpointer user_data) { SeedContext ctx; SeedObject obj, func; builder_ud* priv = (builder_ud*) user_data; GClosure* closure; ctx = priv->ctx; obj = priv->obj; func = seed_object_get_property(ctx, obj, handler_name); if (!seed_value_is_object(ctx, func) || !seed_value_is_function(ctx, func)) return; closure = seed_closure_new(ctx, func, priv->user_data, "signal handler (GtkBuilder)"); if (connect_object != NULL) g_object_watch_closure(connect_object, closure); g_signal_connect_closure(object, signal_name, closure, FALSE); } SeedValue seed_gtk_builder_connect_signals(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { builder_ud ud; GtkBuilder* b; CHECK_ARG_COUNT("GtkBuilder.connect_signals", 1); if (!seed_value_is_object(ctx, arguments[0])) { seed_make_exception( ctx, exception, "TypeError", "connect_signals expects one object as the first argument"); return seed_make_undefined(ctx); } b = GTK_BUILDER(seed_value_to_object(ctx, this_object, exception)); ud.ctx = ctx; ud.obj = arguments[0]; if (argument_count == 2) ud.user_data = arguments[1]; else ud.user_data = NULL; gtk_builder_connect_signals_full(b, seed_builder_connect_func, &ud); return seed_make_undefined(ctx); } SeedObject seed_module_init(SeedEngine* eng) { SeedObject gtkbuilder_proto; gtkbuilder_proto = seed_simple_evaluate(eng->context, "imports.gi.Gtk.Builder.prototype", NULL); seed_create_function(eng->context, "connect_signals", seed_gtk_builder_connect_signals, gtkbuilder_proto); return seed_make_object(eng->context, NULL, NULL); } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/libxml/000077500000000000000000000000001303774616400215655ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/libxml/Makefile.am000066400000000000000000000012621303774616400236220ustar00rootroot00000000000000if BUILD_LIBXML_MODULE EXTRA_DIST = xml.js seedlibdir = ${libdir}/seed@SEED_GTK_VERSION@ seedlib_LTLIBRARIES = \ libseed_libxml.la libseed_libxml_la_SOURCES = \ seed-libxml.c AM_CPPFLAGS = \ -I@top_srcdir@/libseed/ \ $(LIBXML_CFLAGS) \ $(GOBJECT_INTROSPECTION_CFLAGS) \ $(SEED_DEBUG_CFLAGS) \ $(SEED_PROFILE_CFLAGS) libseed_libxml_la_LDFLAGS = \ -module -avoid-version \ $(LIBXML_LDFLAGS) \ $(GOBJECT_INTROSPECTION_LDFLAGS) libseed_libxml_la_LIBADD = \ $(top_builddir)/libseed/libseed@SEED_GTK_VERSION@.la \ $(LIBXML_LIBS) \ $(SEED_PROFILE_LIBS) extensionsdir=$(datadir)/seed@SEED_GTK_VERSION@/extensions extensions_DATA=xml.js endif -include $(top_srcdir)/git.mk seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/libxml/seed-libxml.c000066400000000000000000000431761303774616400241510ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #include #include #include #include #include #include #include #include // for xmlXPathRegisterNs SeedObject namespace_ref; SeedEngine* eng; SeedClass xml_doc_class; SeedClass xml_node_class; SeedClass xml_attr_class; SeedClass xml_xpath_class; SeedClass xml_xpathobj_class; #define XML_DOC_PRIV(obj) ((xmlDocPtr) seed_object_get_private(obj)) #define XML_NODE_PRIV(obj) ((xmlNodePtr) seed_object_get_private(obj)) #define XML_XPATH_PRIV(obj) ((xmlXPathContextPtr) seed_object_get_private(obj)) #define XML_XPATHOBJ_PRIV(obj) \ ((xmlXPathObjectPtr) seed_object_get_private(obj)) static SeedObject seed_make_xml_doc(SeedContext ctx, xmlDocPtr doc) { SeedObject ret; if (doc->_private) return (SeedObject) doc->_private; ret = seed_make_object(ctx, xml_doc_class, doc); doc->_private = ret; return ret; } static SeedObject seed_make_xml_node(SeedContext ctx, xmlNodePtr node) { SeedObject ret; if (node == NULL) return seed_make_null(ctx); if (node->_private) return (SeedObject) node->_private; ret = seed_make_object(ctx, xml_node_class, node); node->_private = ret; return ret; } static SeedObject seed_make_xml_attr(SeedContext ctx, xmlAttrPtr attr) { SeedObject ret; if (attr == NULL) return seed_make_null(ctx); if (attr->_private) return (SeedObject) attr->_private; ret = seed_make_object(ctx, xml_attr_class, attr); attr->_private = ret; return ret; } static gchar* seed_xml_element_type_to_string(xmlElementType type) { if (type == XML_ELEMENT_NODE) return "element"; else if (type == XML_ATTRIBUTE_NODE) return "attribute"; else if (type == XML_TEXT_NODE) return "text"; else return "Implement more types! racarr is lazy."; } static SeedValue seed_xml_parse_file(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { SeedObject ret; xmlDocPtr doc; gchar* path; if (argument_count != 1) { seed_make_exception(ctx, exception, "ArgumentError", "parseFile expected 1 argument, got %zd", argument_count); return seed_make_null(ctx); } path = seed_value_to_string(ctx, arguments[0], exception); doc = xmlParseFile(path); if (!doc) { seed_make_exception(ctx, exception, "XMLError", "Document not parsed successfully"); g_free(path); return seed_make_null(ctx); } ret = seed_make_xml_doc(ctx, doc); g_free(path); return ret; } static SeedValue seed_xml_parse_string(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { SeedObject ret; xmlDocPtr doc; gchar* string; if (argument_count != 1) { seed_make_exception(ctx, exception, "ArgumentError", "parseString expected 1 argument, got %zd", argument_count); return seed_make_null(ctx); } string = seed_value_to_string(ctx, arguments[0], exception); doc = xmlParseMemory(string, strlen(string)); if (!doc) { seed_make_exception(ctx, exception, "XMLError", "Document not parsed successfully"); g_free(string); return seed_make_null(ctx); } ret = seed_make_xml_doc(ctx, doc); g_free(string); return ret; } static SeedValue seed_xml_doc_get_root(SeedContext ctx, SeedObject object, SeedString property_name, SeedException* exception) { xmlDocPtr doc = XML_DOC_PRIV(object); return seed_make_xml_node(ctx, xmlDocGetRootElement(doc)); } static void seed_xml_doc_finalize(SeedObject object) { xmlDocPtr ptr = XML_DOC_PRIV(object); xmlFreeDoc(ptr); } static SeedValue seed_xml_node_get_name(SeedContext ctx, SeedObject object, SeedString property_name, SeedException* exception) { xmlNodePtr node = XML_NODE_PRIV(object); return seed_value_from_string(ctx, (gchar*) node->name, exception); } static SeedValue seed_xml_node_get_children(SeedContext ctx, SeedObject object, SeedString property_name, SeedException* exception) { xmlNodePtr node = XML_NODE_PRIV(object); return seed_make_xml_node(ctx, node->children); } static SeedValue seed_xml_node_get_parent(SeedContext ctx, SeedObject object, SeedString property_name, SeedException* exception) { xmlNodePtr node = XML_NODE_PRIV(object); return seed_make_xml_node(ctx, node->parent); } static SeedValue seed_xml_node_get_next(SeedContext ctx, SeedObject object, SeedString property_name, SeedException* exception) { xmlNodePtr node = XML_NODE_PRIV(object); return seed_make_xml_node(ctx, node->next); } static SeedValue seed_xml_node_get_prev(SeedContext ctx, SeedObject object, SeedString property_name, SeedException* exception) { xmlNodePtr node = XML_NODE_PRIV(object); return seed_make_xml_node(ctx, node->prev); } static SeedValue seed_xml_node_get_last(SeedContext ctx, SeedObject object, SeedString property_name, SeedException* exception) { xmlNodePtr node = XML_NODE_PRIV(object); return seed_make_xml_node(ctx, node->last); } static SeedValue seed_xml_node_get_doc(SeedContext ctx, SeedObject object, SeedString property_name, SeedException* exception) { xmlNodePtr node = XML_NODE_PRIV(object); return seed_make_xml_doc(ctx, node->doc); } static SeedValue seed_xml_node_get_content(SeedContext ctx, SeedObject object, SeedString property_name, SeedException* exception) { SeedValue ret; gchar* content; xmlNodePtr node = XML_NODE_PRIV(object); content = (gchar*) xmlNodeGetContent(node); ret = seed_value_from_string(ctx, content, exception); g_free(content); return ret; } static SeedValue seed_xml_node_get_type(SeedContext ctx, SeedObject object, SeedString property_name, SeedException* exception) { xmlNodePtr node = XML_NODE_PRIV(object); return seed_value_from_string(ctx, seed_xml_element_type_to_string(node->type), exception); } static SeedValue seed_xml_node_get_properties(SeedContext ctx, SeedObject object, SeedString property_name, SeedException* exception) { xmlNodePtr node = XML_NODE_PRIV(object); return seed_make_xml_attr(ctx, node->properties); } static void seed_xml_node_init(SeedContext ctx, SeedObject object) { xmlNodePtr node = XML_NODE_PRIV(object); if (node && node->doc->_private) seed_value_protect(ctx, node->doc->_private); } static void seed_xml_node_finalize(SeedObject object) { xmlNodePtr node = XML_NODE_PRIV(object); if (!node) return; node->_private = NULL; // This might be invalid. if (node->doc->_private) seed_value_unprotect(eng->context, node->doc->_private); } static SeedValue seed_xml_xpath_eval(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { xmlXPathObjectPtr xpath_obj; xmlXPathContextPtr xpath_ctx; guchar* xpath; if (argument_count != 1) { seed_make_exception(ctx, exception, "ArgumentError", "xpathEval expected 1 argument, got %zd", argument_count); return seed_make_null(ctx); } xpath_ctx = XML_XPATH_PRIV(this_object); xpath = (guchar*) seed_value_to_string(ctx, arguments[0], exception); xpath_obj = xmlXPathEval(xpath, xpath_ctx); g_free(xpath); return seed_make_object(ctx, xml_xpathobj_class, xpath_obj); } static SeedValue seed_xml_xpath_register_ns(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { xmlXPathContextPtr xpath; guchar* prefix; guchar* ns_uri; if (argument_count != 2) { seed_make_exception(ctx, exception, "ArgumentError", "xpathRegisterNs expects 2 arguments, got %zd", argument_count); return seed_make_undefined(ctx); } xpath = XML_XPATH_PRIV(this_object); prefix = (guchar*) seed_value_to_string(ctx, arguments[0], exception); ns_uri = (guchar*) seed_value_to_string(ctx, arguments[1], exception); xmlXPathRegisterNs(xpath, prefix, ns_uri); g_free(prefix); g_free(ns_uri); return seed_make_undefined(ctx); } static SeedValue seed_xml_construct_xpath_context(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { xmlXPathContextPtr xpath; xmlDocPtr doc; doc = XML_DOC_PRIV(this_object); xpath = xmlXPathNewContext(doc); seed_value_protect(ctx, this_object); return seed_make_object(ctx, xml_xpath_class, xpath); } static void seed_xml_xpath_finalize(SeedObject object) { xmlXPathContextPtr xpath = XML_XPATH_PRIV(object); // Maybe unsafe. Seems to work. seed_value_unprotect(eng->context, xpath->doc->_private); xmlXPathFreeContext(xpath); } static void seed_xml_xpathobj_finalize(SeedObject object) { xmlXPathObjectPtr xpath = XML_XPATHOBJ_PRIV(object); xmlXPathFreeObject(xpath); } static SeedValue seed_xml_array_from_nodeset(SeedContext ctx, xmlNodeSetPtr nodeset, SeedException* exception) { SeedValue* ary = g_alloca(nodeset->nodeNr * sizeof(SeedValue)); int i; for (i = 0; i < nodeset->nodeNr; i++) { ary[i] = seed_make_xml_node(ctx, nodeset->nodeTab[i]); } return seed_make_array(ctx, ary, nodeset->nodeNr, exception); } static SeedValue seed_xml_xpathobj_get_value(SeedContext ctx, SeedObject object, SeedString property_name, SeedException* exception) { xmlXPathObjectPtr xpath = XML_XPATHOBJ_PRIV(object); switch (xpath->type) { /* case XPATH_BOOLEAN: return seed_value_from_boolean (ctx, xpath->boolval, exception); case XPATH_NUMBER: return seed_value_from_double (ctx, xpath->floatval, exception); case XPATH_STRING: return seed_value_from_string (ctx, xpath->stringval, exception);*/ case XPATH_NODESET: return seed_xml_array_from_nodeset(ctx, xpath->nodesetval, exception); default: return seed_make_null(ctx); } } seed_static_function doc_funcs[] = { { "xpathNewContext", seed_xml_construct_xpath_context, 0 }, { NULL, NULL, 0 } }; seed_static_value doc_values[] = { { "root", seed_xml_doc_get_root, NULL, 0 }, { "name", seed_xml_node_get_name, NULL, 0 }, { "children", seed_xml_node_get_children, NULL, 0 }, { "parent", seed_xml_node_get_parent, NULL, 0 }, { "next", seed_xml_node_get_next, NULL, 0 }, { "prev", seed_xml_node_get_prev, NULL, 0 }, { "last", seed_xml_node_get_last, NULL, 0 }, { "doc", seed_xml_node_get_doc, NULL, 0 }, { "type", seed_xml_node_get_type, NULL, 0 }, { NULL, NULL, NULL, 0 } }; seed_static_function node_funcs[] = { { NULL, NULL, 0 } }; seed_static_value node_values[] = { { "name", seed_xml_node_get_name, NULL, 0 }, { "children", seed_xml_node_get_children, NULL, 0 }, { "parent", seed_xml_node_get_parent, NULL, 0 }, { "next", seed_xml_node_get_next, NULL, 0 }, { "prev", seed_xml_node_get_prev, NULL, 0 }, { "content", seed_xml_node_get_content, NULL, 0 }, { "last", seed_xml_node_get_last, NULL, 0 }, { "doc", seed_xml_node_get_doc, NULL, 0 }, { "type", seed_xml_node_get_type, NULL, 0 }, { "properties", seed_xml_node_get_properties, NULL, 0 }, { NULL, NULL, NULL, 0 } }; seed_static_function attr_funcs[] = { { NULL, NULL, 0 } }; seed_static_value attr_values[] = { { "name", seed_xml_node_get_name, NULL, 0 }, { "children", seed_xml_node_get_children, NULL, 0 }, { "parent", seed_xml_node_get_parent, NULL, 0 }, { "next", seed_xml_node_get_next, NULL, 0 }, { "prev", seed_xml_node_get_prev, NULL, 0 }, { "last", seed_xml_node_get_last, NULL, 0 }, { "doc", seed_xml_node_get_doc, NULL, 0 }, { "type", seed_xml_node_get_type, NULL, 0 }, { NULL, NULL, NULL, 0 } }; seed_static_function xpath_funcs[] = { { "xpathEval", seed_xml_xpath_eval, 0 }, { "xpathRegisterNs", seed_xml_xpath_register_ns, 0 }, { NULL, NULL, 0 } }; seed_static_value xpathobj_values[] = { { "value", seed_xml_xpathobj_get_value, NULL, 0 }, { NULL, NULL, NULL, 0 } }; static void seed_libxml_define_stuff() { SeedObject node_proto; seed_class_definition xml_doc_class_def = seed_empty_class; seed_class_definition xml_node_class_def = seed_empty_class; seed_class_definition xml_attr_class_def = seed_empty_class; seed_class_definition xml_xpath_class_def = seed_empty_class; seed_class_definition xml_xpathobj_class_def = seed_empty_class; xml_doc_class_def.class_name = "XMLDocument"; xml_doc_class_def.static_functions = doc_funcs; xml_doc_class_def.static_values = doc_values; xml_doc_class_def.finalize = seed_xml_doc_finalize; xml_doc_class = seed_create_class(&xml_doc_class_def); xml_node_class_def.class_name = "XMLNode"; xml_node_class_def.static_functions = node_funcs; xml_node_class_def.static_values = node_values; xml_node_class_def.finalize = seed_xml_node_finalize; xml_node_class_def.initialize = seed_xml_node_init; xml_node_class = seed_create_class(&xml_node_class_def); xml_attr_class_def.class_name = "XMLAttribute"; xml_attr_class_def.static_functions = attr_funcs; xml_attr_class_def.static_values = attr_values; xml_attr_class_def.finalize = seed_xml_node_finalize; xml_attr_class_def.initialize = seed_xml_node_init; xml_attr_class = seed_create_class(&xml_attr_class_def); xml_xpath_class_def.class_name = "XMLXPathContext"; xml_xpath_class_def.finalize = seed_xml_xpath_finalize; xml_xpath_class_def.static_functions = xpath_funcs; xml_xpath_class = seed_create_class(&xml_xpath_class_def); xml_xpathobj_class_def.class_name = "XMLXPathObj"; xml_xpathobj_class_def.finalize = seed_xml_xpathobj_finalize; xml_xpathobj_class_def.static_values = xpathobj_values; xml_xpathobj_class = seed_create_class(&xml_xpathobj_class_def); seed_create_function(eng->context, "parseFile", (SeedFunctionCallback) seed_xml_parse_file, namespace_ref); seed_create_function(eng->context, "parseString", (SeedFunctionCallback) seed_xml_parse_string, namespace_ref); node_proto = seed_object_get_prototype( eng->context, seed_make_object(eng->context, xml_node_class, NULL)); seed_make_object(eng->context, xml_node_class, NULL); seed_object_set_property(eng->context, namespace_ref, "_nodeProto", node_proto); seed_simple_evaluate(eng->context, "imports.extensions.xml", NULL); } SeedObject seed_module_init(SeedEngine* local_eng) { eng = local_eng; namespace_ref = seed_make_object(eng->context, NULL, NULL); seed_value_protect(eng->context, namespace_ref); seed_libxml_define_stuff(); return namespace_ref; } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/libxml/xml.js000066400000000000000000000007151303774616400227260ustar00rootroot00000000000000xml = imports.libxml; xml._nodeProto.getElementsByTagName = function(name){ ret = []; child = this.children; while (child){ if (child.name == name) ret.push (child); child = child.next; } return ret; } xml._nodeProto.getAttribute = function(name){ properties = this.properties; while (properties){ if (properties.name == name) return properties.children.content; properties = properties.next } return null; } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/mpfr/000077500000000000000000000000001303774616400212425ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/mpfr/Makefile.am000066400000000000000000000011531303774616400232760ustar00rootroot00000000000000if BUILD_MPFR_MODULE seedlibdir = ${libdir}/seed@SEED_GTK_VERSION@ seedlib_LTLIBRARIES = \ libseed_mpfr.la libseed_mpfr_la_SOURCES = \ seed-mpfr.c \ seed-mpfr-trig.c \ seed-mpfr-arithmetic.c \ seed-mpfr-cmp.c AM_CPPFLAGS = \ -I@top_srcdir@/libseed/ \ $(GOBJECT_INTROSPECTION_CFLAGS) \ $(SEED_DEBUG_CFLAGS) \ $(SEED_PROFILE_CFLAGS) libseed_mpfr_la_LDFLAGS = \ -module -avoid-version \ $(GOBJECT_INTROSPECTION_LDFLAGS) libseed_mpfr_la_LIBADD = -lmpfr -lgmp \ $(top_builddir)/libseed/libseed@SEED_GTK_VERSION@.la \ $(SEED_PROFILE_LIBS) EXTRA_DIST = seed-mpfr.h endif -include $(top_srcdir)/git.mk seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/mpfr/seed-mpfr-arithmetic.c000066400000000000000000001015471303774616400254270ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Matthew Arsenault 2009-2010 */ #include #include "seed-mpfr.h" /* This is a bit disgusting. Oh well. */ SeedValue seed_mpfr_add(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op1, op2; gdouble dop1, dop2; gint ret; seed_mpfr_t argt1, argt2; /* only want 1 double argument. alternatively, could accept 2, add those, and set from the result*/ CHECK_ARG_COUNT("mpfr.add", 3); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[2], exception); argt1 = seed_mpfr_arg_type(ctx, args[0], exception); argt2 = seed_mpfr_arg_type(ctx, args[1], exception); if ((argt1 & argt2) == SEED_MPFR_MPFR) { /* both mpfr_t */ op1 = seed_object_get_private(args[0]); op2 = seed_object_get_private(args[1]); ret = mpfr_add(rop, op1, op2, rnd); } else if ((argt1 | argt2) == (SEED_MPFR_MPFR | SEED_MPFR_DOUBLE)) { /* a double and an mpfr_t. Figure out the order */ if (argt1 == SEED_MPFR_MPFR) { op1 = seed_object_get_private(args[0]); dop2 = seed_value_to_double(ctx, args[1], exception); ret = mpfr_add_d(rop, op1, dop2, rnd); } else { dop2 = seed_value_to_double(ctx, args[0], exception); op1 = seed_object_get_private(args[1]); ret = mpfr_add_d(rop, op1, dop2, rnd); } } else if ((argt1 & argt2) == SEED_MPFR_DOUBLE) { /* 2 doubles. hopefully doesn't happen */ dop1 = seed_value_to_double(ctx, args[0], exception); dop2 = seed_value_to_double(ctx, args[1], exception); ret = mpfr_set_d(rop, dop1 + dop2, rnd); } else { TYPE_EXCEPTION("mpfr.add", "double or mpfr_t"); } return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_sub(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op1, op2; gdouble dop1, dop2; gint ret; seed_mpfr_t argt1, argt2; /* only want 1 double argument. alternatively, could accept 2, add those, and set from the result*/ CHECK_ARG_COUNT("mpfr.sub", 3); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[2], exception); argt1 = seed_mpfr_arg_type(ctx, args[0], exception); argt2 = seed_mpfr_arg_type(ctx, args[1], exception); if ((argt1 & argt2) == SEED_MPFR_MPFR) { /* both mpfr_t */ op1 = seed_object_get_private(args[0]); op2 = seed_object_get_private(args[1]); ret = mpfr_sub(rop, op1, op2, rnd); } else if ((argt1 | argt2) == (SEED_MPFR_MPFR | SEED_MPFR_DOUBLE)) { /* a double and an mpfr_t. Figure out the order */ if (argt1 == SEED_MPFR_MPFR) { op1 = seed_object_get_private(args[0]); dop2 = seed_value_to_double(ctx, args[1], exception); ret = mpfr_sub_d(rop, op1, dop2, rnd); } else { dop1 = seed_value_to_double(ctx, args[0], exception); op2 = seed_object_get_private(args[1]); ret = mpfr_d_sub(rop, dop1, op2, rnd); } } else if ((argt1 & argt2) == SEED_MPFR_DOUBLE) { /* 2 doubles. hopefully doesn't happen */ dop1 = seed_value_to_double(ctx, args[0], exception); dop2 = seed_value_to_double(ctx, args[1], exception); ret = mpfr_set_d(rop, dop1 - dop2, rnd); } else { TYPE_EXCEPTION("mpfr.sub", "double or mpfr_t"); } return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_mul(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op1, op2; gdouble dop1, dop2; gint ret; seed_mpfr_t argt1, argt2; /* only want 1 double argument. alternatively, could accept 2, add those, and set from the result*/ CHECK_ARG_COUNT("mpfr.mul", 3); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[2], exception); argt1 = seed_mpfr_arg_type(ctx, args[0], exception); argt2 = seed_mpfr_arg_type(ctx, args[1], exception); if ((argt1 & argt2) == SEED_MPFR_MPFR) { /* both mpfr_t */ op1 = seed_object_get_private(args[0]); op2 = seed_object_get_private(args[1]); ret = mpfr_mul(rop, op1, op2, rnd); } else if ((argt1 | argt2) == (SEED_MPFR_MPFR | SEED_MPFR_DOUBLE)) { /* a double and an mpfr_t. Figure out the order */ if (argt1 == SEED_MPFR_MPFR) { op1 = seed_object_get_private(args[0]); dop2 = seed_value_to_double(ctx, args[1], exception); ret = mpfr_mul_d(rop, op1, dop2, rnd); } else { dop2 = seed_value_to_double(ctx, args[0], exception); op1 = seed_object_get_private(args[1]); ret = mpfr_mul_d(rop, op1, dop2, rnd); } } else if ((argt1 & argt2) == SEED_MPFR_DOUBLE) { /* 2 doubles. hopefully doesn't happen */ dop1 = seed_value_to_double(ctx, args[0], exception); dop2 = seed_value_to_double(ctx, args[1], exception); ret = mpfr_set_d(rop, dop1 * dop2, rnd); } else { TYPE_EXCEPTION("mpfr.mul", "double or mpfr_t"); } return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_div(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op1, op2; gdouble dop1, dop2; gint ret; seed_mpfr_t argt1, argt2; /* only want 1 double argument. alternatively, could accept 2, add those, and set from the result*/ CHECK_ARG_COUNT("mpfr.div", 3); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[2], exception); argt1 = seed_mpfr_arg_type(ctx, args[0], exception); argt2 = seed_mpfr_arg_type(ctx, args[1], exception); if ((argt1 & argt2) == SEED_MPFR_MPFR) { /* both mpfr_t */ op1 = seed_object_get_private(args[0]); op2 = seed_object_get_private(args[1]); ret = mpfr_div(rop, op1, op2, rnd); } else if ((argt1 | argt2) == (SEED_MPFR_MPFR | SEED_MPFR_DOUBLE)) { /* a double and an mpfr_t. Figure out the order */ if (argt1 == SEED_MPFR_MPFR) { op1 = seed_object_get_private(args[0]); dop2 = seed_value_to_double(ctx, args[1], exception); ret = mpfr_div_d(rop, op1, dop2, rnd); } else { dop1 = seed_value_to_double(ctx, args[0], exception); op2 = seed_object_get_private(args[1]); ret = mpfr_d_div(rop, dop1, op2, rnd); } } else if ((argt1 & argt2) == SEED_MPFR_DOUBLE) { /* 2 doubles. hopefully doesn't happen */ dop1 = seed_value_to_double(ctx, args[0], exception); dop2 = seed_value_to_double(ctx, args[1], exception); ret = mpfr_set_d(rop, dop1 / dop2, rnd); } else { TYPE_EXCEPTION("mpfr.div", "double or mpfr_t"); } return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_pow(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op1, op2; gint ret; glong iop; gulong uiop1, uiop2; seed_mpfr_t argt1, argt2; /* only want 1 double argument. alternatively, could accept 2, add those, and set from the result*/ CHECK_ARG_COUNT("mpfr.pow", 3); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[2], exception); argt1 = seed_mpfr_arg_type(ctx, args[0], exception); argt2 = seed_mpfr_arg_type(ctx, args[1], exception); if ((argt1 & argt2) == SEED_MPFR_MPFR) { /* both mpfr_t */ op1 = seed_object_get_private(args[0]); op2 = seed_object_get_private(args[1]); ret = mpfr_pow(rop, op1, op2, rnd); } else if ((argt1 | argt2) == (SEED_MPFR_MPFR | SEED_MPFR_DOUBLE)) { /* a double and an mpfr_t. Figure out the order */ /* FIXME: is this switching ui and si bad? si_pow doesn't exist, and it's all from double anyway */ if (argt1 == SEED_MPFR_MPFR) { op1 = seed_object_get_private(args[0]); iop = seed_value_to_long(ctx, args[1], exception); ret = mpfr_pow_si(rop, op1, iop, rnd); } else { uiop1 = seed_value_to_ulong(ctx, args[0], exception); op2 = seed_object_get_private(args[1]); ret = mpfr_ui_pow(rop, uiop1, op2, rnd); } } else if ((argt1 & argt2) == SEED_MPFR_DOUBLE) { /* pretend both ui */ uiop1 = seed_value_to_ulong(ctx, args[0], exception); uiop2 = seed_value_to_ulong(ctx, args[1], exception); ret = mpfr_ui_pow_ui(rop, uiop1, uiop2, rnd); } else { TYPE_EXCEPTION("mpfr.pow", "int or unsigned int and mpfr_t"); } return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_sqrt(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.sqrt", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.sqrt", "mpfr_t"); } ret = mpfr_sqrt(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_rec_sqrt(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.rec_sqrt", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.rec_sqrt", "mpfr_t"); } ret = mpfr_rec_sqrt(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_sqr(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.sqr", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.sqr", "mpfr_t"); } ret = mpfr_sqr(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_root(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; gulong k; CHECK_ARG_COUNT("mpfr.root", 3); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[2], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.root", "mpfr_t"); } if (seed_value_is_number(ctx, args[1])) { k = seed_value_to_ulong(ctx, args[1], exception); } else { TYPE_EXCEPTION("mpfr.root", "unsigned long int"); } ret = mpfr_root(rop, op, k, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_cbrt(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.cbrt", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.cbrt", "mpfr_t"); } ret = mpfr_cbrt(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_neg(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.neg", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.neg", "mpfr_t"); } ret = mpfr_neg(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_abs(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.abs", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.abs", "mpfr_t"); } ret = mpfr_abs(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_dim(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op1, op2; gint ret; CHECK_ARG_COUNT("mpfr.dim", 3); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[2], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class) && seed_value_is_object_of_class(ctx, args[1], mpfr_class)) { op1 = seed_object_get_private(args[0]); op2 = seed_object_get_private(args[1]); } else { TYPE_EXCEPTION("mpfr.dim", "mpfr_t"); } ret = mpfr_dim(rop, op1, op2, rnd); return seed_value_from_int(ctx, ret, exception); } /* Rounding functions */ SeedValue seed_mpfr_rint(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.rint", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.rint", "mpfr_t"); } ret = mpfr_rint(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_ceil(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.ceil", 1); rop = seed_object_get_private(this_object); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.ceil", "mpfr_t"); } ret = mpfr_ceil(rop, op); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_floor(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.floor", 1); rop = seed_object_get_private(this_object); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.floor", "mpfr_t"); } ret = mpfr_floor(rop, op); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_round(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.round", 1); rop = seed_object_get_private(this_object); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.round", "mpfr_t"); } ret = mpfr_round(rop, op); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_trunc(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.trunc", 1); rop = seed_object_get_private(this_object); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.trunc", "mpfr_t"); } ret = mpfr_trunc(rop, op); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_rint_ceil(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.rint_ceil", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.rint_ceil", "mpfr_t"); } ret = mpfr_rint_ceil(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_rint_floor(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.rint_floor", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.rint_floor", "mpfr_t"); } ret = mpfr_rint_floor(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_rint_round(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.rint_round", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.rint_round", "mpfr_t"); } ret = mpfr_rint_round(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_rint_trunc(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.rint_trunc", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.rint_trunc", "mpfr_t"); } ret = mpfr_rint_trunc(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_frac(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.frac", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.frac", "mpfr_t"); } ret = mpfr_frac(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_integer_p(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_ptr rop; gboolean ret; CHECK_ARG_COUNT("mpfr.integer", 0); rop = seed_object_get_private(this_object); ret = mpfr_integer_p(rop); return seed_value_from_boolean(ctx, ret, exception); } SeedValue seed_mpfr_fmod(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op1, op2; gint ret; CHECK_ARG_COUNT("mpfr.fmod", 3); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[2], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class) && seed_value_is_object_of_class(ctx, args[1], mpfr_class)) { op1 = seed_object_get_private(args[0]); op2 = seed_object_get_private(args[1]); } else { TYPE_EXCEPTION("mpfr.fmod", "mpfr_t"); } ret = mpfr_fmod(rop, op1, op2, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_remainder(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op1, op2; gint ret; CHECK_ARG_COUNT("mpfr.remainder", 3); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[2], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class) && seed_value_is_object_of_class(ctx, args[1], mpfr_class)) { op1 = seed_object_get_private(args[0]); op2 = seed_object_get_private(args[1]); } else { TYPE_EXCEPTION("mpfr.remainder", "mpfr_t"); } ret = mpfr_remainder(rop, op1, op2, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_nexttoward(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_ptr rop, op; CHECK_ARG_COUNT("mpfr.nexttoward", 1); rop = seed_object_get_private(this_object); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.nexttoward", "mpfr_t"); } mpfr_nexttoward(rop, op); return seed_make_null(ctx); } SeedValue seed_mpfr_nextabove(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_ptr rop; CHECK_ARG_COUNT("mpfr.nextabove", 0); rop = seed_object_get_private(this_object); mpfr_nextabove(rop); return seed_make_null(ctx); } SeedValue seed_mpfr_nextbelow(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_ptr rop; CHECK_ARG_COUNT("mpfr.nextbelow", 0); rop = seed_object_get_private(this_object); mpfr_nextbelow(rop); return seed_make_null(ctx); } SeedValue seed_mpfr_min(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op1, op2; gint ret; CHECK_ARG_COUNT("mpfr.min", 3); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[2], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class) && seed_value_is_object_of_class(ctx, args[1], mpfr_class)) { op1 = seed_object_get_private(args[0]); op2 = seed_object_get_private(args[1]); } else { TYPE_EXCEPTION("mpfr.min", "mpfr_t"); } ret = mpfr_min(rop, op1, op2, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_max(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op1, op2; gint ret; CHECK_ARG_COUNT("mpfr.max", 3); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[2], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class) && seed_value_is_object_of_class(ctx, args[1], mpfr_class)) { op1 = seed_object_get_private(args[0]); op2 = seed_object_get_private(args[1]); } else { TYPE_EXCEPTION("mpfr.max", "mpfr_t"); } ret = mpfr_max(rop, op1, op2, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_prec_round(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mp_prec_t prec; mpfr_ptr rop; gint ret; CHECK_ARG_COUNT("mpfr.prec_round", 2); rop = seed_object_get_private(this_object); prec = seed_value_to_mpfr_prec_t(ctx, args[0], exception); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); ret = mpfr_prec_round(rop, prec, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_signbit(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_ptr rop; gboolean ret; CHECK_ARG_COUNT("mpfr.signbit", 0); rop = seed_object_get_private(this_object); ret = mpfr_signbit(rop); return seed_value_from_boolean(ctx, ret, exception); } SeedValue seed_mpfr_setsign(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_ptr rop, op; gint ret; gint s; mpfr_rnd_t rnd; CHECK_ARG_COUNT("mpfr.signbit", 3); rop = seed_object_get_private(this_object); s = seed_value_to_int(ctx, args[1], exception); rnd = seed_value_to_mpfr_rnd_t(ctx, args[2], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.setsign", "mpfr_t"); } ret = mpfr_setsign(rop, op, s, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_copysign(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op1, op2; gint ret; CHECK_ARG_COUNT("mpfr.copysign", 3); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[2], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class) && seed_value_is_object_of_class(ctx, args[1], mpfr_class)) { op1 = seed_object_get_private(args[0]); op2 = seed_object_get_private(args[1]); } else { TYPE_EXCEPTION("mpfr.copysign", "mpfr_t"); } ret = mpfr_copysign(rop, op1, op2, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_mul_2si(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; gulong k; CHECK_ARG_COUNT("mpfr.mul_2si", 3); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[2], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.mul_2si", "mpfr_t"); } if (seed_value_is_number(ctx, args[1])) { k = seed_value_to_ulong(ctx, args[1], exception); } else { TYPE_EXCEPTION("mpfr.mul_2si", "long int"); } ret = mpfr_mul_2si(rop, op, k, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_div_2si(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; gulong k; CHECK_ARG_COUNT("mpfr.div_2si", 3); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[2], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.div_2si", "mpfr_t"); } if (seed_value_is_number(ctx, args[1])) { k = seed_value_to_ulong(ctx, args[1], exception); } else { TYPE_EXCEPTION("mpfr.div_2si", "long int"); } ret = mpfr_div_2si(rop, op, k, rnd); return seed_value_from_int(ctx, ret, exception); } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/mpfr/seed-mpfr-cmp.c000066400000000000000000000242231303774616400240500ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Matthew Arsenault 2009-2010 */ #include #include "seed-mpfr.h" SeedValue seed_mpfr_cmp(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_ptr rop, op; gdouble dop; gint ret; CHECK_ARG_COUNT("mpfr.cmp", 1); rop = seed_object_get_private(this_object); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); ret = mpfr_cmp(rop, op); } else if (seed_value_is_number(ctx, args[0])) { dop = seed_value_to_double(ctx, args[0], exception); ret = mpfr_cmp_d(rop, dop); } else { TYPE_EXCEPTION("mpfr.cmp", "mpfr_t or double"); } return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_cmpabs(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.cmpabs", 1); rop = seed_object_get_private(this_object); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.cmpabs", "mpfr_t"); } ret = mpfr_cmpabs(rop, op); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_nan_p(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_ptr rop; gboolean ret; CHECK_ARG_COUNT("mpfr.nan_p", 0); rop = seed_object_get_private(this_object); ret = mpfr_nan_p(rop); return seed_value_from_boolean(ctx, ret, exception); } SeedValue seed_mpfr_inf_p(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_ptr rop; gboolean ret; CHECK_ARG_COUNT("mpfr.inf_p", 0); rop = seed_object_get_private(this_object); ret = mpfr_inf_p(rop); return seed_value_from_boolean(ctx, ret, exception); } SeedValue seed_mpfr_number_p(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_ptr rop; gboolean ret; CHECK_ARG_COUNT("mpfr.number_p", 0); rop = seed_object_get_private(this_object); ret = mpfr_number_p(rop); return seed_value_from_boolean(ctx, ret, exception); } SeedValue seed_mpfr_zero_p(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_ptr rop; gboolean ret; CHECK_ARG_COUNT("mpfr.zero_p", 0); rop = seed_object_get_private(this_object); ret = mpfr_zero_p(rop); return seed_value_from_boolean(ctx, ret, exception); } SeedValue seed_mpfr_sgn(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_ptr rop; gint ret; CHECK_ARG_COUNT("mpfr.sgn", 0); rop = seed_object_get_private(this_object); ret = mpfr_sgn(rop); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_greater_p(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_ptr rop, op; gboolean ret; CHECK_ARG_COUNT("mpfr.greater_p", 1); rop = seed_object_get_private(this_object); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.greater_p", "mpfr_t"); } ret = mpfr_greater_p(rop, op); return seed_value_from_boolean(ctx, ret, exception); } SeedValue seed_mpfr_greaterequal_p(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_ptr rop, op; gboolean ret; CHECK_ARG_COUNT("mpfr.greaterequal_p", 1); rop = seed_object_get_private(this_object); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.greaterequal_p", "mpfr_t"); } ret = mpfr_greaterequal_p(rop, op); return seed_value_from_boolean(ctx, ret, exception); } SeedValue seed_mpfr_less_p(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_ptr rop, op; gboolean ret; CHECK_ARG_COUNT("mpfr.less_p", 1); rop = seed_object_get_private(this_object); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.less_p", "mpfr_t"); } ret = mpfr_less_p(rop, op); return seed_value_from_boolean(ctx, ret, exception); } SeedValue seed_mpfr_lessequal_p(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_ptr rop, op; gboolean ret; CHECK_ARG_COUNT("mpfr.less_equal_p", 1); rop = seed_object_get_private(this_object); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.less_equal_p", "mpfr_t"); } ret = mpfr_lessequal_p(rop, op); return seed_value_from_boolean(ctx, ret, exception); } SeedValue seed_mpfr_lessgreater_p(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_ptr rop, op; gboolean ret; CHECK_ARG_COUNT("mpfr.lessgreater_p", 1); rop = seed_object_get_private(this_object); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.lessgreater_p", "mpfr_t"); } ret = mpfr_lessgreater_p(rop, op); return seed_value_from_boolean(ctx, ret, exception); } SeedValue seed_mpfr_equal_p(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_ptr rop, op; gboolean ret; CHECK_ARG_COUNT("mpfr.equal_p", 1); rop = seed_object_get_private(this_object); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.equal_p", "mpfr_t"); } ret = mpfr_equal_p(rop, op); return seed_value_from_boolean(ctx, ret, exception); } SeedValue seed_mpfr_unordered_p(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_ptr rop, op; gboolean ret; CHECK_ARG_COUNT("mpfr.unordered_p", 1); rop = seed_object_get_private(this_object); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.unordered_p", "mpfr_t"); } ret = mpfr_unordered_p(rop, op); return seed_value_from_boolean(ctx, ret, exception); } SeedValue seed_mpfr_cmp_si_2exp(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_ptr op1; gulong op2; mp_exp_t exp; gint ret; CHECK_ARG_COUNT("mpfr.cmp_si_2exp", 2); op1 = seed_object_get_private(this_object); if (seed_value_is_number(ctx, args[0])) { op2 = seed_value_to_ulong(ctx, args[0], exception); } else { TYPE_EXCEPTION("mpfr.cmp_si_2exp", "long int"); } if (seed_value_is_number(ctx, args[1])) { exp = seed_value_to_mp_exp_t(ctx, args[1], exception); } else { TYPE_EXCEPTION("mpfr.cmp_si_2exp", "mp_exp_t"); } ret = mpfr_cmp_si_2exp(op1, op2, exp); return seed_value_from_int(ctx, ret, exception); } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/mpfr/seed-mpfr-trig.c000066400000000000000000000741201303774616400242370ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Matthew Arsenault 2009-2010 */ #include #include "seed-mpfr.h" SeedValue seed_mpfr_sin(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.sin", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.sin", "mpfr_t"); } ret = mpfr_sin(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_cos(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.cos", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.cos", "mpfr_t"); } ret = mpfr_cos(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_tan(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.tan", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.tan", "mpfr_t"); } ret = mpfr_tan(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_csc(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.csc", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.csc", "mpfr_t"); } ret = mpfr_csc(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_sec(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.sec", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.sec", "mpfr_t"); } ret = mpfr_sec(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_cot(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.cot", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.cot", "mpfr_t"); } ret = mpfr_cot(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_asin(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.asin", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.asin", "mpfr_t"); } ret = mpfr_asin(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_acos(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.acos", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.acos", "mpfr_t"); } ret = mpfr_acos(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_atan(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.atan", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.atan", "mpfr_t"); } ret = mpfr_atan(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } /* log functions */ SeedValue seed_mpfr_log(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.log", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.log", "mpfr_t"); } ret = mpfr_log(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_log2(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.log2", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.log2", "mpfr_t"); } ret = mpfr_log2(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_log10(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.log10", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.log10", "mpfr_t"); } ret = mpfr_log10(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } /* hyperbolic trig functions */ SeedValue seed_mpfr_sinh(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.sinh", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.sinh", "mpfr_t"); } ret = mpfr_sinh(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_cosh(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.cosh", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.cosh", "mpfr_t"); } ret = mpfr_cosh(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_tanh(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.tanh", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.tanh", "mpfr_t"); } ret = mpfr_tanh(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_sech(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.sech", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.sech", "mpfr_t"); } ret = mpfr_sech(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_csch(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.csch", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.csch", "mpfr_t"); } ret = mpfr_csch(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_coth(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.coth", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.coth", "mpfr_t"); } ret = mpfr_coth(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } /* inverse hyperbolic trig */ SeedValue seed_mpfr_asinh(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.asinh", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.asinh", "mpfr_t"); } ret = mpfr_asinh(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_acosh(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.acosh", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.acosh", "mpfr_t"); } ret = mpfr_acosh(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_atanh(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.atanh", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.atanh", "mpfr_t"); } ret = mpfr_atanh(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_log1p(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.log1p", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.log1p", "mpfr_t"); } ret = mpfr_log1p(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_expm1(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.expm1", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.expm1", "mpfr_t"); } ret = mpfr_expm1(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_li2(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.li2", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.li2", "mpfr_t"); } ret = mpfr_li2(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_gamma(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.gamma", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.gamma", "mpfr_t"); } ret = mpfr_gamma(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_lngamma(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.lngamma", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.lngamma", "mpfr_t"); } ret = mpfr_lngamma(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_zeta(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; gulong uiop; CHECK_ARG_COUNT("mpfr.zeta", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); ret = mpfr_zeta(rop, op, rnd); } else if (seed_value_is_number(ctx, args[0])) { uiop = seed_value_to_ulong(ctx, args[0], exception); ret = mpfr_zeta_ui(rop, uiop, rnd); } else { TYPE_EXCEPTION("mpfr.zeta", "mpfr_t or unsigned int"); } return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_erf(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.erf", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.erf", "mpfr_t"); } ret = mpfr_erf(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_erfc(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.erfc", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.erfc", "mpfr_t"); } ret = mpfr_erfc(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } /* bessel functions */ SeedValue seed_mpfr_j0(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.j0", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.j0", "mpfr_t"); } ret = mpfr_j0(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_j1(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.j1", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.j1", "mpfr_t"); } ret = mpfr_j1(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_jn(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret, n; CHECK_ARG_COUNT("mpfr.jn", 3); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[2], exception); if (seed_value_is_object_of_class(ctx, args[1], mpfr_class)) { op = seed_object_get_private(args[1]); } else { TYPE_EXCEPTION("mpfr.jn", "mpfr_t"); } if (seed_value_is_number(ctx, args[0])) { n = seed_value_to_int(ctx, args[0], exception); } else { TYPE_EXCEPTION("mpfr.jn", "int"); } ret = mpfr_jn(rop, n, op, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_y0(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.y0", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.y0", "mpfr_t"); } ret = mpfr_y0(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_y1(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.y1", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.y1", "mpfr_t"); } ret = mpfr_y1(rop, op, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_yn(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gint ret, n; CHECK_ARG_COUNT("mpfr.yn", 3); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[2], exception); if (seed_value_is_object_of_class(ctx, args[1], mpfr_class)) { op = seed_object_get_private(args[1]); } else { TYPE_EXCEPTION("mpfr.yn", "mpfr_t"); } if (seed_value_is_number(ctx, args[0])) { n = seed_value_to_int(ctx, args[0], exception); } else { TYPE_EXCEPTION("mpfr.yn", "int"); } ret = mpfr_yn(rop, n, op, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_fma(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op1, op2, op3; gint ret; CHECK_ARG_COUNT("mpfr.fma", 4); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[3], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class) && seed_value_is_object_of_class(ctx, args[1], mpfr_class) && seed_value_is_object_of_class(ctx, args[2], mpfr_class)) { op1 = seed_object_get_private(args[0]); op2 = seed_object_get_private(args[1]); op3 = seed_object_get_private(args[2]); } else { TYPE_EXCEPTION("mpfr.fma", "mpfr_t"); } ret = mpfr_fma(rop, op1, op2, op3, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_fms(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op1, op2, op3; gint ret; CHECK_ARG_COUNT("mpfr.fms", 4); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[3], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class) && seed_value_is_object_of_class(ctx, args[1], mpfr_class) && seed_value_is_object_of_class(ctx, args[2], mpfr_class)) { op1 = seed_object_get_private(args[0]); op2 = seed_object_get_private(args[1]); op3 = seed_object_get_private(args[2]); } else { TYPE_EXCEPTION("mpfr.fms", "mpfr_t"); } ret = mpfr_fms(rop, op1, op2, op3, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_agm(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op1, op2; gint ret; CHECK_ARG_COUNT("mpfr.agm", 3); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[2], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class) && seed_value_is_object_of_class(ctx, args[1], mpfr_class)) { op1 = seed_object_get_private(args[0]); op2 = seed_object_get_private(args[1]); } else { TYPE_EXCEPTION("mpfr.agm", "mpfr_t"); } ret = mpfr_agm(rop, op1, op2, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_hypot(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op1, op2; gint ret; CHECK_ARG_COUNT("mpfr.hypot", 3); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[2], exception); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class) && seed_value_is_object_of_class(ctx, args[1], mpfr_class)) { op1 = seed_object_get_private(args[0]); op2 = seed_object_get_private(args[1]); } else { TYPE_EXCEPTION("mpfr.hypot", "mpfr_t"); } ret = mpfr_hypot(rop, op1, op2, rnd); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_free_cache(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { CHECK_ARG_COUNT("mpfr.free_cache", 0); mpfr_free_cache(); return seed_make_null(ctx); } SeedValue seed_mpfr_clear_flags(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { CHECK_ARG_COUNT("mpfr.clear_flags", 0); mpfr_clear_flags(); return seed_make_null(ctx); } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/mpfr/seed-mpfr.c000066400000000000000000001100011303774616400232610ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Matthew Arsenault 2009-2010 */ #include #include #include #include "seed-mpfr.h" SeedObject ns_ref; SeedClass mpfr_class; /* For now at least ignoring the ability to use gmp types since there is no gmp * module */ SeedEngine* eng; seed_mpfr_t seed_mpfr_arg_type(SeedContext ctx, SeedValue arg, SeedException exept) { if (seed_value_is_object_of_class(ctx, arg, mpfr_class)) return SEED_MPFR_MPFR; else if (seed_value_is_number(ctx, arg)) return SEED_MPFR_DOUBLE; else if (seed_value_is_string(ctx, arg)) return SEED_MPFR_STRING; else return SEED_MPFR_UNKNOWN; } static SeedValue seed_mpfr_out_str(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { gsize n; FILE* stream; gint base; mpfr_rnd_t rnd; mpfr_ptr op; CHECK_ARG_COUNT("mpfr.out_str", 4); stream = (FILE*) seed_pointer_get_pointer(ctx, args[0]); base = seed_value_to_int(ctx, args[1], exception); n = seed_value_to_uint(ctx, args[2], exception); op = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[3], exception); return seed_value_from_uint(ctx, mpfr_out_str(stream, base, n, op, rnd), exception); } /* no way to do real printf with varargs yet, this is a way to get fake printf */ static SeedValue seed_mpfr_print(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_ptr op; mpfr_rnd_t rnd; unsigned int width, sigdigits; gint ret; CHECK_ARG_COUNT("mpfr.print", 3); op = seed_object_get_private(this_object); width = seed_value_to_uint(ctx, args[0], exception); sigdigits = seed_value_to_uint(ctx, args[1], exception); rnd = seed_value_to_mpfr_rnd_t(ctx, args[2], exception); ret = mpfr_printf("%*.*R*g", width, sigdigits, rnd, op); return seed_value_from_int(ctx, ret, exception); } static SeedValue seed_mpfr_const_pi(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop; gint ret; CHECK_ARG_COUNT("mpfr.pi", 1); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[0], exception); ret = mpfr_const_pi(rop, rnd); return seed_value_from_int(ctx, ret, exception); } static SeedValue seed_mpfr_const_euler(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop; gint ret; CHECK_ARG_COUNT("mpfr.euler", 1); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[0], exception); ret = mpfr_const_euler(rop, rnd); return seed_value_from_int(ctx, ret, exception); } static SeedValue seed_mpfr_const_catalan(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop; gint ret; CHECK_ARG_COUNT("mpfr.catalan", 1); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[0], exception); ret = mpfr_const_catalan(rop, rnd); return seed_value_from_int(ctx, ret, exception); } static SeedValue seed_mpfr_get_d(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop; gdouble ret; CHECK_ARG_COUNT("mpfr.get_d", 1); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[0], exception); ret = mpfr_get_d(rop, rnd); return seed_value_from_double(ctx, ret, exception); } static SeedValue seed_mpfr_fits_ulong_p(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop; gboolean ret; CHECK_ARG_COUNT("mpfr.fits_ulong_p", 1); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[0], exception); ret = mpfr_fits_ulong_p(rop, rnd); return seed_value_from_boolean(ctx, ret, exception); } static SeedValue seed_mpfr_fits_slong_p(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop; gboolean ret; CHECK_ARG_COUNT("mpfr.fits_slong_p", 1); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[0], exception); ret = mpfr_fits_slong_p(rop, rnd); return seed_value_from_boolean(ctx, ret, exception); } static SeedValue seed_mpfr_fits_uint_p(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop; gboolean ret; CHECK_ARG_COUNT("mpfr.fits_uint_p", 1); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[0], exception); ret = mpfr_fits_uint_p(rop, rnd); return seed_value_from_boolean(ctx, ret, exception); } static SeedValue seed_mpfr_fits_sint_p(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop; gboolean ret; CHECK_ARG_COUNT("mpfr.fits_sint_p", 1); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[0], exception); ret = mpfr_fits_sint_p(rop, rnd); return seed_value_from_boolean(ctx, ret, exception); } static SeedValue seed_mpfr_fits_ushort_p(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop; gboolean ret; CHECK_ARG_COUNT("mpfr.fits_ushort_p", 1); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[0], exception); ret = mpfr_fits_ushort_p(rop, rnd); return seed_value_from_boolean(ctx, ret, exception); } static SeedValue seed_mpfr_fits_sshort_p(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop; gboolean ret; CHECK_ARG_COUNT("mpfr.fits_sshort_p", 1); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[0], exception); ret = mpfr_fits_sshort_p(rop, rnd); return seed_value_from_boolean(ctx, ret, exception); } static SeedValue seed_mpfr_fits_intmax_p(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop; gboolean ret; CHECK_ARG_COUNT("mpfr.fits_intmax_p", 1); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[0], exception); ret = mpfr_fits_intmax_p(rop, rnd); return seed_value_from_boolean(ctx, ret, exception); } static SeedValue seed_mpfr_fits_uintmax_p(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop; gboolean ret; CHECK_ARG_COUNT("mpfr.fits_uintmax_p", 1); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[0], exception); ret = mpfr_fits_uintmax_p(rop, rnd); return seed_value_from_boolean(ctx, ret, exception); } static SeedValue seed_mpfr_get_exp(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedException* exception) { mpfr_ptr ptr = seed_object_get_private(this_object); return seed_value_from_mp_exp_t(ctx, mpfr_get_exp(ptr), exception); } static gboolean seed_mpfr_set_exp(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedValue value, SeedException* exception) { mpfr_ptr ptr = seed_object_get_private(this_object); mpfr_set_exp(ptr, seed_value_to_mp_exp_t(ctx, value, exception)); return TRUE; } static gboolean seed_mpfr_set_default_rounding_mode(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedValue value, SeedException* exception) { mpfr_set_default_rounding_mode( seed_value_to_mpfr_rnd_t(ctx, value, exception)); return TRUE; } static SeedValue seed_mpfr_get_default_rounding_mode(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedException* exception) { return seed_value_from_mpfr_rnd_t(ctx, mpfr_get_default_rounding_mode(), exception); } static SeedValue seed_mpfr_get_prec(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedException* exception) { mpfr_ptr ptr = seed_object_get_private(this_object); return seed_value_from_mpfr_prec_t(ctx, mpfr_get_prec(ptr), exception); } static gboolean seed_mpfr_set_prec(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedValue value, SeedException* exception) { mpfr_ptr ptr = seed_object_get_private(this_object); mpfr_set_prec(ptr, seed_value_to_mpfr_prec_t(ctx, value, exception)); return TRUE; } static void seed_mpfr_finalize(SeedObject obj) { mpfr_ptr ptr = seed_object_get_private(obj); if (ptr) { mpfr_clear(ptr); g_free(ptr); } } static SeedValue seed_mpfr_set(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op; gdouble dop; gint ret; gchar* str; seed_mpfr_t argt; CHECK_ARG_COUNT("mpfr.set", 2); rop = seed_object_get_private(this_object); argt = seed_mpfr_arg_type(ctx, args[0], exception); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); switch (argt) { case SEED_MPFR_MPFR: op = seed_object_get_private(args[0]); ret = mpfr_set(rop, op, rnd); break; case SEED_MPFR_DOUBLE: dop = seed_value_to_double(ctx, args[0], exception); ret = mpfr_set_d(rop, dop, rnd); break; case SEED_MPFR_STRING: str = seed_value_to_string(ctx, args[0], exception); ret = mpfr_set_str(rop, str, 10, rnd); g_free(str); break; default: TYPE_EXCEPTION("mpfr.set", "mpfr_t, double or string"); } return seed_value_from_int(ctx, ret, exception); } SeedValue seed_mpfr_set_inf(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_ptr rop; gint sign; CHECK_ARG_COUNT("mpfr.set_inf", 1); rop = seed_object_get_private(this_object); if (seed_value_is_number(ctx, args[0])) { sign = seed_value_to_int(ctx, args[0], exception); } else { TYPE_EXCEPTION("mpfr.set_inf", "int"); } mpfr_set_inf(rop, sign); return seed_make_null(ctx); } SeedValue seed_mpfr_set_nan(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_ptr rop; CHECK_ARG_COUNT("mpfr.set_nan", 0); rop = seed_object_get_private(this_object); mpfr_set_nan(rop); return seed_make_null(ctx); } SeedValue seed_mpfr_swap(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_ptr rop, op; CHECK_ARG_COUNT("mpfr.swap", 1); rop = seed_object_get_private(this_object); if (seed_value_is_object_of_class(ctx, args[0], mpfr_class)) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.swap", "mpfr_t"); } mpfr_swap(rop, op); return seed_make_null(ctx); } SeedValue seed_mpfr_can_round(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd1, rnd2; mpfr_ptr rop; gboolean ret; mpfr_prec_t prec; mp_exp_t err; CHECK_ARG_COUNT("mpfr.can_round", 4); rop = seed_object_get_private(this_object); err = seed_value_to_mp_exp_t(ctx, args[0], exception); rnd1 = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); rnd2 = seed_value_to_mpfr_rnd_t(ctx, args[2], exception); prec = seed_value_to_mpfr_prec_t(ctx, args[3], exception); ret = mpfr_can_round(rop, err, rnd1, rnd2, prec); return seed_value_from_boolean(ctx, ret, exception); } /* init and set functions, using default precision, or optionally specifying it */ SeedObject seed_mpfr_construct_with_set(SeedContext ctx, SeedObject constructor, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_prec_t prec; mpfr_rnd_t rnd; mpfr_ptr newmp, op; gdouble dbl; gchar* str; SeedObject obj; seed_mpfr_t argt; /* TODO: Precision range check */ switch (argument_count) { case 2: prec = mpfr_get_default_prec(); break; case 3: if (seed_value_is_number(ctx, args[1])) { prec = seed_value_to_mpfr_prec_t(ctx, args[1], exception); } else { TYPE_EXCEPTION("mpfr constructor with set", "mpfr_prec_t"); } break; default: seed_make_exception( ctx, exception, "ArgumentError", "mpfr_t constructor.set expected 2 or 3 arguments got %zd", argument_count); return seed_make_undefined(ctx); } /* last argument is always rnd */ if (seed_value_is_number(ctx, args[argument_count - 1])) rnd = seed_value_to_mpfr_rnd_t(ctx, args[argument_count - 1], exception); else { TYPE_EXCEPTION("mpfr constructor", "mpfr_rnd_t"); } newmp = (mpfr_ptr) g_malloc(sizeof(mpfr_t)); mpfr_init2(newmp, prec); argt = seed_mpfr_arg_type(ctx, args[0], exception); switch (argt) { case SEED_MPFR_MPFR: obj = seed_value_to_object(ctx, args[0], exception); op = seed_object_get_private(obj); mpfr_set(newmp, op, rnd); break; case SEED_MPFR_DOUBLE: dbl = seed_value_to_double(ctx, args[0], exception); mpfr_set_d(newmp, dbl, rnd); break; case SEED_MPFR_STRING: /* TODO: Assuming base 10 is bad */ str = seed_value_to_string(ctx, args[0], exception); mpfr_set_str(newmp, str, 10, rnd); break; default: mpfr_clear(newmp); g_free(newmp); TYPE_EXCEPTION("mpfr_constructor", "mpfr_t, double or string"); } return seed_make_object(ctx, mpfr_class, newmp); } /* init, optionally specifying precision */ SeedObject seed_mpfr_construct(SeedContext ctx, SeedObject constructor, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_prec_t prec; mpfr_ptr newmp = (mpfr_ptr) g_malloc(sizeof(mpfr_t)); switch (argument_count) { case 0: mpfr_init(newmp); /* use default precision */ break; case 1: if (seed_value_is_number(ctx, args[0])) { prec = seed_value_to_mpfr_prec_t(ctx, args[0], exception); mpfr_init2(newmp, prec); } else { g_free(newmp); TYPE_EXCEPTION("mpfr constructor", "mpfr_prec_t"); } break; default: seed_make_exception( ctx, exception, "ArgumentError", "mpfr_t constructor expected 0 or 1 arguments got %zd", argument_count); return seed_make_undefined(ctx); } return seed_make_object(ctx, mpfr_class, newmp); } SeedValue seed_mpfr_get_version(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedException* exception) { const gchar* str; SeedValue ret; str = mpfr_get_version(); ret = seed_value_from_string(ctx, str, exception); return ret; } SeedValue seed_mpfr_get_patches(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedException* exception) { const gchar* str; SeedValue ret; str = mpfr_get_patches(); ret = seed_value_from_string(ctx, str, exception); return ret; } static gboolean seed_mpfr_set_emin(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedValue value, SeedException* exception) { mp_exp_t exp; gint ret; exp = seed_value_to_mp_exp_t(ctx, value, exception); ret = mpfr_set_emin(exp); return ret; } static gboolean seed_mpfr_set_emax(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedValue value, SeedException* exception) { mp_exp_t exp; gint ret; exp = seed_value_to_mp_exp_t(ctx, value, exception); ret = mpfr_set_emax(exp); return ret; } SeedValue seed_mpfr_get_emax(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedException* exception) { mp_exp_t exp; exp = mpfr_get_emax(); return seed_value_from_mp_exp_t(ctx, exp, exception); } SeedValue seed_mpfr_get_emin(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedException* exception) { mp_exp_t exp; exp = mpfr_get_emin(); return seed_value_from_mp_exp_t(ctx, exp, exception); } SeedValue seed_mpfr_get_emin_min(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedException* exception) { mp_exp_t exp; exp = mpfr_get_emin_min(); return seed_value_from_mp_exp_t(ctx, exp, exception); } SeedValue seed_mpfr_get_emin_max(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedException* exception) { mp_exp_t exp; exp = mpfr_get_emin_max(); return seed_value_from_mp_exp_t(ctx, exp, exception); } SeedValue seed_mpfr_get_emax_min(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedException* exception) { mp_exp_t exp; exp = mpfr_get_emax_min(); return seed_value_from_mp_exp_t(ctx, exp, exception); } SeedValue seed_mpfr_get_emax_max(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedException* exception) { mp_exp_t exp; exp = mpfr_get_emax_max(); return seed_value_from_mp_exp_t(ctx, exp, exception); } SeedValue seed_mpfr_underflow_p(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedException* exception) { gint ret = mpfr_underflow_p(); return seed_value_from_int(ctx, ret, exception); } gboolean seed_mpfr_set_underflow(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedValue value, SeedException* exception) { gboolean setorclear; setorclear = seed_value_to_boolean(ctx, value, exception); if (setorclear) mpfr_set_underflow(); else mpfr_clear_underflow(); return setorclear; } SeedValue seed_mpfr_overflow_p(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedException* exception) { gint ret = mpfr_overflow_p(); return seed_value_from_int(ctx, ret, exception); } gboolean seed_mpfr_set_overflow(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedValue value, SeedException* exception) { gboolean setorclear; setorclear = seed_value_to_boolean(ctx, value, exception); if (setorclear) mpfr_set_overflow(); else mpfr_clear_overflow(); return setorclear; } SeedValue seed_mpfr_nanflag_p(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedException* exception) { gint ret = mpfr_nanflag_p(); return seed_value_from_int(ctx, ret, exception); } gboolean seed_mpfr_set_nanflag(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedValue value, SeedException* exception) { gboolean setorclear; setorclear = seed_value_to_boolean(ctx, value, exception); if (setorclear) mpfr_set_nanflag(); else mpfr_clear_nanflag(); return setorclear; } SeedValue seed_mpfr_inexflag_p(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedException* exception) { gint ret = mpfr_inexflag_p(); return seed_value_from_int(ctx, ret, exception); } gboolean seed_mpfr_set_inexflag(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedValue value, SeedException* exception) { gboolean setorclear; setorclear = seed_value_to_boolean(ctx, value, exception); if (setorclear) mpfr_set_inexflag(); else mpfr_clear_inexflag(); return setorclear; } SeedValue seed_mpfr_erangeflag_p(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedException* exception) { gint ret = mpfr_erangeflag_p(); return seed_value_from_int(ctx, ret, exception); } gboolean seed_mpfr_set_erangeflag(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedValue value, SeedException* exception) { gboolean setorclear; setorclear = seed_value_to_boolean(ctx, value, exception); if (setorclear) mpfr_set_erangeflag(); else mpfr_clear_erangeflag(); return setorclear; } static SeedValue seed_mpfr_subnormalize(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop; gint ret, t; CHECK_ARG_COUNT("mpfr.subnormalize", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); t = seed_value_to_int(ctx, args[0], exception); ret = mpfr_subnormalize(rop, t, rnd); return seed_value_from_int(ctx, ret, exception); } static SeedValue seed_mpfr_check_range(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException* exception) { mpfr_rnd_t rnd; mpfr_ptr rop; gint ret, t; CHECK_ARG_COUNT("mpfr.check_range", 2); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[1], exception); t = seed_value_to_int(ctx, args[0], exception); ret = mpfr_check_range(rop, t, rnd); return seed_value_from_int(ctx, ret, exception); } seed_static_value mpfr_ns_values[] = { { "default_rounding_mode", seed_mpfr_get_default_rounding_mode, seed_mpfr_set_default_rounding_mode, SEED_PROPERTY_ATTRIBUTE_DONT_DELETE }, { "emax", seed_mpfr_get_emax, seed_mpfr_set_emax, SEED_PROPERTY_ATTRIBUTE_DONT_DELETE }, { "emin", seed_mpfr_get_emin, seed_mpfr_set_emin, SEED_PROPERTY_ATTRIBUTE_DONT_DELETE }, { "emin_min", seed_mpfr_get_emin_min, NULL, SEED_PROPERTY_ATTRIBUTE_DONT_DELETE }, { "emin_max", seed_mpfr_get_emin_max, NULL, SEED_PROPERTY_ATTRIBUTE_DONT_DELETE }, { "emax_min", seed_mpfr_get_emax_min, NULL, SEED_PROPERTY_ATTRIBUTE_DONT_DELETE }, { "emax_max", seed_mpfr_get_emax_max, NULL, SEED_PROPERTY_ATTRIBUTE_DONT_DELETE }, { "underflow", seed_mpfr_underflow_p, seed_mpfr_set_underflow, SEED_PROPERTY_ATTRIBUTE_DONT_DELETE }, { "overflow", seed_mpfr_overflow_p, seed_mpfr_set_overflow, SEED_PROPERTY_ATTRIBUTE_DONT_DELETE }, { "nanflag", seed_mpfr_nanflag_p, seed_mpfr_set_nanflag, SEED_PROPERTY_ATTRIBUTE_DONT_DELETE }, { "inexflag", seed_mpfr_inexflag_p, seed_mpfr_set_inexflag, SEED_PROPERTY_ATTRIBUTE_DONT_DELETE }, { "erangeflag", seed_mpfr_erangeflag_p, seed_mpfr_set_erangeflag, SEED_PROPERTY_ATTRIBUTE_DONT_DELETE }, { "version", seed_mpfr_get_version, NULL, SEED_PROPERTY_ATTRIBUTE_DONT_DELETE }, { "patches", seed_mpfr_get_patches, NULL, SEED_PROPERTY_ATTRIBUTE_DONT_DELETE }, { NULL, NULL, NULL, 0 } }; seed_static_function mpfr_ns_funcs[] = { { "free_cache", seed_mpfr_free_cache, 0 }, { "clear_flags", seed_mpfr_clear_flags, 0 }, { NULL, NULL, 0 } }; seed_static_function mpfr_funcs[] = { { "add", seed_mpfr_add, 0 }, { "sub", seed_mpfr_sub, 0 }, { "mul", seed_mpfr_mul, 0 }, { "div", seed_mpfr_div, 0 }, { "sqrt", seed_mpfr_sqrt, 0 }, { "sqr", seed_mpfr_sqr, 0 }, { "pow", seed_mpfr_pow, 0 }, { "mul_2si", seed_mpfr_mul_2si, 0 }, { "div_2si", seed_mpfr_div_2si, 0 }, { "root", seed_mpfr_root, 0 }, { "rec_sqrt", seed_mpfr_rec_sqrt, 0 }, { "cbrt", seed_mpfr_cbrt, 0 }, { "neg", seed_mpfr_neg, 0 }, { "abs", seed_mpfr_abs, 0 }, { "rint", seed_mpfr_rint, 0 }, { "ceil", seed_mpfr_ceil, 0 }, { "floor", seed_mpfr_floor, 0 }, { "round", seed_mpfr_round, 0 }, { "trunc", seed_mpfr_trunc, 0 }, { "prec_round", seed_mpfr_prec_round, 0 }, { "can_round", seed_mpfr_can_round, 0 }, { "signbit", seed_mpfr_signbit, 0 }, { "setsign", seed_mpfr_setsign, 0 }, { "copysign", seed_mpfr_copysign, 0 }, { "nexttoward", seed_mpfr_nexttoward, 0 }, { "nextabove", seed_mpfr_nextabove, 0 }, { "nextbelow", seed_mpfr_nextbelow, 0 }, { "rint_ceil", seed_mpfr_rint_ceil, 0 }, { "rint_floor", seed_mpfr_rint_floor, 0 }, { "rint_round", seed_mpfr_rint_round, 0 }, { "rint_trunc", seed_mpfr_rint_trunc, 0 }, { "min", seed_mpfr_min, 0 }, { "max", seed_mpfr_max, 0 }, { "frac", seed_mpfr_frac, 0 }, { "fmod", seed_mpfr_fmod, 0 }, { "remainder", seed_mpfr_remainder, 0 }, { "integer_p", seed_mpfr_integer_p, 0 }, { "dim", seed_mpfr_dim, 0 }, { "sin", seed_mpfr_sin, 0 }, { "cos", seed_mpfr_cos, 0 }, { "tan", seed_mpfr_tan, 0 }, { "asin", seed_mpfr_asin, 0 }, { "acos", seed_mpfr_acos, 0 }, { "atan", seed_mpfr_atan, 0 }, { "csc", seed_mpfr_csc, 0 }, { "sec", seed_mpfr_sec, 0 }, { "cot", seed_mpfr_cot, 0 }, { "log", seed_mpfr_log, 0 }, { "log2", seed_mpfr_log2, 0 }, { "log10", seed_mpfr_log10, 0 }, { "sinh", seed_mpfr_sinh, 0 }, { "cosh", seed_mpfr_cosh, 0 }, { "tanh", seed_mpfr_tanh, 0 }, { "csch", seed_mpfr_csch, 0 }, { "sech", seed_mpfr_sech, 0 }, { "coth", seed_mpfr_coth, 0 }, { "asinh", seed_mpfr_asinh, 0 }, { "acosh", seed_mpfr_acosh, 0 }, { "atanh", seed_mpfr_atanh, 0 }, { "log1p", seed_mpfr_log1p, 0 }, { "expm1", seed_mpfr_expm1, 0 }, { "li2", seed_mpfr_li2, 0 }, { "gamma", seed_mpfr_gamma, 0 }, { "lngamma", seed_mpfr_lngamma, 0 }, { "zeta", seed_mpfr_zeta, 0 }, { "erf", seed_mpfr_erf, 0 }, { "erfc", seed_mpfr_erfc, 0 }, { "j0", seed_mpfr_j0, 0 }, { "j1", seed_mpfr_j1, 0 }, { "jn", seed_mpfr_jn, 0 }, { "y0", seed_mpfr_y0, 0 }, { "y1", seed_mpfr_y1, 0 }, { "yn", seed_mpfr_yn, 0 }, { "fma", seed_mpfr_fma, 0 }, { "fms", seed_mpfr_fms, 0 }, { "agm", seed_mpfr_agm, 0 }, { "hypot", seed_mpfr_hypot, 0 }, { "set", seed_mpfr_set, 0 }, { "set_inf", seed_mpfr_set_inf, 0 }, { "set_nan", seed_mpfr_set_nan, 0 }, { "swap", seed_mpfr_swap, 0 }, { "cmp", seed_mpfr_cmp, 0 }, { "cmpabs", seed_mpfr_cmpabs, 0 }, { "cmp_si_2exp", seed_mpfr_cmp_si_2exp, 0 }, { "greater_p", seed_mpfr_greater_p, 0 }, { "greaterequal_p", seed_mpfr_greaterequal_p, 0 }, { "less_p", seed_mpfr_less_p, 0 }, { "lessequal_p", seed_mpfr_lessequal_p, 0 }, { "lessgreater_p", seed_mpfr_lessgreater_p, 0 }, { "equal_p", seed_mpfr_equal_p, 0 }, { "unordered_p", seed_mpfr_unordered_p, 0 }, { "nan_p", seed_mpfr_nan_p, 0 }, { "inf_p", seed_mpfr_inf_p, 0 }, { "number_p", seed_mpfr_number_p, 0 }, { "zero_p", seed_mpfr_zero_p, 0 }, { "sgn", seed_mpfr_sgn, 0 }, { "get_d", seed_mpfr_get_d, 0 }, { "fits_ulong_p", seed_mpfr_fits_ulong_p, 0 }, { "fits_slong_p", seed_mpfr_fits_slong_p, 0 }, { "fits_uint_p", seed_mpfr_fits_uint_p, 0 }, { "fits_sint_p", seed_mpfr_fits_sint_p, 0 }, { "fits_ushort_p", seed_mpfr_fits_ushort_p, 0 }, { "fits_sshort_p", seed_mpfr_fits_sshort_p, 0 }, { "fits_intmax_p", seed_mpfr_fits_intmax_p, 0 }, { "fits_uintmax_p", seed_mpfr_fits_uintmax_p, 0 }, { "out_str", seed_mpfr_out_str, 0 }, { "print", seed_mpfr_print, 0 }, { "pi", seed_mpfr_const_pi, 0 }, { "euler", seed_mpfr_const_euler, 0 }, { "catalan", seed_mpfr_const_catalan, 0 }, { "subnormalize", seed_mpfr_subnormalize, 0 }, { "check_range", seed_mpfr_check_range, 0 }, { NULL, NULL, 0 } }; seed_static_value mpfr_values[] = { { "prec", seed_mpfr_get_prec, seed_mpfr_set_prec, SEED_PROPERTY_ATTRIBUTE_DONT_DELETE }, { "exp", seed_mpfr_get_exp, seed_mpfr_set_exp, SEED_PROPERTY_ATTRIBUTE_DONT_DELETE }, { NULL, NULL, NULL, 0 } }; SeedObject seed_module_init(SeedEngine* local_eng) { SeedGlobalContext ctx = local_eng->context; seed_class_definition mpfr_def = seed_empty_class; seed_class_definition ns_ref_class_def = seed_empty_class; SeedObject mpfr_constructor, mpfr_constructor_set; SeedClass ns_class; ns_ref_class_def.static_values = mpfr_ns_values; ns_ref_class_def.static_functions = mpfr_ns_funcs; ns_class = seed_create_class(&ns_ref_class_def); ns_ref = seed_make_object(ctx, ns_class, NULL); seed_value_protect(ctx, ns_ref); mpfr_def.class_name = "mpfr_t"; mpfr_def.static_functions = mpfr_funcs; mpfr_def.finalize = seed_mpfr_finalize; mpfr_def.static_values = mpfr_values; mpfr_class = seed_create_class(&mpfr_def); mpfr_constructor = seed_make_constructor(ctx, mpfr_class, seed_mpfr_construct); mpfr_constructor_set = seed_make_constructor(ctx, mpfr_class, seed_mpfr_construct_with_set); seed_object_set_property(ctx, ns_ref, "mpfr_t", mpfr_constructor); seed_object_set_property(ctx, mpfr_constructor, "set", mpfr_constructor_set); /* Setup enums */ DEFINE_ENUM_MEMBER(ns_ref, GMP_RNDN); DEFINE_ENUM_MEMBER(ns_ref, GMP_RNDZ); DEFINE_ENUM_MEMBER(ns_ref, GMP_RNDU); DEFINE_ENUM_MEMBER(ns_ref, GMP_RNDD); DEFINE_ENUM_MEMBER_EXT(ns_ref, "VERSION_MAJOR", MPFR_VERSION_MAJOR); DEFINE_ENUM_MEMBER_EXT(ns_ref, "VERSION_MINOR", MPFR_VERSION_MINOR); DEFINE_ENUM_MEMBER_EXT(ns_ref, "VERSION_PATCHLEVEL", MPFR_VERSION_PATCHLEVEL); seed_object_set_property(ctx, ns_ref, "VERSION_STRING", seed_value_from_string(ctx, MPFR_VERSION_STRING, NULL)); DEFINE_ENUM_MEMBER_EXT(ns_ref, "PREC_MIN", MPFR_PREC_MIN); DEFINE_ENUM_MEMBER_EXT(ns_ref, "PREC_MAX", MPFR_PREC_MAX); DEFINE_ENUM_MEMBER_EXT(ns_ref, "EMAX_DEFAULT", MPFR_EMAX_DEFAULT); DEFINE_ENUM_MEMBER_EXT(ns_ref, "EMIN_DEFAULT", MPFR_EMIN_DEFAULT); DEFINE_ENUM_MEMBER_EXT(ns_ref, "NAN_KIND", MPFR_NAN_KIND); DEFINE_ENUM_MEMBER_EXT(ns_ref, "INF_KIND", MPFR_INF_KIND); DEFINE_ENUM_MEMBER_EXT(ns_ref, "ZERO_KIND", MPFR_ZERO_KIND); DEFINE_ENUM_MEMBER_EXT(ns_ref, "REGULAR_KIND", MPFR_REGULAR_KIND); return ns_ref; } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/mpfr/seed-mpfr.h000066400000000000000000000131251303774616400232770ustar00rootroot00000000000000#ifndef _SEED_MPFR_H_ #define _SEED_MPFR_H_ #include #include #define TYPE_EXCEPTION(name, wanted) \ seed_make_exception(ctx, exception, "TypeError", \ name " expected " wanted); \ return seed_make_undefined(ctx); #if 0 /* TODO: Make this work */ /* kind of stupid hack */ #if MPFR_PREC_MAX == G_MAXLONG #define seed_value_to_mpfr_prec_t(a, b, c) seed_value_to_ulong(a, b, c) #define seed_value_from_mpfr_prec_t(a, b, c) seed_value_from_ulong(a, b, c) #elif MPFR_PREC_MAX == G_MAXUSHORT #define seed_value_to_mpfr_prec_t(a, b, c) seed_value_to_ushort(a, b, c) #define seed_value_from_mpfr_prec_t(a, b, c) seed_value_from_ushort(a, b, c) #elif MPFR_PREC_MAX == G_MAXINT #define seed_value_to_mpfr_prec_t(a, b, c) seed_value_to_int(a, b, c) #define seed_value_from_mpfr_prec_t(a, b, c) seed_value_from_int(a, b, c) #elif MPFR_PREC_MAX == G_MAXUINT64 #define seed_value_to_mpfr_prec_t(a, b, c) seed_value_to_uint64(a, b, c) #define seed_value_from_mpfr_prec_t(a, b, c) seed_value_from_uint64(a, b, c) #else #error "Wrong mpfr_prec_t size somehow?" #endif #endif #define seed_value_to_mpfr_prec_t(a, b, c) seed_value_to_uint64(a, b, c) #define seed_value_from_mpfr_prec_t(a, b, c) seed_value_from_uint64(a, b, c) /* TODO: Right size for this */ #define seed_value_to_mpfr_rnd_t(a, b, c) seed_value_to_char(a, b, c) #define seed_value_from_mpfr_rnd_t(a, b, c) seed_value_from_char(a, b, c) #define seed_value_from_mp_exp_t(a, b, c) seed_value_from_ulong(a, b, c) #define seed_value_to_mp_exp_t(a, b, c) seed_value_to_ulong(a, b, c) #define DEF_SEED_MPFR_FUNC(name) \ SeedValue name(SeedContext, SeedObject, SeedObject, gsize, \ const SeedValue[], SeedException*) extern SeedObject ns_ref; extern SeedClass mpfr_class; typedef enum _seed_mpfr_t { SEED_MPFR_UNKNOWN = 0, SEED_MPFR_MPFR = 1 << 1, SEED_MPFR_DOUBLE = 1 << 2, SEED_MPFR_STRING = 1 << 3, } seed_mpfr_t; seed_mpfr_t seed_mpfr_arg_type(SeedContext, SeedValue, SeedException); DEF_SEED_MPFR_FUNC(seed_mpfr_neg); DEF_SEED_MPFR_FUNC(seed_mpfr_abs); DEF_SEED_MPFR_FUNC(seed_mpfr_dim); DEF_SEED_MPFR_FUNC(seed_mpfr_rint); DEF_SEED_MPFR_FUNC(seed_mpfr_ceil); DEF_SEED_MPFR_FUNC(seed_mpfr_floor); DEF_SEED_MPFR_FUNC(seed_mpfr_round); DEF_SEED_MPFR_FUNC(seed_mpfr_trunc); DEF_SEED_MPFR_FUNC(seed_mpfr_frac); DEF_SEED_MPFR_FUNC(seed_mpfr_nexttoward); DEF_SEED_MPFR_FUNC(seed_mpfr_nextabove); DEF_SEED_MPFR_FUNC(seed_mpfr_nextbelow); DEF_SEED_MPFR_FUNC(seed_mpfr_prec_round); DEF_SEED_MPFR_FUNC(seed_mpfr_signbit); DEF_SEED_MPFR_FUNC(seed_mpfr_setsign); DEF_SEED_MPFR_FUNC(seed_mpfr_copysign); DEF_SEED_MPFR_FUNC(seed_mpfr_min); DEF_SEED_MPFR_FUNC(seed_mpfr_max); DEF_SEED_MPFR_FUNC(seed_mpfr_fmod); DEF_SEED_MPFR_FUNC(seed_mpfr_remainder); DEF_SEED_MPFR_FUNC(seed_mpfr_integer_p); DEF_SEED_MPFR_FUNC(seed_mpfr_rint_ceil); DEF_SEED_MPFR_FUNC(seed_mpfr_rint_floor); DEF_SEED_MPFR_FUNC(seed_mpfr_rint_round); DEF_SEED_MPFR_FUNC(seed_mpfr_rint_trunc); DEF_SEED_MPFR_FUNC(seed_mpfr_add); DEF_SEED_MPFR_FUNC(seed_mpfr_sub); DEF_SEED_MPFR_FUNC(seed_mpfr_mul); DEF_SEED_MPFR_FUNC(seed_mpfr_div); DEF_SEED_MPFR_FUNC(seed_mpfr_sin); DEF_SEED_MPFR_FUNC(seed_mpfr_cos); DEF_SEED_MPFR_FUNC(seed_mpfr_tan); DEF_SEED_MPFR_FUNC(seed_mpfr_csc); DEF_SEED_MPFR_FUNC(seed_mpfr_sec); DEF_SEED_MPFR_FUNC(seed_mpfr_cot); DEF_SEED_MPFR_FUNC(seed_mpfr_asin); DEF_SEED_MPFR_FUNC(seed_mpfr_acos); DEF_SEED_MPFR_FUNC(seed_mpfr_atan); DEF_SEED_MPFR_FUNC(seed_mpfr_log); DEF_SEED_MPFR_FUNC(seed_mpfr_log2); DEF_SEED_MPFR_FUNC(seed_mpfr_log10); DEF_SEED_MPFR_FUNC(seed_mpfr_sinh); DEF_SEED_MPFR_FUNC(seed_mpfr_cosh); DEF_SEED_MPFR_FUNC(seed_mpfr_tanh); DEF_SEED_MPFR_FUNC(seed_mpfr_csch); DEF_SEED_MPFR_FUNC(seed_mpfr_sech); DEF_SEED_MPFR_FUNC(seed_mpfr_coth); DEF_SEED_MPFR_FUNC(seed_mpfr_asinh); DEF_SEED_MPFR_FUNC(seed_mpfr_acosh); DEF_SEED_MPFR_FUNC(seed_mpfr_atanh); DEF_SEED_MPFR_FUNC(seed_mpfr_sqrt); DEF_SEED_MPFR_FUNC(seed_mpfr_sqr); DEF_SEED_MPFR_FUNC(seed_mpfr_pow); DEF_SEED_MPFR_FUNC(seed_mpfr_root); DEF_SEED_MPFR_FUNC(seed_mpfr_rec_sqrt); DEF_SEED_MPFR_FUNC(seed_mpfr_cbrt); DEF_SEED_MPFR_FUNC(seed_mpfr_mul_2si); DEF_SEED_MPFR_FUNC(seed_mpfr_div_2si); DEF_SEED_MPFR_FUNC(seed_mpfr_cmp); DEF_SEED_MPFR_FUNC(seed_mpfr_cmpabs); DEF_SEED_MPFR_FUNC(seed_mpfr_cmp_si_2exp); DEF_SEED_MPFR_FUNC(seed_mpfr_nan_p); DEF_SEED_MPFR_FUNC(seed_mpfr_inf_p); DEF_SEED_MPFR_FUNC(seed_mpfr_number_p); DEF_SEED_MPFR_FUNC(seed_mpfr_zero_p); DEF_SEED_MPFR_FUNC(seed_mpfr_sgn); DEF_SEED_MPFR_FUNC(seed_mpfr_greater_p); DEF_SEED_MPFR_FUNC(seed_mpfr_greaterequal_p); DEF_SEED_MPFR_FUNC(seed_mpfr_less_p); DEF_SEED_MPFR_FUNC(seed_mpfr_lessequal_p); DEF_SEED_MPFR_FUNC(seed_mpfr_lessgreater_p); DEF_SEED_MPFR_FUNC(seed_mpfr_equal_p); DEF_SEED_MPFR_FUNC(seed_mpfr_unordered_p); DEF_SEED_MPFR_FUNC(seed_mpfr_log1p); DEF_SEED_MPFR_FUNC(seed_mpfr_expm1); DEF_SEED_MPFR_FUNC(seed_mpfr_li2); DEF_SEED_MPFR_FUNC(seed_mpfr_gamma); DEF_SEED_MPFR_FUNC(seed_mpfr_lngamma); DEF_SEED_MPFR_FUNC(seed_mpfr_zeta); DEF_SEED_MPFR_FUNC(seed_mpfr_erf); DEF_SEED_MPFR_FUNC(seed_mpfr_erfc); DEF_SEED_MPFR_FUNC(seed_mpfr_j0); DEF_SEED_MPFR_FUNC(seed_mpfr_j1); DEF_SEED_MPFR_FUNC(seed_mpfr_jn); DEF_SEED_MPFR_FUNC(seed_mpfr_y0); DEF_SEED_MPFR_FUNC(seed_mpfr_y1); DEF_SEED_MPFR_FUNC(seed_mpfr_yn); DEF_SEED_MPFR_FUNC(seed_mpfr_fma); DEF_SEED_MPFR_FUNC(seed_mpfr_fms); DEF_SEED_MPFR_FUNC(seed_mpfr_agm); DEF_SEED_MPFR_FUNC(seed_mpfr_hypot); DEF_SEED_MPFR_FUNC(seed_mpfr_free_cache); DEF_SEED_MPFR_FUNC(seed_mpfr_clear_flags); #endif /* _SEED_MFPR_H_ */ seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/multiprocessing/000077500000000000000000000000001303774616400235255ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/multiprocessing/Makefile.am000066400000000000000000000011661303774616400255650ustar00rootroot00000000000000if BUILD_MULTIPROCESSING_MODULE EXTRA_DIST = fork.js bi.js seedlibdir = ${libdir}/seed@SEED_GTK_VERSION@ seedlib_LTLIBRARIES = \ libseed_multiprocessing.la libseed_multiprocessing_la_SOURCES = \ seed-multiprocessing.c libseed_multiprocessing_la_CFLAGS = \ -I@top_srcdir@/libseed/ \ $(GOBJECT_INTROSPECTION_CFLAGS) \ $(SEED_DEBUG_CFLAGS) \ $(SEED_PROFILE_CFLAGS) libseed_multiprocessing_la_LDFLAGS = \ -module -avoid-version \ $(GOBJECT_INTROSPECTION_LDFLAGS) libseed_multiprocessing_la_LIBADD = \ $(top_builddir)/libseed/libseed@SEED_GTK_VERSION@.la \ $(SEED_PROFILE_LIBS) endif -include $(top_srcdir)/git.mk seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/multiprocessing/bi.js000077500000000000000000000010611303774616400244560ustar00rootroot00000000000000#!/usr/bin/env seed multiprocessing = imports.multiprocessing; Gtk = imports.gi.Gtk; os = imports.os; JSON = imports.JSON; pipes = new multiprocessing.Pipe(); child_pid = os.fork(); if (child_pid == 0) { mine = pipes[0]; mine.add_watch(1, function() { var message = {type: "PING", data: "Hello!"}; mine.write(JSON.stringify(message)); return true; }); Gtk.main(); } mine = pipes[1]; mine.write("Ping"); message = JSON.parse(mine.read()); print("Parent Got: " + message.type + ": " + message.data); seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/multiprocessing/fork.js000077500000000000000000000012701303774616400250270ustar00rootroot00000000000000#!/usr/bin/env seed multiprocessing = imports.multiprocessing; Gtk = imports.gi.Gtk; GLib = imports.gi.GLib; os = imports.os; JSON = imports.JSON; pipe = new multiprocessing.Pipe(); child_pid = os.fork(); if (child_pid == 0) { Gtk.init(null, null); childs = pipe[0]; w = new Gtk.Window(); l = new Gtk.Label(); w.add(l); w.show_all(); childs.add_watch(1, function(source, condition, label) { label.label = source.read(); return true; }, l); Gtk.main(); } Gtk.init(null, null); parents = pipe[1]; w = new Gtk.Window(); l = new Gtk.Entry(); w.add(l); w.show_all(); l.signal.activate.connect(function(entry){parents.write(entry.text);}); Gtk.main(); seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/multiprocessing/seed-multiprocessing.c000066400000000000000000000144051303774616400300420ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #include #include #include SeedEngine* eng; SeedObject namespace_ref; SeedClass pipe_class; typedef struct _pipe_priv { GIOChannel* read; GIOChannel* write; } pipe_priv; void pipe_finalize(SeedObject pipeobj) { pipe_priv* priv = seed_object_get_private(pipeobj); g_io_channel_unref(priv->read); g_io_channel_unref(priv->write); g_free(priv); } SeedObject seed_construct_pipe(SeedContext ctx, SeedObject constructor, size_t argument_count, const SeedValue arguments[], SeedException* exception) { SeedObject jsone, jstwo, jsret; int fd1[2], fd2[2]; pipe_priv *priv_one, *priv_two; CHECK_ARG_COUNT("multiprocessing.pipe constructor", 0); if (pipe(fd1) < 0) { perror("Pipe failed. Make me a javascript exception"); return seed_make_null(ctx); } if (pipe(fd2) < 0) { perror("Pipe failed. Make me a javascript exception"); return seed_make_null(ctx); } priv_one = g_new0(pipe_priv, 1); priv_two = g_new0(pipe_priv, 1); priv_one->read = g_io_channel_unix_new(fd1[0]); priv_one->write = g_io_channel_unix_new(fd2[1]); priv_two->read = g_io_channel_unix_new(fd2[0]); priv_two->write = g_io_channel_unix_new(fd1[1]); g_io_channel_set_close_on_unref(priv_one->read, TRUE); g_io_channel_set_close_on_unref(priv_one->write, TRUE); g_io_channel_set_close_on_unref(priv_two->read, TRUE); g_io_channel_set_close_on_unref(priv_two->write, TRUE); jsret = seed_make_object(ctx, 0, 0); jsone = seed_make_object(ctx, pipe_class, priv_one); jstwo = seed_make_object(ctx, pipe_class, priv_two); seed_object_set_property_at_index(ctx, jsret, 0, jsone, exception); seed_object_set_property_at_index(ctx, jsret, 1, jstwo, exception); return jsret; } #define GET_CHANNEL pipe_priv* priv = seed_object_get_private(this_object) SeedValue seed_pipe_read(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { SeedValue ret; gchar* read; GET_CHANNEL; CHECK_ARG_COUNT("multiprocessing.pipe.read", 0); g_io_channel_read_line(priv->read, &read, 0, 0, 0); ret = seed_value_from_string(ctx, read, exception); g_free(read); return ret; } typedef struct _marshal_privates { SeedObject function; SeedObject source; SeedValue user_data; } marshal_privates; static gboolean gio_marshal_func(GIOChannel* source, GIOCondition condition, gpointer data) { SeedGlobalContext ctx = seed_context_create(eng->group, 0); SeedValue jscondition = seed_value_from_long(ctx, (glong) condition, 0); SeedValue args[3], ret; marshal_privates* priv = (marshal_privates*) data; gboolean bret; args[0] = priv->source; args[1] = jscondition; args[2] = priv->user_data; ret = seed_object_call(ctx, priv->function, 0, 3, args, 0); bret = seed_value_to_boolean(ctx, ret, 0); seed_context_unref(ctx); if (!bret) g_free(priv); return bret; } SeedValue seed_pipe_write(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { gchar* data; gsize written; gchar eol = '\n'; GET_CHANNEL; CHECK_ARG_COUNT("multiprocessing.pipe.write", 1); data = seed_value_to_string(ctx, arguments[0], exception); g_io_channel_write_chars(priv->write, data, -1, &written, 0); g_io_channel_write_chars(priv->write, &eol, 1, 0, 0); g_io_channel_flush(priv->write, 0); return seed_value_from_int(ctx, written, exception); } SeedValue seed_pipe_add_watch(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { GET_CHANNEL; marshal_privates* mpriv = g_malloc0(sizeof(marshal_privates)); glong condition = seed_value_to_long(ctx, arguments[0], exception); mpriv->function = arguments[1]; mpriv->source = this_object; mpriv->user_data = argument_count == 3 ? arguments[2] : seed_make_null(ctx); g_io_add_watch(priv->read, condition, gio_marshal_func, mpriv); return seed_value_from_boolean(ctx, TRUE, exception); } seed_static_function pipe_funcs[] = { { "read", seed_pipe_read, 0 }, { "write", seed_pipe_write, 0 }, { "add_watch", seed_pipe_add_watch, 0 }, { NULL, NULL, 0 } }; SeedObject seed_module_init(SeedEngine* local_eng) { SeedObject pipe_constructor; seed_class_definition pipe_class_def = seed_empty_class; eng = local_eng; namespace_ref = seed_make_object(eng->context, 0, 0); pipe_class_def.class_name = "Pipe"; pipe_class_def.static_functions = pipe_funcs; pipe_class_def.finalize = pipe_finalize; pipe_class = seed_create_class(&pipe_class_def); pipe_constructor = seed_make_constructor(eng->context, 0, seed_construct_pipe); seed_object_set_property(eng->context, namespace_ref, "Pipe", pipe_constructor); return namespace_ref; } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/os/000077500000000000000000000000001303774616400207175ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/os/Makefile.am000066400000000000000000000010401303774616400227460ustar00rootroot00000000000000if BUILD_OS_MODULE seedlibdir = ${libdir}/seed@SEED_GTK_VERSION@ seedlib_LTLIBRARIES = \ libseed_os.la libseed_os_la_SOURCES = \ seed-os.c libseed_os_la_CFLAGS = \ -I@top_srcdir@/libseed/ \ $(GOBJECT_INTROSPECTION_CFLAGS) \ $(SEED_DEBUG_CFLAGS) \ $(SEED_PROFILE_CFLAGS) libseed_os_la_LDFLAGS = \ -module -avoid-version \ $(GOBJECT_INTROSPECTION_LDFLAGS) \ $(SEED_DEBUG_LDFLAGS) libseed_os_la_LIBADD = \ $(top_builddir)/libseed/libseed@SEED_GTK_VERSION@.la \ -lutil \ $(SEED_PROFILE_LIBS) endif -include $(top_srcdir)/git.mk seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/os/seed-os.c000066400000000000000000000760041303774616400224310ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #define _GNU_SOURCE #include "../../config.h" #include #include #include #include #include #include #include #if defined(__FreeBSD__) || defined(__OpenBSD__) #include #endif #include #include #include #if defined(__FreeBSD__) #include #endif #include #include #ifdef HAVE_PTY_H #include #endif #include SeedObject os_namespace; #define EXPECTED_EXCEPTION(name, argnum) \ seed_make_exception(ctx, exception, "ArgumentError", \ name " expected " argnum " got %zd", argument_count); \ return seed_make_undefined(ctx); SeedValue seed_os_realpath(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { SeedValue sv; gchar* arg; gchar* resolved_path; if (argument_count != 1) { EXPECTED_EXCEPTION("os.realpath", "1 argument"); } arg = seed_value_to_string(ctx, arguments[0], exception); resolved_path = realpath(arg, NULL); g_free(arg); sv = seed_value_from_string(ctx, resolved_path, exception); g_free(resolved_path); return sv; } SeedValue seed_os_chdir(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { gchar* arg; gint ret; if (argument_count != 1) { EXPECTED_EXCEPTION("os.chdir", "1 argument"); } arg = seed_value_to_string(ctx, arguments[0], exception); ret = chdir(arg); g_free(arg); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_os_fchdir(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { gint ret, arg; if (argument_count != 1) { EXPECTED_EXCEPTION("os.fchdir", "1 argument"); } arg = seed_value_to_int(ctx, arguments[0], exception); ret = fchdir(arg); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_os_getcwd(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { SeedValue seed_ret; gchar* ret; if (argument_count != 0) { EXPECTED_EXCEPTION("os.getcwd", "no arguments"); } ret = getcwd(NULL, 0); seed_ret = seed_value_from_string(ctx, ret, exception); g_free(ret); return seed_ret; } SeedValue seed_os_ctermid(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { SeedValue seed_ret; gchar* ret; if (argument_count != 0) { EXPECTED_EXCEPTION("os.getcwd", "no arguments"); } // ctermid returns a static buffer ret = ctermid(NULL); seed_ret = seed_value_from_string(ctx, ret, exception); return seed_ret; } SeedValue seed_os_getegid(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { gid_t ret; if (argument_count != 0) { EXPECTED_EXCEPTION("os.getegid", "no arguments"); } ret = getegid(); return seed_value_from_long(ctx, (glong) ret, exception); } SeedValue seed_os_geteuid(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { uid_t ret; if (argument_count != 0) { EXPECTED_EXCEPTION("os.geteuid", "no arguments"); } ret = geteuid(); return seed_value_from_long(ctx, (glong) ret, exception); } SeedValue seed_os_getgid(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { gid_t ret; if (argument_count != 0) { EXPECTED_EXCEPTION("os.getgid", "no arguments"); } ret = getgid(); return seed_value_from_long(ctx, (glong) ret, exception); } SeedValue seed_os_getuid(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { uid_t ret; if (argument_count != 0) { EXPECTED_EXCEPTION("os.getuid", "no arguments"); } ret = getuid(); return seed_value_from_long(ctx, (glong) ret, exception); } SeedValue seed_os_getgroups(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { SeedValue ret; SeedValue* groups; gid_t* group_list; guint num_groups, i; if (argument_count != 0) { EXPECTED_EXCEPTION("os.getgroups", "no arguments"); } num_groups = getgroups(0, NULL); group_list = g_alloca(num_groups * sizeof(gid_t)); groups = g_alloca(num_groups * sizeof(SeedValue)); if (getgroups(num_groups, group_list) < 0) { // TODO: Decide on how to handle exceptions for things like this... // Investigate python return seed_make_null(ctx); } for (i = 0; i < num_groups; i++) { groups[i] = seed_value_from_long(ctx, (glong) group_list[i], exception); } ret = seed_make_array(ctx, groups, num_groups, exception); return ret; } SeedValue seed_os_getlogin(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { if (argument_count != 0) { EXPECTED_EXCEPTION("os.getlogin", "no arguments"); } return seed_value_from_string(ctx, getlogin(), exception); } SeedValue seed_os_getpgid(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { pid_t pid; if (argument_count != 1) { EXPECTED_EXCEPTION("os.getpgid", "1 argument"); } pid = (pid_t) seed_value_to_long(ctx, arguments[0], exception); return seed_value_from_long(ctx, (glong) getpgid(pid), exception); } SeedValue seed_os_getpgrp(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { if (argument_count != 0) { EXPECTED_EXCEPTION("os.getpgrp", "no arguments"); } return seed_value_from_long(ctx, (glong) getpgrp(), exception); } SeedValue seed_os_getpid(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { if (argument_count != 0) { EXPECTED_EXCEPTION("os.getpid", "no arguments"); } return seed_value_from_long(ctx, (glong) getpid(), exception); } SeedValue seed_os_getppid(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { if (argument_count != 0) { EXPECTED_EXCEPTION("os.getppid", "no arguments"); } return seed_value_from_long(ctx, (glong) getppid(), exception); } SeedValue seed_os_getenv(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { SeedValue ret; gchar *name, *value; if (argument_count != 1) { EXPECTED_EXCEPTION("os.getenv", "1 arguments"); } name = seed_value_to_string(ctx, arguments[0], exception); value = getenv(name); ret = seed_value_from_string(ctx, value, exception); g_free(name); return ret; } SeedValue seed_os_putenv(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { gint ret; gchar *name, *value, *arg; if (argument_count != 2) { EXPECTED_EXCEPTION("os.putenv", "2 arguments"); } name = seed_value_to_string(ctx, arguments[0], exception); value = seed_value_to_string(ctx, arguments[1], exception); arg = g_strconcat(name, "=", value, NULL); ret = putenv(arg); g_free(name); g_free(value); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_os_setegid(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { gid_t arg; if (argument_count != 1) { EXPECTED_EXCEPTION("os.setegid", "1 argument"); } arg = seed_value_to_long(ctx, arguments[0], exception); return seed_value_from_int(ctx, setegid(arg), exception); } SeedValue seed_os_setgid(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { gid_t arg; if (argument_count != 1) { EXPECTED_EXCEPTION("os.setgid", "1 argument"); } arg = seed_value_to_long(ctx, arguments[0], exception); return seed_value_from_int(ctx, setgid(arg), exception); } SeedValue seed_os_seteuid(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { uid_t arg; if (argument_count != 1) { EXPECTED_EXCEPTION("os.seteuid", "1 argument"); } arg = seed_value_to_long(ctx, arguments[0], exception); return seed_value_from_int(ctx, seteuid(arg), exception); } SeedValue seed_os_setuid(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { uid_t arg; if (argument_count != 1) { EXPECTED_EXCEPTION("os.setuid", "1 argument"); } arg = seed_value_to_long(ctx, arguments[0], exception); return seed_value_from_int(ctx, setuid(arg), exception); } SeedValue seed_os_strerror(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { int arg; if (argument_count != 1) { EXPECTED_EXCEPTION("os.strerror", "1 argument"); } arg = seed_value_to_int(ctx, arguments[0], exception); return seed_value_from_string(ctx, strerror(arg), exception); } SeedValue seed_os_umask(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { mode_t arg; if (argument_count != 1) { EXPECTED_EXCEPTION("os.umask", "1 argument"); } arg = seed_value_to_long(ctx, arguments[0], exception); return seed_value_from_long(ctx, umask(arg), exception); } SeedValue seed_os_uname(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { SeedValue elements[5], ret; guint c; struct utsname name; if (argument_count != 0) { EXPECTED_EXCEPTION("os.uname", "no arguments"); } c = uname(&name); // TODO: Do something with c elements[0] = seed_value_from_string(ctx, name.sysname, exception); elements[1] = seed_value_from_string(ctx, name.nodename, exception); elements[2] = seed_value_from_string(ctx, name.release, exception); elements[3] = seed_value_from_string(ctx, name.version, exception); elements[4] = seed_value_from_string(ctx, name.machine, exception); ret = seed_make_array(ctx, elements, 5, exception); return ret; } SeedValue seed_os_unsetenv(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { gint ret; gchar* arg; if (argument_count != 1) { EXPECTED_EXCEPTION("os.unsetenv", "1 argument"); } arg = seed_value_to_string(ctx, arguments[0], exception); #if __FreeBSD_version < 700000 ret = 0; unsetenv(arg); #else ret = unsetenv(arg); #endif g_free(arg); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_os_open(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { gchar* path; gint flags, ret; if (argument_count != 2) { EXPECTED_EXCEPTION("os.open", "2 arguments"); } path = seed_value_to_string(ctx, arguments[0], exception); flags = seed_value_to_int(ctx, arguments[1], exception); ret = open(path, flags); g_free(path); return seed_value_from_int(ctx, ret, exception); } SeedValue seed_os_close(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { gint arg; if (argument_count != 1) { EXPECTED_EXCEPTION("os.close", "2 arguments"); } arg = seed_value_to_int(ctx, arguments[0], exception); return seed_value_from_int(ctx, close(arg), exception); } SeedValue seed_os_dup(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { gint arg; if (argument_count != 1) { EXPECTED_EXCEPTION("os.dup", "1 argument"); } arg = seed_value_to_int(ctx, arguments[0], exception); return seed_value_from_int(ctx, dup(arg), exception); } SeedValue seed_os_dup2(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { gint arg, arg2; if (argument_count != 2) { EXPECTED_EXCEPTION("os.dup2", "2 arguments"); } arg = seed_value_to_int(ctx, arguments[0], exception); arg2 = seed_value_to_int(ctx, arguments[0], exception); return seed_value_from_int(ctx, dup2(arg, arg2), exception); } SeedValue seed_os_fchmod(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { gint fd; mode_t mode; if (argument_count != 2) { EXPECTED_EXCEPTION("os.fchmod", "2 arguments"); } fd = seed_value_to_int(ctx, arguments[0], exception); mode = seed_value_to_long(ctx, arguments[1], exception); return seed_value_from_int(ctx, fchmod(fd, mode), exception); } SeedValue seed_os_fchown(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { gint fd; gid_t gid; uid_t uid; if (argument_count != 3) { EXPECTED_EXCEPTION("os.fchown", "3 arguments"); } fd = seed_value_to_int(ctx, arguments[0], exception); uid = seed_value_to_long(ctx, arguments[1], exception); gid = seed_value_to_long(ctx, arguments[2], exception); return seed_value_from_int(ctx, fchown(fd, uid, gid), exception); } SeedValue seed_os_fdatasync(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { #if !defined(__FreeBSD__) && !defined(__OpenBSD__) gint fd; if (argument_count != 1) { EXPECTED_EXCEPTION("os.fdatasync", "1 argument"); } fd = seed_value_to_int(ctx, arguments[0], exception); return seed_value_from_int(ctx, fdatasync(fd), exception); #else errno = ENOSYS; return seed_value_from_int(ctx, -1, exception); #endif } SeedValue seed_os_fpathconf(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { gint fd, name; if (argument_count != 2) { EXPECTED_EXCEPTION("os.fpathconf", "2 arguments"); } fd = seed_value_to_int(ctx, arguments[0], exception); name = seed_value_to_int(ctx, arguments[1], exception); return seed_value_from_long(ctx, fpathconf(fd, name), exception); } SeedValue seed_os_fsync(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { gint fd; if (argument_count != 1) { EXPECTED_EXCEPTION("os.fsync", "1 argument"); } fd = seed_value_to_int(ctx, arguments[0], exception); return seed_value_from_long(ctx, fsync(fd), exception); } SeedValue seed_os_ftruncate(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { gint fd; off_t length; if (argument_count != 2) { EXPECTED_EXCEPTION("os.ftruncate", "2 arguments"); } fd = seed_value_to_int(ctx, arguments[0], exception); length = seed_value_to_int(ctx, arguments[1], exception); return seed_value_from_long(ctx, ftruncate(fd, length), exception); } SeedValue seed_os_isatty(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { gint fd; if (argument_count != 1) { EXPECTED_EXCEPTION("os.isatty", "1 argument"); } fd = seed_value_to_int(ctx, arguments[0], exception); return seed_value_from_boolean(ctx, isatty(fd), exception); } SeedValue seed_os_lseek(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { gint fd, whence; off_t offset; if (argument_count != 3) { EXPECTED_EXCEPTION("os.lseek", "3 arguments"); } fd = seed_value_to_int(ctx, arguments[0], exception); offset = seed_value_to_long(ctx, arguments[1], exception); whence = seed_value_to_int(ctx, arguments[2], exception); return seed_value_from_long(ctx, lseek(fd, offset, whence), exception); } SeedValue seed_os_openpty(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { SeedValue fds[2], ret; gint master, slave; if (argument_count != 0) { EXPECTED_EXCEPTION("os.openpty", "no arguments"); } openpty(&master, &slave, NULL, NULL, NULL); fds[0] = seed_value_from_int(ctx, master, exception); fds[1] = seed_value_from_int(ctx, slave, exception); ret = seed_make_array(ctx, fds, 2, exception); return ret; } SeedValue seed_os_pipe(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { SeedValue fds[2], ret; gint fildes[2]; if (argument_count != 0) { EXPECTED_EXCEPTION("os.pipe", "no arguments"); } if (pipe(fildes) < 0) { // TODO } fds[0] = seed_value_from_int(ctx, fildes[0], exception); fds[1] = seed_value_from_int(ctx, fildes[1], exception); ret = seed_make_array(ctx, fds, 2, exception); return ret; } SeedValue seed_os_read(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { SeedValue ret; gint fd, n, nr; gchar* buf; if (argument_count != 2) { EXPECTED_EXCEPTION("os.read", "2 arguments"); } fd = seed_value_to_int(ctx, arguments[0], exception); n = seed_value_to_int(ctx, arguments[1], exception); buf = g_alloca(n * sizeof(gchar)); nr = read(fd, buf, n); buf[nr] = '\0'; if (nr) ret = seed_value_from_string(ctx, buf, exception); else ret = seed_make_null(ctx); return ret; } SeedValue seed_os_write(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { gint fd, nw; gchar* buf; if (argument_count != 2) { EXPECTED_EXCEPTION("os.write", "2 arguments"); } fd = seed_value_to_int(ctx, arguments[0], exception); buf = seed_value_to_string(ctx, arguments[1], exception); nw = write(fd, buf, strlen(buf)); return seed_value_from_int(ctx, nw, exception); } SeedValue seed_os_ttyname(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { gint fd; if (argument_count != 1) { EXPECTED_EXCEPTION("os.ttyname", "1 argument"); } fd = seed_value_to_int(ctx, arguments[0], exception); return seed_value_from_string(ctx, ttyname(fd), exception); } SeedValue seed_os_tcgetpgrp(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { gint fd; if (argument_count != 1) { EXPECTED_EXCEPTION("os.tcgetpgrp", "1 argument"); } fd = seed_value_to_int(ctx, arguments[0], exception); return seed_value_from_long(ctx, tcgetpgrp(fd), exception); } SeedValue seed_os_tcsetpgrp(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { gint fd; pid_t pgrp; if (argument_count != 2) { EXPECTED_EXCEPTION("os.tcsetpgrp", "2 arguments"); } fd = seed_value_to_int(ctx, arguments[0], exception); pgrp = seed_value_to_int(ctx, arguments[1], exception); return seed_value_from_int(ctx, tcsetpgrp(fd, pgrp), exception); } SeedValue seed_os_access(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { int ret; gchar* path; int amd; if (argument_count != 2) { EXPECTED_EXCEPTION("os.access", "2 arguments"); } path = seed_value_to_string(ctx, arguments[0], exception); amd = seed_value_to_int(ctx, arguments[1], exception); ret = access(path, amd); if (ret == 0) return seed_value_from_boolean(ctx, TRUE, exception); else return seed_value_from_boolean(ctx, FALSE, exception); } static SeedValue seed_os_fork(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException* exception) { pid_t t = fork(); return seed_value_from_long(ctx, t, exception); } seed_static_function os_funcs[] = { { "fork", seed_os_fork, 0 }, { "realpath", seed_os_realpath, 0 }, { "chdir", seed_os_chdir, 0 }, { "fchdir", seed_os_fchdir, 0 }, { "getcwd", seed_os_getcwd, 0 }, { "ctermid", seed_os_ctermid, 0 }, { "getegid", seed_os_getegid, 0 }, { "geteuid", seed_os_geteuid, 0 }, { "getgid", seed_os_getgid, 0 }, { "getuid", seed_os_getuid, 0 }, { "getlogin", seed_os_getlogin, 0 }, { "getpgid", seed_os_getpgid, 0 }, { "getpgrp", seed_os_getpgrp, 0 }, { "getpid", seed_os_getpid, 0 }, { "getppid", seed_os_getuid, 0 }, { "getenv", seed_os_getenv, 0 }, { "putenv", seed_os_putenv, 0 }, { "setegid", seed_os_setegid, 0 }, { "setgid", seed_os_setegid, 0 }, { "seteuid", seed_os_setegid, 0 }, { "setuid", seed_os_setuid, 0 }, { "strerror", seed_os_strerror, 0 }, { "umask", seed_os_umask, 0 }, { "uname", seed_os_uname, 0 }, { "unsetenv", seed_os_unsetenv, 0 }, { "open", seed_os_open, 0 }, { "close", seed_os_close, 0 }, { "dup", seed_os_dup, 0 }, { "dup2", seed_os_dup2, 0 }, { "fchmod", seed_os_fchmod, 0 }, { "fchown", seed_os_fchown, 0 }, { "fdatasync", seed_os_fdatasync, 0 }, { "fpathconf", seed_os_fpathconf, 0 }, { "fsync", seed_os_fsync, 0 }, { "ftruncate", seed_os_ftruncate, 0 }, { "isatty", seed_os_isatty, 0 }, { "lseek", seed_os_lseek, 0 }, { "openpty", seed_os_openpty, 0 }, { "pipe", seed_os_pipe, 0 }, { "read", seed_os_read, 0 }, { "write", seed_os_write, 0 }, { "ttyname", seed_os_ttyname, 0 }, { "tcgetpgrp", seed_os_tcgetpgrp, 0 }, { "tcsetpgrp", seed_os_tcsetpgrp, 0 }, { "access", seed_os_access, 0 }, { NULL, NULL, 0 } }; #define OS_DEFINE_ENUM(name, value) \ seed_object_set_property(eng->context, os_namespace, name, \ seed_value_from_long(eng->context, value, NULL)) #define OS_DEFINE_QUICK_ENUM(value) \ seed_object_set_property(eng->context, os_namespace, #value, \ seed_value_from_long(eng->context, value, NULL)) SeedObject seed_module_init(SeedEngine* eng) { SeedClass os_namespace_class; seed_class_definition os_namespace_class_definition = seed_empty_class; os_namespace_class_definition.static_functions = os_funcs; os_namespace_class = seed_create_class(&os_namespace_class_definition); os_namespace = seed_make_object(eng->context, os_namespace_class, NULL); OS_DEFINE_QUICK_ENUM(O_RDONLY); OS_DEFINE_QUICK_ENUM(O_WRONLY); OS_DEFINE_QUICK_ENUM(O_RDWR); OS_DEFINE_QUICK_ENUM(O_APPEND); OS_DEFINE_QUICK_ENUM(O_CREAT); OS_DEFINE_QUICK_ENUM(O_EXCL); OS_DEFINE_QUICK_ENUM(O_TRUNC); #if defined(O_DSYNC) OS_DEFINE_QUICK_ENUM(O_DSYNC); #endif #if defined(O_RSYNC) OS_DEFINE_QUICK_ENUM(O_RSYNC); #endif OS_DEFINE_QUICK_ENUM(O_SYNC); OS_DEFINE_QUICK_ENUM(O_NDELAY); OS_DEFINE_QUICK_ENUM(O_NONBLOCK); OS_DEFINE_QUICK_ENUM(O_NOCTTY); // OS_DEFINE_QUICK_ENUM (O_SHLOCK); // OS_DEFINE_QUICK_ENUM (O_EXLOCK); OS_DEFINE_QUICK_ENUM(O_ASYNC); #if defined(O_DIRECT) OS_DEFINE_QUICK_ENUM(O_DIRECT); #endif #if defined(O_DIRECTORY) OS_DEFINE_QUICK_ENUM(O_DIRECTORY); #endif OS_DEFINE_QUICK_ENUM(O_NOFOLLOW); #if defined(O_NOATIME) OS_DEFINE_QUICK_ENUM(O_NOATIME); #endif OS_DEFINE_QUICK_ENUM(SEEK_SET); OS_DEFINE_QUICK_ENUM(SEEK_CUR); OS_DEFINE_QUICK_ENUM(SEEK_END); OS_DEFINE_QUICK_ENUM(F_OK); OS_DEFINE_QUICK_ENUM(R_OK); OS_DEFINE_QUICK_ENUM(W_OK); OS_DEFINE_QUICK_ENUM(X_OK); return os_namespace; } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/readline/000077500000000000000000000000001303774616400220615ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/readline/Makefile.am000066400000000000000000000011311303774616400241110ustar00rootroot00000000000000if BUILD_READLINE_MODULE seedlibdir = ${libdir}/seed@SEED_GTK_VERSION@ seedlib_LTLIBRARIES = \ libseed_readline.la libseed_readline_la_SOURCES = \ seed-readline.c libseed_readline_la_CFLAGS = \ -I@top_srcdir@/libseed/ \ $(GOBJECT_INTROSPECTION_CFLAGS) \ $(FFI_CFLAGS) \ $(SEED_DEBUG_CFLAGS) \ $(SEED_PROFILE_CFLAGS) libseed_readline_la_LDFLAGS = \ -module -avoid-version \ $(GOBJECT_INTROSPECTION_LDFLAGS) \ $(FFI_LDFLAGS) libseed_readline_la_LIBADD = \ $(top_builddir)/libseed/libseed@SEED_GTK_VERSION@.la \ -lreadline \ $(SEED_PROFILE_LIBS) endif -include $(top_srcdir)/git.mk seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/readline/seed-readline.c000066400000000000000000000125331303774616400247320ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #include #include #include #include #include #include SeedObject namespace_ref; SeedEngine* eng; gboolean readline_has_initialized = FALSE; static void seed_handle_rl_closure(ffi_cif* cif, void* result, void** args, void* userdata) { SeedContext ctx = seed_context_create(eng->group, NULL); SeedValue exception = 0; SeedObject function = (SeedObject) userdata; seed_object_call(ctx, function, 0, 0, 0, &exception); if (exception) { gchar* mes = seed_exception_to_string(ctx, exception); g_warning("Exception in readline bind key closure. %s \n", mes); } seed_context_unref((SeedContext) ctx); } // "Leaky" in that it exists for lifetime of program, // kind of unavoidable though. static ffi_closure* seed_make_rl_closure(SeedObject function) { ffi_cif* cif; ffi_closure* closure; cif = g_new0(ffi_cif, 1); closure = mmap(0, sizeof(ffi_closure), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0); ffi_prep_cif(cif, FFI_DEFAULT_ABI, 0, &ffi_type_sint, 0); ffi_prep_closure(closure, cif, seed_handle_rl_closure, function); return closure; } static SeedValue seed_readline_bind(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedValue* exception) { gchar* key; ffi_closure* c; CHECK_ARG_COUNT("readline.bind", 2); key = seed_value_to_string(ctx, arguments[0], exception); c = seed_make_rl_closure((SeedObject) arguments[1]); rl_bind_key(*key, (rl_command_func_t*) c); g_free(key); return seed_make_null(ctx); } static SeedValue seed_rl_done(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedValue* exception) { CHECK_ARG_COUNT("readline.done", 0); rl_done = 1; return seed_make_null(ctx); } static SeedValue seed_rl_buffer(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedValue* exception) { CHECK_ARG_COUNT("readline.buffer", 0); return seed_value_from_string(ctx, rl_line_buffer, exception); } static SeedValue seed_rl_insert(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedValue* exception) { gchar* ins; gint ret; CHECK_ARG_COUNT("readline.insert", 1); ins = seed_value_to_string(ctx, arguments[0], exception); ret = rl_insert_text(ins); g_free(ins); return seed_value_from_int(ctx, ret, exception); } static SeedValue seed_readline(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedValue* exception) { SeedValue valstr = 0; gchar* str = NULL; gchar* buf; const gchar* histfname = g_get_home_dir(); gchar* path = g_build_filename(histfname, ".seed_history", NULL); if (!readline_has_initialized) { read_history(path); readline_has_initialized = TRUE; } CHECK_ARG_COUNT("readline.readline", 1); buf = seed_value_to_string(ctx, arguments[0], exception); str = readline(buf); if (str && *str) { add_history(str); valstr = seed_value_from_string(ctx, str, exception); g_free(str); } write_history(path); history_truncate_file(path, 1000); g_free(buf); g_free(path); if (valstr == 0) valstr = seed_make_null(ctx); return valstr; } seed_static_function readline_funcs[] = { { "readline", seed_readline, 0 }, { "bind", seed_readline_bind, 0 }, { "done", seed_rl_done, 0 }, { "buffer", seed_rl_buffer, 0 }, { "insert", seed_rl_insert, 0 }, { NULL, NULL, 0 } }; SeedObject seed_module_init(SeedEngine* local_eng) { seed_class_definition readline_ns_class_def = seed_empty_class; readline_ns_class_def.static_functions = readline_funcs; SeedClass readline_ns_class = seed_create_class(&readline_ns_class_def); eng = local_eng; namespace_ref = seed_make_object(eng->context, readline_ns_class, 0); return namespace_ref; } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/sandbox/000077500000000000000000000000001303774616400217345ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/sandbox/Makefile.am000066400000000000000000000007671303774616400240020ustar00rootroot00000000000000seedlibdir = ${libdir}/seed@SEED_GTK_VERSION@ seedlib_LTLIBRARIES = \ libseed_sandbox.la libseed_sandbox_la_SOURCES = \ seed-sandbox.c AM_CPPFLAGS = \ -I@top_srcdir@/libseed/ \ $(GOBJECT_INTROSPECTION_CFLAGS) \ $(SEED_DEBUG_CFLAGS) \ $(SEED_PROFILE_CFLAGS) libseed_sandbox_la_LDFLAGS = \ -module -avoid-version \ $(GOBJECT_INTROSPECTION_LDFLAGS) libseed_sandbox_la_LIBADD = \ $(top_builddir)/libseed/libseed@SEED_GTK_VERSION@.la \ $(SEED_PROFILE_LIBS) -include $(top_srcdir)/git.mk seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/sandbox/seed-sandbox.c000066400000000000000000000113011303774616400244500ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #include SeedContext ctx; SeedContextGroup group; SeedObject namespace_ref; SeedClass context_class; static SeedObject seed_construct_sandbox_context(SeedContext ctx, SeedObject constructor, size_t argument_count, const SeedValue arguments[], SeedException* exception) { SeedObject ret; SeedContext c; c = seed_context_create(group, NULL); ret = seed_make_object(ctx, context_class, c); seed_object_set_property(ctx, ret, "global", seed_context_get_global_object(c)); return ret; } static SeedValue seed_context_eval(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { SeedContext c = seed_object_get_private(this_object); SeedValue ret; gchar* s; if (!c) { seed_make_exception(ctx, exception, "ArgumentError", "Context is destroyed"); return seed_make_undefined(ctx); } s = seed_value_to_string(ctx, arguments[0], exception); ret = seed_simple_evaluate(c, s, exception); g_free(s); return ret; } static SeedValue seed_sandbox_context_add_globals(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { SeedContext c = seed_object_get_private(this_object); if (!c) { seed_make_exception(ctx, exception, "ArgumentError", "Context is destroyed"); return seed_make_undefined(ctx); } seed_prepare_global_context(c); SeedObject g = seed_context_get_global_object(c); SeedObject global = seed_context_get_global_object(ctx); SeedValue script_path = seed_object_get_property(ctx, global, "__script_path__"); seed_object_set_property(c, g, "__script_path__", (script_path && seed_value_is_object(ctx, script_path)) ? script_path : seed_make_undefined(ctx)); return seed_make_null(ctx); } static SeedValue seed_sandbox_context_destroy(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { SeedContext c = seed_object_get_private(this_object); seed_context_unref(c); seed_object_set_private(this_object, NULL); return seed_make_null(ctx); } seed_static_function context_funcs[] = { { "eval", seed_context_eval, 0 }, { "add_globals", seed_sandbox_context_add_globals, 0 }, { "destroy", seed_sandbox_context_destroy, 0 }, { NULL, NULL, 0 } }; SeedObject seed_module_init(SeedEngine* eng) { SeedObject context_constructor; seed_class_definition context_class_def = seed_empty_class; ctx = eng->context; group = eng->group; namespace_ref = seed_make_object(ctx, NULL, NULL); context_class_def.class_name = "Context"; context_class_def.static_functions = context_funcs; context_class = seed_create_class(&context_class_def); context_constructor = seed_make_constructor(eng->context, context_class, seed_construct_sandbox_context); seed_object_set_property(eng->context, namespace_ref, "Context", context_constructor); return namespace_ref; } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/sqlite/000077500000000000000000000000001303774616400215775ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/sqlite/Makefile.am000066400000000000000000000012051303774616400236310ustar00rootroot00000000000000if BUILD_SQLITE_MODULE seedlibdir = ${libdir}/seed@SEED_GTK_VERSION@ EXTRA_DIST = example.js seedlib_LTLIBRARIES = \ libseed_sqlite.la libseed_sqlite_la_SOURCES = \ seed-sqlite.c libseed_sqlite_la_CFLAGS = \ -I@top_srcdir@/libseed/ \ $(GOBJECT_INTROSPECTION_CFLAGS) \ $(SQLITE_CFLAGS) \ $(SEED_DEBUG_CFLAGS) \ $(SEED_PROFILE_CFLAGS) libseed_sqlite_la_LDFLAGS = \ -module -avoid-version \ $(GOBJECT_INTROSPECTION_LDFLAGS) \ $(SQLITE_LDFLAGS) \ $(SEED_DEBUG_LDFLAGS) libseed_sqlite_la_LIBADD = \ $(top_builddir)/libseed/libseed@SEED_GTK_VERSION@.la \ $(SQLITE_LIBS) \ $(SEED_PROFILE_LIBS) endif -include $(top_srcdir)/git.mk seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/sqlite/example.js000077500000000000000000000007371303774616400236020ustar00rootroot00000000000000#!/usr/bin/env seed sqlite = imports.sqlite; d = new sqlite.Database(Seed.argv[2]); d.exec("create table t1 (t1key INTEGER PRIMARY KEY,data TEXT,num double,timeEnter DATE);"); d.exec("insert into t1 (data,num) values ('This is sample data',3);"); d.exec("insert into t1 (data,num) values ('More sample data',6);"); d.exec("insert into t1 (data,num) values ('And a little more',9);"); d.exec("select * from t1", function(results){print(JSON.stringify(results))}); d.close(); seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/sqlite/seed-sqlite.c000066400000000000000000000142631303774616400241700ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #include "../../libseed/seed.h" #include SeedObject namespace_ref; SeedClass sqlite_class; SeedEngine* eng; #define MAKE_ERROR_ENUM(name) \ seed_object_set_property(eng->context, namespace_ref, #name, \ seed_value_from_int(eng->context, SQLITE_##name, \ 0)) void define_errors(SeedEngine* eng) { MAKE_ERROR_ENUM(OK); MAKE_ERROR_ENUM(ERROR); MAKE_ERROR_ENUM(INTERNAL); MAKE_ERROR_ENUM(PERM); MAKE_ERROR_ENUM(ABORT); MAKE_ERROR_ENUM(BUSY); MAKE_ERROR_ENUM(LOCKED); MAKE_ERROR_ENUM(NOMEM); MAKE_ERROR_ENUM(READONLY); MAKE_ERROR_ENUM(INTERRUPT); MAKE_ERROR_ENUM(CORRUPT); MAKE_ERROR_ENUM(NOTFOUND); MAKE_ERROR_ENUM(FULL); MAKE_ERROR_ENUM(CANTOPEN); MAKE_ERROR_ENUM(PROTOCOL); MAKE_ERROR_ENUM(EMPTY); MAKE_ERROR_ENUM(SCHEMA); MAKE_ERROR_ENUM(TOOBIG); MAKE_ERROR_ENUM(CONSTRAINT); MAKE_ERROR_ENUM(MISMATCH); MAKE_ERROR_ENUM(MISUSE); MAKE_ERROR_ENUM(NOLFS); MAKE_ERROR_ENUM(AUTH); MAKE_ERROR_ENUM(FORMAT); MAKE_ERROR_ENUM(RANGE); MAKE_ERROR_ENUM(NOTADB); MAKE_ERROR_ENUM(ROW); MAKE_ERROR_ENUM(DONE); } void sqlite_database_finalize(SeedObject object) { sqlite3* db = seed_object_get_private(object); if (db) sqlite3_close(db); } SeedObject sqlite_construct_database(SeedContext ctx, SeedObject constructor, size_t argument_count, const SeedValue arguments[], SeedException* exception) { SeedObject ret; gchar* file; sqlite3* db; int rc; if (argument_count != 1) { seed_make_exception(ctx, exception, "ArgumentError", "sqlite.Database constructor expected 1 argument"); return (SeedObject) seed_make_null(ctx); } file = seed_value_to_string(ctx, arguments[0], exception); rc = sqlite3_open(file, &db); g_free(file); ret = seed_make_object(ctx, sqlite_class, db); seed_object_set_property(ctx, ret, "status", seed_value_from_int(ctx, rc, exception)); return ret; } static int seed_sqlite_exec_callback(SeedObject function, int argc, gchar** argv, gchar** azColName) { SeedGlobalContext ctx; SeedObject hash; int i; if (!function) return 0; ctx = seed_context_create(eng->group, NULL); hash = seed_make_object(ctx, 0, 0); for (i = 0; i < argc; i++) { seed_object_set_property(ctx, hash, azColName[i], seed_value_from_string(ctx, argv[i], 0)); } seed_object_call(ctx, function, 0, 1, &hash, 0); seed_context_unref(ctx); return 0; } SeedValue seed_sqlite_exec(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { gchar* statement; gchar* sqlite_error = 0; sqlite3* db; int rc; if (argument_count < 1) { seed_make_exception(ctx, exception, "ArgumentError", "sqlite.Database.exec expected 1 or 2 arguments"); return seed_make_null(ctx); } statement = seed_value_to_string(ctx, arguments[0], exception); db = seed_object_get_private(this_object); g_assert(db); rc = sqlite3_exec(db, statement, seed_sqlite_exec_callback, argument_count == 2 ? arguments[1] : 0, &sqlite_error); g_free(statement); if (rc != SQLITE_OK) { if (sqlite_error) { seed_make_exception(ctx, exception, "SqliteError", sqlite_error, NULL); sqlite3_free(sqlite_error); } return seed_make_null(ctx); } return seed_value_from_int(ctx, rc, exception); } SeedValue seed_sqlite_close(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { sqlite3* db = seed_object_get_private(this_object); sqlite3_close(db); return seed_value_from_boolean(ctx, TRUE, exception); } seed_static_function database_funcs[] = { { "close", seed_sqlite_close, 0 }, { "exec", seed_sqlite_exec, 0 }, { NULL, NULL, 0 } }; SeedObject seed_module_init(SeedEngine* local_eng) { SeedObject db_constructor; seed_class_definition sqlite_class_def = seed_empty_class; eng = local_eng; namespace_ref = seed_make_object(eng->context, 0, 0); define_errors(eng); sqlite_class_def.class_name = "Database"; sqlite_class_def.finalize = sqlite_database_finalize; sqlite_class_def.static_functions = database_funcs; sqlite_class = seed_create_class(&sqlite_class_def); db_constructor = seed_make_constructor(eng->context, sqlite_class, sqlite_construct_database); seed_object_set_property(eng->context, namespace_ref, "Database", db_constructor); return namespace_ref; } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/xorg/000077500000000000000000000000001303774616400212555ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/xorg/Makefile.am000066400000000000000000000011361303774616400233120ustar00rootroot00000000000000if BUILD_XORG_MODULE seedlibdir = ${libdir}/seed@SEED_GTK_VERSION@ seedlib_LTLIBRARIES = \ libseed_xorg.la libseed_xorg_la_SOURCES = \ seed-xorg.c libseed_xorg_la_CFLAGS = \ -I@top_srcdir@/libseed/ \ $(GOBJECT_INTROSPECTION_CFLAGS) \ $(LIBXSS_CFLAGS) \ $(SEED_DEBUG_CFLAGS) \ $(SEED_PROFILE_CFLAGS) libseed_xorg_la_LDFLAGS = \ -module -avoid-version \ $(GOBJECT_INTROSPECTION_LDFLAGS) \ $(LIBXSS_LDLAGS) \ $(SEED_DEBUG_LDFLAGS) libseed_xorg_la_LIBADD = \ $(top_builddir)/libseed/libseed@SEED_GTK_VERSION@.la \ $(LIBXSS_LIBS) \ $(SEED_PROFILE_LIBS) endif -include $(top_srcdir)/git.mk seed-webkit2-4.0.0+20161014+6c77960+dfsg1/modules/xorg/seed-xorg.c000066400000000000000000000046761303774616400233330ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Alan Knowles 2011 * * This started of as a way to get Xorg information not easily available * elsewhere * * It currently is only used with libxss (screensaver extension) to * get the idle time. * */ #include "../../libseed/seed.h" #include /** * screensaverinfo_get_idletime() * @returns screen idle time. */ SeedValue seed_xorg_screensaverinfo_get_idletime(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { int rc = -1; XScreenSaverInfo* info = XScreenSaverAllocInfo(); Display* display = XOpenDisplay(NULL); if (display != NULL) { XScreenSaverQueryInfo(display, DefaultRootWindow(display), info); rc = info->idle; XCloseDisplay(display); } XFree(info); return seed_value_from_int(ctx, rc, exception); } seed_static_function xorg_funcs[] = { { "screensaverinfo_get_idletime", seed_xorg_screensaverinfo_get_idletime, 0 }, { NULL, NULL, 0 } }; SeedObject seed_module_init(SeedEngine* eng) { SeedObject seed_xorg; SeedClass seed_xorg_class; seed_class_definition seed_xorg_class_definition = seed_empty_class; seed_xorg_class_definition.static_functions = xorg_funcs; seed_xorg_class = seed_create_class(&seed_xorg_class_definition); seed_xorg = seed_make_object(eng->context, seed_xorg_class, NULL); return seed_xorg; } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/ondemand.namespace.diff000066400000000000000000000506421303774616400232070ustar00rootroot00000000000000diff --git a/libseed/seed-builtins.c b/libseed/seed-builtins.c index b5b14fc..6bbb07c 100644 --- a/libseed/seed-builtins.c +++ b/libseed/seed-builtins.c @@ -279,6 +279,48 @@ seed_g_type_name_to_string (GITypeInfo * type) return type_name; } + + +static JSValueRef +seed_run_dispose (JSContextRef ctx, + JSObjectRef function, + JSObjectRef this_object, + size_t argumentCount, + const JSValueRef arguments[], JSValueRef * exception) +{ + + GObject* object; + + + if (argumentCount != 1) + { + seed_make_exception (ctx, exception, "ArgumentError", + "Seed.run_dispose^ expected 1 argument, " + "got %zd", argumentCount); + return JSValueMakeNull (ctx); + } + + if (!JSValueIsObject (ctx, arguments[0])) + return JSValueMakeNull (ctx); + if (!JSValueIsObjectOfClass (ctx, arguments[0], gobject_class)) { + SEED_NOTE (FINALIZATION, + "seed_run_dispose - failed - not gobject_class "); + + return JSValueMakeNull (ctx); + } + + object = seed_value_to_object (ctx, arguments[0], exception); + while(object->ref_count > 1) + g_object_unref(object); + + SEED_NOTE (FINALIZATION, + "Manual dispose of gobject."); + + g_object_run_dispose(object); + return JSValueMakeNull (ctx); +} + + static JSValueRef seed_introspect (JSContextRef ctx, JSObjectRef function, @@ -542,6 +584,7 @@ seed_init_builtins (SeedEngine * local_eng, gint * argc, gchar *** argv) "introspect", &seed_introspect, obj); seed_create_function (local_eng->context, "spawn", &seed_spawn, obj); seed_create_function (local_eng->context, "quit", &seed_quit, obj); + seed_create_function (local_eng->context, "run_dispose", &seed_run_dispose, obj); seed_create_function (local_eng->context, "breakpoint", &seed_breakpoint, obj); diff --git a/libseed/seed-closure.c b/libseed/seed-closure.c index 62241c8..f621160 100644 --- a/libseed/seed-closure.c +++ b/libseed/seed-closure.c @@ -288,10 +288,9 @@ seed_handle_closure (ffi_cif * cif, void *result, void **args, gpointer userdata *(gpointer *) result = 0; } g_base_info_unref ((GIBaseInfo *) return_type); - - JSGarbageCollect(ctx); - + JSGlobalContextRelease ((JSGlobalContextRef) ctx); + JSGarbageCollect(ctx); } SeedNativeClosure * diff --git a/libseed/seed-engine.c b/libseed/seed-engine.c index 3870fb0..06364f1 100644 --- a/libseed/seed-engine.c +++ b/libseed/seed-engine.c @@ -1009,6 +1009,45 @@ seed_gobject_define_property_from_function_info (JSContextRef ctx, } + + +JSObjectRef +seed_gobject_function_info_to_value (JSContextRef ctx, + GIFunctionInfo * info, + gboolean instance) +{ + GIFunctionInfoFlags flags; + JSObjectRef method_ref; + const gchar *name; + + //if (g_base_info_is_deprecated ((GIBaseInfo *) info)) + //g_printf("Not defining deprecated symbol: %s \n", + //g_base_info_get_name((GIBaseInfo *)info)); + + flags = g_function_info_get_flags (info); + + if (instance && (flags & GI_FUNCTION_IS_CONSTRUCTOR)) + { + return; + } + + method_ref = JSObjectMake (ctx, gobject_method_class, + g_base_info_ref ((GIBaseInfo *) info)); + + JSObjectSetPrototype (ctx, method_ref, function_proto); + + + seed_object_set_property (ctx, method_ref, "info", + seed_make_struct (ctx, + g_base_info_ref ((GIBaseInfo *) + info), + base_info_info)); + return method_ref; + +} + + + static void seed_gobject_add_methods_for_interfaces (JSContextRef ctx, GIObjectInfo * oinfo, diff --git a/libseed/seed-engine.h b/libseed/seed-engine.h index 4adcde5..a97c4bd 100644 --- a/libseed/seed-engine.h +++ b/libseed/seed-engine.h @@ -52,6 +52,10 @@ typedef struct _SeedScript JSObjectRef seed_gobject_get_prototype_for_gtype (GType type); JSClassRef seed_gobject_get_class_for_gtype (JSContextRef ctx, GType type); +JSObjectRef +seed_gobject_function_info_to_value (JSContextRef ctx, + GIFunctionInfo * info, + gboolean instance); void seed_gobject_define_property_from_function_info (JSContextRef ctx, GIFunctionInfo * info, diff --git a/libseed/seed-importer.c b/libseed/seed-importer.c index de331ff..b345480 100644 --- a/libseed/seed-importer.c +++ b/libseed/seed-importer.c @@ -28,6 +28,8 @@ JSClassRef importer_class; JSObjectRef importer; JSClassRef gi_importer_class; +JSClassRef gi_importer_namespace; + JSObjectRef gi_importer; JSObjectRef gi_importer_versions; @@ -90,24 +92,25 @@ seed_gi_importer_is_init (GIFunctionInfo * info) return TRUE; } -static void +static JSValueRef seed_gi_importer_handle_function (JSContextRef ctx, - JSObjectRef namespace_ref, GIFunctionInfo * info, JSValueRef * exception) { - if (!seed_gi_importer_is_init (info)) - seed_gobject_define_property_from_function_info (ctx, - (GIFunctionInfo *) info, - namespace_ref, FALSE); - else - { - JSObjectRef init_method; - - init_method = JSObjectMake (ctx, gobject_init_method_class, + + if (seed_gi_importer_is_init (info)) { + + + return JSObjectMake (ctx, gobject_init_method_class, g_base_info_ref ((GIBaseInfo *) info)); - seed_object_set_property (ctx, namespace_ref, "init", init_method); + } + +return seed_gobject_function_info_to_value (ctx, info, FALSE); + + + + } /* @@ -116,9 +119,8 @@ seed_gi_importer_handle_function (JSContextRef ctx, * a value for each member, all in uppercase * i.e. Gtk.WindowType.NORMAL */ -static void -seed_gi_importer_handle_enum (JSContextRef ctx, - JSObjectRef namespace_ref, +static JSValueRef +seed_gi_importer_handle_enum (JSContextRef ctx, GIEnumInfo * info, JSValueRef * exception) { JSObjectRef enum_class; @@ -130,9 +132,9 @@ seed_gi_importer_handle_enum (JSContextRef ctx, enum_class = JSObjectMake (ctx, 0, 0); num_vals = g_enum_info_get_n_values (info); - seed_object_set_property (ctx, namespace_ref, - g_base_info_get_name ((GIBaseInfo *) info), - enum_class); + //seed_object_set_property (ctx, namespace_ref, + // g_base_info_get_name ((GIBaseInfo *) info), + // enum_class); for (i = 0; i < num_vals; i++) { @@ -158,6 +160,7 @@ seed_gi_importer_handle_enum (JSContextRef ctx, g_base_info_unref ((GIBaseInfo *) val); } + return enum_class; } /* @@ -165,78 +168,81 @@ seed_gi_importer_handle_enum (JSContextRef ctx, * Namespace.Type will be the constructor and Namespace.Type.prototype is * the prototype object. Namespace.Type.type will be the GType. */ -static void -seed_gi_importer_handle_object (JSContextRef ctx, - JSObjectRef namespace_ref, +static JSValueRef +seed_gi_importer_handle_object (JSContextRef ctx, GIObjectInfo * info, JSValueRef * exception) { GType type; JSClassRef class_ref; + //JSValueRef ret; + type = g_registered_type_info_get_g_type ((GIRegisteredTypeInfo *) info); - if (type != 0) - { - GIFunctionInfo *finfo; - GIFunctionInfoFlags flags; - JSObjectRef constructor_ref; - guint i, n_methods; + if (type == 0) { + return NULL; + } - class_ref = seed_gobject_get_class_for_gtype (ctx, type); - constructor_ref = - JSObjectMake (ctx, gobject_constructor_class, (gpointer) type); + GIFunctionInfo *finfo; + GIFunctionInfoFlags flags; + JSObjectRef constructor_ref; + guint i, n_methods; - seed_object_set_property (ctx, constructor_ref, - "type", - seed_value_from_long (ctx, type, exception)); - n_methods = g_object_info_get_n_methods (info); - for (i = 0; i < n_methods; i++) - { - finfo = g_object_info_get_method (info, i); - flags = g_function_info_get_flags (finfo); - if (flags & GI_FUNCTION_IS_CONSTRUCTOR) - { - JSObjectRef constructor = JSObjectMake (ctx, - gobject_named_constructor_class, - finfo); - const gchar *fname = - g_base_info_get_name ((GIBaseInfo *) finfo); - if (g_strrstr (fname, "new_") == fname) - fname += 4; - else if (!g_strcmp0 (fname, "new")) - fname = "c_new"; - - seed_object_set_property (ctx, - constructor_ref, fname, constructor); - } - else if (!(flags & GI_FUNCTION_IS_METHOD)) - { - seed_gobject_define_property_from_function_info - (ctx, finfo, constructor_ref, FALSE); - } - else - { - g_base_info_unref ((GIBaseInfo *) finfo); - } - } + class_ref = seed_gobject_get_class_for_gtype (ctx, type); + + constructor_ref = + JSObjectMake (ctx, gobject_constructor_class, (gpointer) type); - seed_object_set_property (ctx, namespace_ref, - g_base_info_get_name ((GIBaseInfo *) info), - constructor_ref); - seed_object_set_property (ctx, constructor_ref, - "prototype", - seed_gobject_get_prototype_for_gtype (type)); + seed_object_set_property (ctx, constructor_ref, + "type", + seed_value_from_long (ctx, type, exception)); + n_methods = g_object_info_get_n_methods (info); + for (i = 0; i < n_methods; i++) + { + finfo = g_object_info_get_method (info, i); + flags = g_function_info_get_flags (finfo); + if (flags & GI_FUNCTION_IS_CONSTRUCTOR) + { + JSObjectRef constructor = JSObjectMake (ctx, + gobject_named_constructor_class, + finfo); + const gchar *fname = + g_base_info_get_name ((GIBaseInfo *) finfo); + if (g_strrstr (fname, "new_") == fname) + fname += 4; + else if (!g_strcmp0 (fname, "new")) + fname = "c_new"; + + seed_object_set_property (ctx, + constructor_ref, fname, constructor); } + else if (!(flags & GI_FUNCTION_IS_METHOD)) + { + seed_gobject_define_property_from_function_info + (ctx, finfo, constructor_ref, FALSE); + } + else + { + g_base_info_unref ((GIBaseInfo *) finfo); + } + } + // sets up imports.gi.Gtk.Window << + + seed_object_set_property (ctx, constructor_ref, + "prototype", + seed_gobject_get_prototype_for_gtype (type)); + + return (JSValueRef) constructor_ref; + } /* * Set up prototype and constructor for structs. Same semantics as objects except * for the type. */ -static void +static JSValueRef seed_gi_importer_handle_struct (JSContextRef ctx, - JSObjectRef namespace_ref, GIStructInfo * info, JSValueRef * exception) { JSObjectRef struct_ref; @@ -279,14 +285,15 @@ seed_gi_importer_handle_struct (JSContextRef ctx, proto = seed_struct_prototype (ctx, (GIBaseInfo *) info); seed_object_set_property (ctx, struct_ref, "prototype", proto); - seed_object_set_property (ctx, namespace_ref, + return struct_ref; + /*seed_object_set_property (ctx, namespace_ref, g_base_info_get_name ((GIBaseInfo *) info), struct_ref); + */ } -static void +static JSValueRef seed_gi_importer_handle_union (JSContextRef ctx, - JSObjectRef namespace_ref, GIUnionInfo * info, JSValueRef * exception) { JSObjectRef union_ref; @@ -315,32 +322,31 @@ seed_gi_importer_handle_union (JSContextRef ctx, proto = seed_union_prototype (ctx, (GIBaseInfo *) info); seed_object_set_property (ctx, union_ref, "prototype", proto); - - seed_object_set_property (ctx, namespace_ref, - g_base_info_get_name ((GIBaseInfo *) info), - union_ref); + return union_ref; + //seed_object_set_property (ctx, namespace_ref, +// g_base_info_get_name ((GIBaseInfo *) info), + // union_ref); } -static void +static JSValueRef seed_gi_importer_handle_callback (JSContextRef ctx, - JSObjectRef namespace_ref, GICallbackInfo * info, JSValueRef * exception) { JSObjectRef callback_ref = JSObjectMake (ctx, seed_callback_class, info); - seed_object_set_property (ctx, namespace_ref, - g_base_info_get_name ((GIBaseInfo *) info), - (JSValueRef) callback_ref); + return callback_ref; + // seed_object_set_property (ctx, namespace_ref, +// g_base_info_get_name ((GIBaseInfo *) info), +// (JSValueRef) callback_ref); } /* * Define constants toplevel. Uses the casing as in the typelib */ -static void +static JSValueRef seed_gi_importer_handle_constant (JSContextRef ctx, - JSObjectRef namespace_ref, GIConstantInfo * info, JSValueRef * exception) { @@ -351,11 +357,14 @@ seed_gi_importer_handle_constant (JSContextRef ctx, g_constant_info_get_value (info, &argument); constant_value = seed_value_from_gi_argument (ctx, &argument, constant_type, exception); - seed_object_set_property (ctx, namespace_ref, - g_base_info_get_name ((GIBaseInfo *) info), - constant_value); +g_base_info_unref ((GIBaseInfo *) constant_type); + return constant_value; + + //seed_object_set_property (ctx, namespace_ref, + // g_base_info_get_name ((GIBaseInfo *) info), + // constant_value); - g_base_info_unref ((GIBaseInfo *) constant_type); + } static gchar * @@ -373,6 +382,13 @@ seed_gi_importer_get_version (JSContextRef ctx, return version; } +/** + * original code creates a huge object, when even a large namespace is pulled in. + * let's try and create a fake object, representing the namespace, + * and see what happens + * + */ + JSObjectRef seed_gi_importer_do_namespace (JSContextRef ctx, gchar * namespace, JSValueRef * exception) @@ -380,7 +396,6 @@ seed_gi_importer_do_namespace (JSContextRef ctx, GIBaseInfo *info; JSObjectRef namespace_ref; GError *e = NULL; - guint n, i; gchar *version = NULL; gchar *jsextension; JSStringRef extension_script; @@ -397,6 +412,7 @@ seed_gi_importer_do_namespace (JSContextRef ctx, if (gi_importer_versions != NULL) version = seed_gi_importer_get_version (ctx, namespace, exception); + if (!g_irepository_require (NULL, namespace, version, 0, &e)) { seed_make_exception_from_gerror (ctx, exception, e); @@ -407,6 +423,16 @@ seed_gi_importer_do_namespace (JSContextRef ctx, if (version != NULL) g_free (version); + // at this point we have loaded the namespace (eg. proved it exists) + namespace_ref = JSObjectMake (ctx, gi_importer_namespace, + g_strdup (namespace)); + + SEED_NOTE (IMPORTER, "Constructing namespace ref (%p) for %s", + namespace_ref, namespace); + + JSValueProtect (ctx, namespace_ref); + + /* n = g_irepository_get_n_infos (NULL, namespace); namespace_ref = JSObjectMake (ctx, NULL, NULL); @@ -461,9 +487,13 @@ seed_gi_importer_do_namespace (JSContextRef ctx, } g_base_info_unref (info); } - +*/ + // store it for quick lookup + g_hash_table_insert (gi_imports, g_strdup (namespace), namespace_ref); + // run a specific extension relating to this namespace.. + jsextension = g_strdup_printf ("imports.extensions.%s", namespace); extension_script = JSStringCreateWithUTF8CString (jsextension); JSEvaluateScript (ctx, extension_script, NULL, NULL, 0, exception); @@ -476,6 +506,117 @@ seed_gi_importer_do_namespace (JSContextRef ctx, } static JSValueRef +seed_gi_importer_namespace_get_property (JSContextRef ctx, + JSObjectRef object, + JSStringRef property_name, + JSValueRef * exception) +{ + JSObjectRef ret; + guint len; + gchar *prop; + gchar * namespace; + guint n, i; + GIBaseInfo *info; + + //what prop are we trying to get... + len = JSStringGetMaximumUTF8CStringSize (property_name); + prop = g_alloca (len * sizeof (gchar)); + JSStringGetUTF8CString (property_name, prop, len); + + // what are we trying to get it from + namespace = (gchar*) JSObjectGetPrivate (object); + + SEED_NOTE (IMPORTER, "seed_gi_importer_namespace_get_property %s::%s", + namespace, prop); + + + n = g_irepository_get_n_infos (NULL, namespace); + + ret = NULL; + + for (i = 0; i < n; i++) + { + GIInfoType info_type; + + info = g_irepository_get_info (NULL, namespace, i); + info_type = g_base_info_get_type (info); + // does the name need freeing??? + //info_name = if (g_strcmp0 (g_base_info_get_name ((GIBaseInfo *) info), "init")) + + if (g_strcmp0 (g_base_info_get_name ((GIBaseInfo *) info), prop)) { + g_base_info_unref (info); + continue; + } + + switch (info_type) + { + case GI_INFO_TYPE_FUNCTION: + SEED_NOTE (IMPORTER, "seed_gi_importer_namespace_get_property %s::%s :: is a function", + namespace, prop); + + ret = seed_gi_importer_handle_function (ctx, (GIFunctionInfo *) info, + exception); + + + break; + case GI_INFO_TYPE_ENUM: + case GI_INFO_TYPE_FLAGS: + SEED_NOTE (IMPORTER, "seed_gi_importer_namespace_get_property %s::%s :: is a enum/flag", + namespace, prop); + + ret = seed_gi_importer_handle_enum (ctx, + (GIEnumInfo *) info, exception); + + g_base_info_unref (info); + return ret; + + break; + case GI_INFO_TYPE_OBJECT: + ret = seed_gi_importer_handle_object (ctx, + (GIObjectInfo *) info, exception); + break; + case GI_INFO_TYPE_STRUCT: + SEED_NOTE (IMPORTER, "seed_gi_importer_namespace_get_property %s::%s :: is a struct", + namespace, prop); + + ret = seed_gi_importer_handle_struct (ctx, + (GIStructInfo *) info, exception); + break; + case GI_INFO_TYPE_UNION: + SEED_NOTE (IMPORTER, "seed_gi_importer_namespace_get_property %s::%s :: is a union", + namespace, prop); + + ret = seed_gi_importer_handle_union (ctx, + (GIUnionInfo *) info, exception); + + break; + case GI_INFO_TYPE_CALLBACK: + SEED_NOTE (IMPORTER, "seed_gi_importer_namespace_get_property %s::%s :: is a callback", + namespace, prop); + + ret = seed_gi_importer_handle_callback (ctx, + (GICallbackInfo *) info, + exception); + break; + case GI_INFO_TYPE_CONSTANT: + SEED_NOTE (IMPORTER, "seed_gi_importer_namespace_get_property %s::%s :: is a constant", + namespace, prop); + + ret = seed_gi_importer_handle_constant (ctx, + (GIConstantInfo *) info, + exception); + break; + default: + break; + } + g_base_info_unref (info); + } + + return ret; + +} + +static JSValueRef seed_gi_importer_get_property (JSContextRef ctx, JSObjectRef object, JSStringRef property_name, @@ -1040,6 +1181,28 @@ JSClassDefinition gi_importer_class_def = { NULL /* Convert To Type */ }; +JSClassDefinition gi_importer_namespace_def = { + 0, /* Version, always 0 */ + 0, + "gi_namespace_importer", /* Class Name */ + NULL, /* Parent Class */ + NULL, /* Static Values */ + NULL, /* Static Functions */ + NULL, /* Initialize */ + NULL, /* Finalize */ + NULL, /* Has Property */ + seed_gi_importer_namespace_get_property, /* Get Property */ + NULL, /* Set Property */ + NULL, /* Delete Property */ + NULL, /* Get Property Names */ + NULL, /* Call As Function */ + NULL, /* Call As Constructor */ + NULL, /* Has Instance */ + NULL /* Convert To Type */ +}; + + + JSClassDefinition importer_dir_class_def = { 0, /* Version, always 0 */ 0, @@ -1075,6 +1238,10 @@ seed_initialize_importer (JSContextRef ctx, JSObjectRef global) JSValueProtect (ctx, gi_importer); JSValueProtect (ctx, gi_importer_versions); + gi_importer_namespace = JSClassCreate (&gi_importer_namespace_def); + //JSValueProtect (ctx, gi_importer_namespace); + + importer_dir_class = JSClassCreate (&importer_dir_class_def); gi_imports = g_hash_table_new (g_str_hash, g_str_equal); diff --git a/libseed/seed-types.c b/libseed/seed-types.c index 5f17d9b..e68ab89 100644 --- a/libseed/seed-types.c +++ b/libseed/seed-types.c @@ -45,6 +45,10 @@ seed_toggle_ref (gpointer data, GObject * object, gboolean is_last_ref) if (!g_object_get_data (object, "js-ref")) return; + SEED_NOTE (MISC, + "seed_toggle_ref %d", is_last_ref ? 1 : 0); + + wrapper = (JSValueRef) data; if (is_last_ref) @@ -60,6 +64,9 @@ seed_toggle_ref (gpointer data, GObject * object, gboolean is_last_ref) static void seed_gobject_destroyed (gpointer object) { +SEED_NOTE (MISC, + "seed_gobject_destroyed "); + JSValueUnprotect (eng->context, (JSValueRef) object); JSObjectSetPrivate ((JSObjectRef) object, 0); } @@ -110,7 +117,7 @@ seed_wrap_object (JSContextRef ctx, GObject * object) g_object_set_qdata_full (object, js_ref_quark, (gpointer) js_ref, seed_gobject_destroyed); - JSValueProtect (eng->context, js_ref); + //JSValueProtect (eng->context, js_ref); g_object_add_toggle_ref (object, seed_toggle_ref, (gpointer) js_ref); seed_add_signals_to_object (ctx, js_ref, object); seed-webkit2-4.0.0+20161014+6c77960+dfsg1/patches/000077500000000000000000000000001303774616400202555ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/patches/gir-repo-gtktreemodel-get-value.patch000066400000000000000000000012701303774616400273750ustar00rootroot00000000000000From 205c9b9fe98b51a03b3541ec40283337e4a689b1 Mon Sep 17 00:00:00 2001 From: Tim Horton Date: Thu, 18 Jun 2009 18:54:58 -0400 Subject: [PATCH] Add annotation for gtk_tree_model_get_value's out argument --- gir/Gtk-custom.c | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-) diff --git a/gir/Gtk-custom.c b/gir/Gtk-custom.c index 16e3ce3..f7c187d 100644 --- a/gir/Gtk-custom.c +++ b/gir/Gtk-custom.c @@ -1394,6 +1394,13 @@ gtk_dialog_get_vbox(GtkDialog *dialog) */ /** + * gtk_tree_model_get_value: + * @iter: + * @column: + * @value: (out) (transfer none): + */ + +/** * gtk_tree_model_iter_children: * @parent: (allow-none): */ -- 1.6.3.2 seed-webkit2-4.0.0+20161014+6c77960+dfsg1/po/000077500000000000000000000000001303774616400172445ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/po/.cvsignore000066400000000000000000000003111303774616400212370ustar00rootroot00000000000000.libs .deps .*swp .nautilus-metafile.xml *.autosave *.gmo *.mo *.pot *~ #*# *.bak *.o *.lo *.la cat-id-tbl.c stamp-cat-id messages missing POTFILES Makefile Makefile.in Makefile.in.in translations.xml seed-webkit2-4.0.0+20161014+6c77960+dfsg1/po/ChangeLog000066400000000000000000000000001303774616400210040ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/po/LINGUAS000066400000000000000000000000601303774616400202650ustar00rootroot00000000000000# please keep this list sorted alphabetically # seed-webkit2-4.0.0+20161014+6c77960+dfsg1/po/POTFILES.in000066400000000000000000000001041303774616400210140ustar00rootroot00000000000000# List of source files containing translatable strings. src/main.c seed-webkit2-4.0.0+20161014+6c77960+dfsg1/po/POTFILES.skip000066400000000000000000000000441303774616400213570ustar00rootroot00000000000000examples/clutter-pad/clutter-pad.ui seed-webkit2-4.0.0+20161014+6c77960+dfsg1/seed.doap000066400000000000000000000036541303774616400204230ustar00rootroot00000000000000 Seed Seed GNOME WebKit Javascript bindings GNOME WebKit Javascript bindings C JavaScript Robert Carr racarr Tim Horton hortont Alan Knowles alank Danilo Cesar Lemes de Paula danilocesar seed-webkit2-4.0.0+20161014+6c77960+dfsg1/seed.pc.in000066400000000000000000000005431303774616400205010ustar00rootroot00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ bindir=@bindir@ includedir=@includedir@ Cflags: -I${includedir}/seed@SEED_GTK_VERSION@ Requires: @WEBKIT_PC@ gobject-introspection-1.0 glib-2.0 gobject-2.0 gmodule-2.0 gthread-2.0 Libs: -L${libdir} -lseed@SEED_GTK_VERSION@ Name: Seed Description: Seed Javascript Interpreter. Version: @VERSION@ seed-webkit2-4.0.0+20161014+6c77960+dfsg1/src/000077500000000000000000000000001303774616400174155ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/src/.cvsignore000066400000000000000000000002041303774616400214110ustar00rootroot00000000000000.libs .deps .*swp .nautilus-metafile.xml *.autosave *.bak *~ #*# *.gladep *.la *.lo *.o *.class *.pyc *.plugin Makefile Makefile.in seed-webkit2-4.0.0+20161014+6c77960+dfsg1/src/Makefile.am000066400000000000000000000011371303774616400214530ustar00rootroot00000000000000## Process this file with automake to produce Makefile.in bin_PROGRAMS = seed seed_SOURCES = \ main.c \ args.c seed_CFLAGS = \ -DPACKAGE_LOCALE_DIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \ -DPACKAGE_SRC_DIR=\""$(srcdir)"\" \ -DPACKAGE_DATA_DIR=\""$(datadir)"\" \ -Wall \ $(SEED_DEBUG_CFLAGS) \ $(SEED_PROFILE_CFLAGS) \ $(GOBJECT_INTROSPECTION_CFLAGS) \ $(WEBKIT_CFLAGS) seed_LDFLAGS = \ $(SEED_PROFILE_LIBS) \ $(LIBFFI_LDFLAGS) \ $(GOBJECT_INTROSPECTION_LDFLAGS) \ $(WEBKIT_LDFLAGS) \ $(GTHREAD_LIBS) seed_LDADD = \ ../libseed/libseed@SEED_GTK_VERSION@.la -include $(top_srcdir)/git.mk seed-webkit2-4.0.0+20161014+6c77960+dfsg1/src/args.c000066400000000000000000000051541303774616400205220ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #include #include #include #include "../libseed/seed.h" #include "../libseed/seed-debug.h" #include #include "config.h" extern gboolean seed_interpreter_arg_print_version; extern gchar* seed_interpreter_arg_exec_string; static GOptionEntry seed_args[] = { { "version", 0, 0, G_OPTION_ARG_NONE, &seed_interpreter_arg_print_version, "Print interpreter version", 0 }, { "execute", 'e', 0, G_OPTION_ARG_STRING, &seed_interpreter_arg_exec_string, "Pass program in as string", "expression" }, { NULL, }, }; static GOptionGroup* seed_interpreter_get_option_group(void) { GOptionGroup* group; group = g_option_group_new("seed-interpreter", "Interpreter Options", "Show Interpreter Options", NULL, NULL); g_option_group_add_entries(group, seed_args); return group; } gboolean seed_interpreter_parse_args(int* argc, char*** argv) { GOptionContext* option_context; GOptionGroup* interpreter_group; GError* error = NULL; gboolean ret = TRUE; option_context = g_option_context_new(NULL); g_option_context_set_ignore_unknown_options(option_context, TRUE); g_option_context_set_help_enabled(option_context, TRUE); /* Initiate any command line options from the backend */ interpreter_group = seed_interpreter_get_option_group(); g_option_context_set_main_group(option_context, interpreter_group); g_option_context_add_group(option_context, seed_get_option_group()); if (!g_option_context_parse(option_context, argc, argv, &error)) { if (error) { g_warning("%s", error->message); g_error_free(error); } ret = FALSE; } g_option_context_free(option_context); return ret; } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/src/main.c000066400000000000000000000075311303774616400205130ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #include #include #include #include "../libseed/seed.h" #include "../libseed/seed-debug.h" #include #include "config.h" #define DEFAULT_PATH "." SeedEngine* eng; gboolean seed_interpreter_arg_print_version; gchar* seed_interpreter_arg_exec_string; gboolean seed_interpreter_parse_args(int* argc, char*** argv); static void seed_repl() { SeedScript* script; SeedException e; script = seed_make_script(eng->context, "repl = imports.repl", NULL, 0); if ((e = seed_script_exception(script))) { g_critical("%s", seed_exception_to_string(eng->context, e)); exit(EXIT_FAILURE); } seed_evaluate(eng->context, script, 0); if ((e = seed_script_exception(script))) { g_critical("%s", seed_exception_to_string(eng->context, e)); exit(EXIT_FAILURE); } g_free(script); } static void seed_exec(gchar* filename) { SeedObject global; SeedScript* script; SeedException e; gchar* buffer; g_file_get_contents(filename, &buffer, 0, 0); if (!buffer) { g_critical("File %s not found!", filename); exit(EXIT_FAILURE); } if (*buffer == '#') { while (*buffer != '\n') buffer++; buffer++; } script = seed_make_script(eng->context, buffer, filename, 1); if ((e = seed_script_exception(script))) { g_critical("%s", seed_exception_to_string(eng->context, e)); exit(EXIT_FAILURE); } global = seed_context_get_global_object(eng->context); seed_importer_add_global(global, filename); seed_evaluate(eng->context, script, 0); if ((e = seed_script_exception(script))) { g_critical("%s", seed_exception_to_string(eng->context, e)); exit(EXIT_FAILURE); } g_free(script); } static void seed_exec_str() { SeedException e = NULL; SeedValue val; gchar* val_str; val = seed_simple_evaluate(eng->context, seed_interpreter_arg_exec_string, &e); if (e) { g_critical("%s", seed_exception_to_string(eng->context, e)); exit(EXIT_FAILURE); } else { val_str = seed_value_to_string(eng->context, val, &e); if (e) { g_critical("%s", seed_exception_to_string(eng->context, e)); exit(EXIT_FAILURE); } g_print("%s\n", val_str); g_free(seed_interpreter_arg_exec_string); g_free(val_str); exit(EXIT_SUCCESS); } } gint main(gint argc, gchar** argv) { g_set_prgname("seed"); #if !GLIB_CHECK_VERSION(2, 32, 0) g_thread_init(NULL); #endif seed_interpreter_parse_args(&argc, &argv); if (seed_interpreter_arg_print_version) { g_print("%s\n", "Seed " VERSION); exit(EXIT_SUCCESS); } eng = seed_init(&argc, &argv); seed_engine_set_search_path(eng, DEFAULT_PATH); if (seed_interpreter_arg_exec_string) seed_exec_str(); else if (argc == 1) seed_repl(); else seed_exec(argv[1]); return EXIT_SUCCESS; } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/000077500000000000000000000000001303774616400177705ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/COPYING000066400000000000000000000001031303774616400210150ustar00rootroot00000000000000Any code in these tests is to be considered under the MIT license. seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/Makefile.am000066400000000000000000000001141303774616400220200ustar00rootroot00000000000000SUBDIRS = javascript c EXTRA_DIST = COPYING -include $(top_srcdir)/git.mk seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/c/000077500000000000000000000000001303774616400202125ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/c/Makefile.am000066400000000000000000000020571303774616400222520ustar00rootroot00000000000000TESTS_ENVIRONMENT = \ GI_TYPELIB_PATH=$(top_builddir)/libgjs-private:$$GI_TYPELIB_PATH \ LD_LIBRARY_PATH=$(top_builddir)/libgjs-private/.libs:$$LD_LIBRARY_PATH \ SEED_MODULE_PATH=$(top_srcdir)/modules:$$SEED_MODULE_PATH \ $(NULL) noinst_PROGRAMS = TESTS = noinst_PROGRAMS += test test-module-whitelist TESTS += test test-module-whitelist test_SOURCES = \ main.c \ basic.c \ api-types.c \ api-closure.c \ api-js-signal-from-c.c \ $(NULL) test_CFLAGS = \ -Wall \ $(GOBJECT_INTROSPECTION_CFLAGS) test_LDFLAGS = \ $(GOBJECT_INTROSPECTION_LIBS) test_LDADD = \ ../../libseed/libseed@SEED_GTK_VERSION@.la noinst_PROGRAMS += test-module-whitelist TESTS += test-module-whitelist test_module_whitelist_SOURCES = \ test-module-whitelist.c \ $(NULL) test_module_whitelist_CFLAGS = \ -Wall \ $(GOBJECT_INTROSPECTION_CFLAGS) test_module_whitelist_LDFLAGS = \ $(GOBJECT_INTROSPECTION_LIBS) test_module_whitelist_LDADD = \ ../../libseed/libseed@SEED_GTK_VERSION@.la EXTRA_DIST = \ test-common.h -include $(top_srcdir)/git.mk seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/c/api-closure.c000066400000000000000000000051701303774616400226040ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #include "../../libseed/seed.h" #include "test-common.h" SeedValue do_some_math(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException* exception) { g_assert(argument_count == 4); guint a = seed_value_to_uint(ctx, arguments[0], NULL); gdouble b = seed_value_to_int(ctx, arguments[1], NULL); gint c = seed_value_to_int(ctx, arguments[2], NULL); gchar* d = seed_value_to_string(ctx, arguments[3], NULL); g_assert(d[0] == 'a'); return seed_value_from_double(ctx, (a + b) / c, NULL); } void closures(TestSimpleFixture* fixture, gconstpointer _data) { TestSharedState* state = (TestSharedState*) _data; seed_create_function(state->eng->context, "do_some_math", (SeedFunctionCallback) do_some_math, (SeedObject) state->eng->global); SeedValue* val = seed_simple_evaluate(state->eng->context, "do_some_math(5, 8.66, -2, 'a')", NULL); g_assert(seed_value_to_double(state->eng->context, val, NULL) == -6.5); SeedObject* dsm_obj = seed_object_get_property(state->eng->context, (SeedObject) state->eng->global, "do_some_math"); SeedValue args[4]; args[0] = seed_value_from_uint(state->eng->context, 5, NULL); args[1] = seed_value_from_double(state->eng->context, 8.66, NULL); args[2] = seed_value_from_int(state->eng->context, -2, NULL); args[3] = seed_value_from_string(state->eng->context, "a", NULL); val = seed_object_call(state->eng->context, dsm_obj, NULL, 4, args, NULL); g_assert(seed_value_to_double(state->eng->context, val, NULL) == -6.5); } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/c/api-js-signal-from-c.c000066400000000000000000000044611303774616400242020ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #include "../../libseed/seed.h" #include "test-common.h" #include gdouble hello_cb(gpointer w, gint a, gchar* b) { g_assert(a == 2); g_assert(strncmp(b, "Test", 4) == 0); return 5.12; } void js_signal_from_c(TestSimpleFixture* fixture, gconstpointer _data) { TestSharedState* state = (TestSharedState*) _data; SeedValue* val = seed_simple_evaluate( state->eng->context, "Gtk = imports.gi.Gtk;" "GObject = imports.gi.GObject;" "Gtk.init(null, null);" "HelloWindowType = {" " parent: Gtk.Window.type," " name: \"HelloWindow\"," " class_init: function(klass, prototype)" " {" " var HelloSignalDefinition = {name: \"hello\"," " " "parameters: [GObject.TYPE_INT," " " " GObject.TYPE_STRING]," " " "return_type: GObject.TYPE_DOUBLE};" " hello_signal_id = klass.install_signal(HelloSignalDefinition);" " }," " init: function(instance)" " {" " }};" "HelloWindow = new GType(HelloWindowType);" "w = new HelloWindow();", NULL); GObject* obj = seed_value_to_object(state->eng->context, val, NULL); g_signal_connect(obj, "hello", G_CALLBACK(hello_cb), NULL); val = seed_simple_evaluate(state->eng->context, "g = w.signal.hello.emit(2,'Test')", NULL); g_assert(seed_value_to_double(state->eng->context, val, NULL) == 5.12); } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/c/api-types.c000066400000000000000000000125011303774616400222700ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #include "../../libseed/seed.h" #include "test-common.h" #include // The biggest problem here is everything gets cast to a double in JSCore! void basic_types(TestSimpleFixture* fixture, gconstpointer _data) { // bool to/from JS equality gboolean bool_test_in = TRUE; SeedValue* bool_test = seed_value_from_boolean(fixture->context, bool_test_in, NULL); gboolean bool_test_out = seed_value_to_boolean(fixture->context, bool_test, NULL); g_assert(bool_test_in == bool_test_out); // uint to/from JS equality guint uint_test_in = 2946623; SeedValue* uint_test = seed_value_from_uint(fixture->context, uint_test_in, NULL); guint uint_test_out = seed_value_to_uint(fixture->context, uint_test, NULL); g_assert(uint_test_in == uint_test_out); // int to/from JS equality gint int_test_in = -54374; SeedValue* int_test = seed_value_from_int(fixture->context, int_test_in, NULL); gint int_test_out = seed_value_to_int(fixture->context, int_test, NULL); g_assert(int_test_in == int_test_out); // char to/from JS equality gchar char_test_in = -126; SeedValue* char_test = seed_value_from_char(fixture->context, char_test_in, NULL); gchar char_test_out = seed_value_to_char(fixture->context, char_test, NULL); g_assert(char_test_in == char_test_out); // uchar to/from JS equality guchar uchar_test_in = 250; SeedValue* uchar_test = seed_value_from_uchar(fixture->context, uchar_test_in, NULL); guchar uchar_test_out = seed_value_to_uchar(fixture->context, uchar_test, NULL); g_assert(uchar_test_in == uchar_test_out); // long to/from JS equality glong long_test_in = -454250; SeedValue* long_test = seed_value_from_long(fixture->context, long_test_in, NULL); glong long_test_out = seed_value_to_long(fixture->context, long_test, NULL); g_assert(long_test_in == long_test_out); // ulong to/from JS equality gulong ulong_test_in = 250; SeedValue* ulong_test = seed_value_from_ulong(fixture->context, ulong_test_in, NULL); gulong ulong_test_out = seed_value_to_ulong(fixture->context, ulong_test, NULL); g_assert(ulong_test_in == ulong_test_out); // int64 to/from JS equality gint64 int64_test_in = -54374; SeedValue* int64_test = seed_value_from_int64(fixture->context, int64_test_in, NULL); gint64 int64_test_out = seed_value_to_int64(fixture->context, int64_test, NULL); g_assert(int64_test_in == int64_test_out); // uint64 to/from JS equality guint64 uint64_test_in = 2946623; SeedValue* uint64_test = seed_value_from_uint64(fixture->context, uint64_test_in, NULL); guint64 uint64_test_out = seed_value_to_uint64(fixture->context, uint64_test, NULL); g_assert(uint64_test_in == uint64_test_out); // float to/from JS equality gfloat float_test_in = 1.618; SeedValue* float_test = seed_value_from_float(fixture->context, float_test_in, NULL); gfloat float_test_out = seed_value_to_float(fixture->context, float_test, NULL); g_assert(float_test_in == float_test_out); // double to/from JS equality gdouble double_test_in = 1.6134857638; SeedValue* double_test = seed_value_from_double(fixture->context, double_test_in, NULL); gdouble double_test_out = seed_value_to_double(fixture->context, double_test, NULL); g_assert(double_test_in == double_test_out); // string to/from JS equality gchar* string_test_in = "Hello, world!"; SeedValue* string_test = seed_value_from_string(fixture->context, string_test_in, NULL); gchar* string_test_out = seed_value_to_string(fixture->context, string_test, NULL); g_assert(strncmp(string_test_in, string_test_out, strlen(string_test_in)) == 0); // filename to/from JS equality gchar* filename_test_in = "/bin"; SeedValue* filename_test = seed_value_from_filename(fixture->context, filename_test_in, NULL); gchar* filename_test_out = seed_value_to_filename(fixture->context, filename_test, NULL); g_assert( strncmp(filename_test_in, filename_test_out, strlen(filename_test_in)) == 0); SeedValue si[2]; si[0] = seed_value_from_string(fixture->context, "Hi", NULL); si[1] = seed_value_from_int(fixture->context, 1, NULL); gint ni; gchar* ns; seed_value_to_format(fixture->context, "si", si, NULL, &ns, &ni, NULL); g_assert(ni == 1); g_assert(!strcmp(ns, "Hi")); } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/c/basic.c000066400000000000000000000017451303774616400214460ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #include "../../libseed/seed.h" #include "test-common.h" void basic(TestSimpleFixture* fixture, gconstpointer _data) { g_assert(1); } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/c/main.c000066400000000000000000000044041303774616400213040ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright (C) Robert Carr 2009 */ #include "../../libseed/seed.h" #include #include "test-common.h" // Test stuff stolen from Clutter #define TEST_SIMPLE(NAMESPACE, FUNC) \ extern void FUNC(TestSimpleFixture* fixture, gconstpointer data); \ g_test_add(NAMESPACE "/" #FUNC, TestSimpleFixture, shared_state, \ test_simple_fixture_setup, FUNC, test_simple_fixture_teardown); void test_simple_fixture_setup(TestSimpleFixture* fixture, gconstpointer data) { TestSharedState* state = (TestSharedState*) data; fixture->context = seed_context_create(state->eng->group, NULL); } void test_simple_fixture_teardown(TestSimpleFixture* fixture, gconstpointer data) { seed_context_unref(fixture->context); } int main(int argc, char** argv) { TestSharedState* shared_state = g_new0(TestSharedState, 1); const gchar* display = g_getenv("DISPLAY"); if (!display || *display == '\0') { g_print("No DISPLAY found. Unable to run the test suite without X11."); return EXIT_SUCCESS; } g_test_init(&argc, &argv, NULL); SeedEngine* eng = seed_init(NULL, NULL); shared_state->argc_addr = &argc; shared_state->argv_addr = &argv; shared_state->eng = eng; TEST_SIMPLE("/", basic); TEST_SIMPLE("/", closures); TEST_SIMPLE("/types/", basic_types); TEST_SIMPLE("/js-signal-from-c/", js_signal_from_c); return g_test_run(); } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/c/test-common.h000066400000000000000000000011451303774616400226310ustar00rootroot00000000000000 /* Stuff you put in here is setup once in main() and gets passed around to * all test functions and fixture setup/teardown functions in the data * argument */ typedef struct _TestSharedState { int* argc_addr; char*** argv_addr; SeedEngine* eng; } TestSharedState; /* This fixture structure is allocated by glib, and before running each test * the test_conform_simple_fixture_setup func (see below) is called to * initialise it, and test_conform_simple_fixture_teardown is called when * the test is finished. */ typedef struct _TestSimpleFixture { SeedContext* context; } TestSimpleFixture; seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/c/test-module-whitelist.c000066400000000000000000000121641303774616400246360ustar00rootroot00000000000000/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */ /* * This file is part of Seed, the GObject Introspection<->Javascript bindings. * * Seed is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * Seed 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with Seed. If not, see . * * Copyright © 2016 Robert Bosch Car Multimedia GmbH */ #include "../../libseed/seed.h" static void test_module_whitelist(void) { SeedEngine* engine; SeedValue* val; SeedException exception = NULL; engine = seed_init_constrained(NULL, NULL); /* In the initial state, the engine is completely sandboxed */ val = seed_simple_evaluate(engine->context, "Os = imports.os;", &exception); g_assert(val == NULL); g_assert_cmpstr(seed_exception_get_message(engine->context, exception), ==, "Can't find variable: imports"); exception = NULL; /* Even printing is impossible */ val = seed_simple_evaluate(engine->context, "print (\"Hello world!\");", &exception); g_assert(val == NULL); g_assert_cmpstr(seed_exception_get_message(engine->context, exception), ==, "Can't find variable: print"); exception = NULL; /* Let's fix that */ seed_init_builtins(engine, NULL, NULL); val = seed_simple_evaluate(engine->context, "print (\"Hello world!\");", &exception); g_assert(val != NULL); g_assert(exception == NULL); /* imports is not a builtin, and thus should not yet be available */ val = seed_simple_evaluate(engine->context, "Os = imports.os;", &exception); g_assert(val == NULL); g_assert_cmpstr(seed_exception_get_message(engine->context, exception), ==, "Can't find variable: imports"); exception = NULL; /* Let's fix that */ seed_engine_initialize_importer(engine); val = seed_simple_evaluate(engine->context, "Os = imports.os;", &exception); g_assert(exception == NULL); g_assert(val != NULL); /* As imports is now available, seed doesn't raise an exception anymore, * however as the search path for modules is currently empty, the type of * val should be undefined. */ g_assert(seed_value_get_type(engine->context, val) == SEED_TYPE_UNDEFINED); /* Let's update the search path, this is set in Makefile.am * to an uninstalled location which is guaranteed to contain an * os module */ { const gchar* env_paths = g_getenv("SEED_MODULE_PATH"); g_assert(env_paths != NULL); gchar** paths = g_strsplit(env_paths, ":", -1); seed_importer_set_search_path(engine->context, paths); g_strfreev(paths); } val = seed_simple_evaluate(engine->context, "Os = imports.os;", &exception); g_assert(exception == NULL); g_assert(val != NULL); /* imports.os is no longer undefined, but an actual object */ g_assert(seed_value_get_type(engine->context, val) == SEED_TYPE_OBJECT); /* We're now less sandboxed, but there are still some things we can't do, * for example importing any gi module */ val = seed_simple_evaluate(engine->context, "GObject = imports.gi.GObject;", &exception); g_assert(val == NULL); /* Pretty obscure error message, but the idea is there */ g_assert_cmpstr( seed_exception_get_message(engine->context, exception), ==, "undefined is not an object (evaluating 'imports.extensions.GObject')"); exception = NULL; /* Let's now authorize GObject and GObject only */ val = seed_engine_expose_namespace(engine, "GObject", exception); g_assert(val != NULL); g_assert(exception == NULL); /* Seed tells us all went well, let's try anyway */ val = seed_simple_evaluate(engine->context, "GObject = imports.gi.GObject;", &exception); g_assert(val != NULL); g_assert(exception == NULL); /* Only need to check whether another module which we know * would be available if the engine was not constrained is indeed * still unavailable */ val = seed_simple_evaluate(engine->context, "GLib = imports.gi.GLib;", &exception); g_assert(val == NULL); /* The error message isn't any clearer since last time */ g_assert_cmpstr( seed_exception_get_message(engine->context, exception), ==, "undefined is not an object (evaluating 'imports.extensions.GLib')"); exception = NULL; seed_engine_destroy(engine); } int main(int argc, char** argv) { g_test_init(&argc, &argv, NULL); g_test_add_func("/module-whitelist", test_module_whitelist); return g_test_run(); } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/000077500000000000000000000000001303774616400221365ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/COPYING000066400000000000000000000001031303774616400231630ustar00rootroot00000000000000Any code in these tests is to be considered under the MIT license. seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/Makefile.am000066400000000000000000000026531303774616400242000ustar00rootroot00000000000000 TESTS_ENVIRONMENT = PATH=$(top_builddir)/src:$$PATH SUBDIRS = gtypes signals structs workingtests = \ argv.js \ array-gtype.js \ builtin-argument-length.js \ check-syntax.js \ closure-finalization.js \ compare.js \ constructor-args.js \ constructor-prototype.js \ enum.js \ fork.js \ function-info.js \ gobject-scope.js \ gvalue-argument.js \ include.js \ included.js \ include-syntax.js \ introspect.js \ json-constructor.js \ json.js \ list-test.js \ modules.js \ modules-noasserts.js \ native-closure-exception.js \ native-closure.js \ object-info.js \ out-test.js \ property-benchmark.js \ property-glib-exception.js \ quit.js \ sqlite.js \ syntax-test.js \ syntax-test-noasserts.js \ type-conversion.js failingtests = \ syntax-test-noasserts.js \ modules-noasserts.js \ included.js \ gerror.js \ gdk-event.js \ $(NULL) otherfiles = testsuite.js \ modules-noasserts.js.in \ syntax-test-noasserts.js.in \ included.js.in \ COPYING \ $(NULL) installingtests_DATA = $(workingtests) $(otherfiles) installingtestsdir = $(datadir)/seed@SEED_GTK_VERSION@-tests/javascript/ EXTRA_DIST = \ $(workingtests) \ $(failingtests) \ $(otherfiles) \ $(NULL) TESTS = \ $(workingtests) \ $(failingtests) \ $(NULL) XFAIL_TESTS = \ $(failingtests) \ $(NULL) -include $(top_srcdir)/git.mk seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/argv.js000077500000000000000000000003311303774616400234330ustar00rootroot00000000000000#!/usr/bin/env seed // when running make check, argv is actually path/to/lt-seed or path/to/seed imports.testsuite.assert(Seed.argv[0] == "seed" || Seed.argv[0].match(/\/lt-seed$/) || Seed.argv[0].match(/\/seed$/)) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/array-gtype.js000077500000000000000000000004221303774616400247410ustar00rootroot00000000000000#!/usr/bin/env seed Gtk = imports.gi.Gtk; GObject = imports.gi.GObject; Gtk.init(Seed.argv); try { list = new Gtk.ListStore(); list.set_column_types([GObject.TYPE_STRING, GObject.TYPE_INT]); } catch(e) { print(e.message) imports.testsuite.unreachable() } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/builtin-argument-length.js000077500000000000000000000017471303774616400272550ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite function correctArgs(fs, a) { try { eval(fs).apply(this, a) } catch(e) { if(e.name == "ArgumentError") testsuite.unreachable(fs) } } function wrongArgs(fs, a) { try { eval(fs).apply(this, a) testsuite.unreachable(fs) } catch(e) { } } wrongArgs("Seed.spawn", []) correctArgs("Seed.spawn", ["asdfasdfasdf"]) wrongArgs("Seed.include", []) wrongArgs("Seed.include", [1]) correctArgs("Seed.include", [""]) wrongArgs("Seed.include", [1,2]) wrongArgs("Seed.include", ["fail.js","another.js"]) wrongArgs("print", []) wrongArgs("print", [1,2]) wrongArgs("print", ["asdf",2]) wrongArgs("print", [1,2,3]) wrongArgs("Seed.introspect", []) correctArgs("Seed.introspect", [Seed]) wrongArgs("Seed.introspect", [Seed, 5.23]) wrongArgs("Seed.check_syntax", []) correctArgs("Seed.check_syntax", ["asdfasdf"]) wrongArgs("Seed.check_syntax", ["5+5", "asdf"]) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/check-syntax.js000077500000000000000000000007021303774616400250770ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite try { Seed.check_syntax("5+5;") } catch(e) { testsuite.unreachable("5+5; is not a syntax error") } try { Seed.check_syntax("asdfasdf.jsdf()") } catch(e) { testsuite.unreachable("asdfasdf.jsdf() is not a syntax error") } try { Seed.check_syntax("one[)") testsuite.unreachable("one[) should be a syntax error") } catch(e) { testsuite.assert(e instanceof SyntaxError) } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/closure-finalization.js000077500000000000000000000007361303774616400266460ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite; Gtk = imports.gi.Gtk; Gtk.init(Seed.argv); w = new Gtk.Window(); // Closure will always be GCed at end of signal. signal = function() { widgets = [] w.foreach(function(widget){widgets.push(widget.toString())}) testsuite.assert(widgets[0] == ["[object GtkVBox]"]) testsuite.assert(widgets.length == 1) }; vbox = new Gtk.VBox(); w.add(vbox); w.signal.show.connect(signal); w.show_all(); testsuite.checkAsserts(2) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/compare.js000077500000000000000000000003241303774616400241240ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite Gtk = imports.gi.Gtk; Gtk.init(Seed.argv); var a = new Gtk.Button(); var b = new Gtk.Button(); var c = a; testsuite.assert(a != b); testsuite.assert(c == a); seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/constructor-args.js000077500000000000000000000006631303774616400260230ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite Gtk = imports.gi.Gtk; Gtk.init(Seed.argv); try { w = new Gtk.Window(); } catch (e) { testsuite.unreachable() } try { w = new Gtk.Window(1, 2); testsuite.unreachable() } catch (e) { testsuite.assert(e.name == "ArgumentError") } try { w = new Gtk.Window("safA"); testsuite.unreachable() } catch (e) { testsuite.assert(e.name == "ArgumentError") } testsuite.checkAsserts(2) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/constructor-prototype.js000077500000000000000000000003131303774616400271240ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite Gtk = imports.gi.Gtk Gtk.init(Seed.argv) Gtk.Window.prototype.hello = "Hello World" a = new Gtk.Window() testsuite.assert(a.hello == "Hello World") seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/enum.js000077500000000000000000000003431303774616400234430ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite Gtk = imports.gi.Gtk; Gtk.init(Seed.argv); b = new Gtk.Button() b.relief = Gtk.ReliefStyle.NONE testsuite.assert(Gtk.ReliefStyle.NONE == 2) testsuite.assert(b.relief == 2) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/fork.js000077500000000000000000000001541303774616400234400ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite os = imports.os a = os.fork() testsuite.assert(a >= 0) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/function-info.js000077500000000000000000000002331303774616400252530ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite Gtk = imports.gi.Gtk f = Gtk.Window.prototype.resize.info; testsuite.assert(f.get_name() == "resize") seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/gdk-event.js000077500000000000000000000006641303774616400243710ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite Gtk = imports.gi.Gtk Gdk = imports.gi.Gdk Gtk.init(Seed.argv) function paint(wdg, cr) { testsuite.assert(wdg.window instanceof Gdk.Window) var sz = wdg.get_size(); testsuite.assert(sz.width == 200) Gtk.main_quit() return false } var win = new Gtk.Window() win.signal.draw.connect(paint) win.resize(200,200) win.show() Gtk.main() testsuite.checkAsserts(2) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/gerror.js000077500000000000000000000002771303774616400240050ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite Gio = imports.gi.Gio try { Gio.simple_write(".", "test") testsuite.unreachable() } catch (e) { testsuite.assert(e.name == "GIoError") } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/glib-variant.js000066400000000000000000000045241303774616400250600ustar00rootroot00000000000000//#!/usr/bin/env seed // test for js object <-> Variant conversion. // TODO: test edge cases GLib = imports.gi.GLib; testsuite = imports.testsuite // array -> variant conversion tests var testArray = ["Variantify", 42, [43, "me!"]]; var testArrayVariant = GLib.Variant.new(testArray); var variantify = testArrayVariant.get_child_value(0).get_variant().get_string(); var fortyTwo = testArrayVariant.get_child_value(1).get_variant().get_int64(); var subArray = testArrayVariant.get_child_value(2).get_variant(); var fortyThree = subArray.get_child_value(0).get_variant().get_int64(); var me = subArray.get_child_value(1).get_variant().get_string(); testsuite.assert(testArrayVariant.is_container()); testsuite.assert(variantify == "Variantify"); testsuite.assert(fortyTwo == 42); testsuite.assert(fortyThree == 43); testsuite.assert(me == "me!"); // variant -> array conversion tests var testArray2 = testArrayVariant.to_js(); testsuite.assert(testArray2[0] == testArray[0]); testsuite.assert(testArray2[1] == testArray[1]); testsuite.assert(testArray2[2][0] == testArray[2][0]); testsuite.assert(testArray2[2][1] == testArray[2][1]); // object -> variant test var your = 42; var testObject = {Let: "me", "be": your, object: 42}; var testObjectVariant = GLib.Variant.new(testObject); var _let = testObjectVariant.get_child_value(0).get_child_value(0).get_string(); me = testObjectVariant.get_child_value(0).get_child_value(1).get_variant().get_string(); var be = testObjectVariant.get_child_value(1).get_child_value(0).get_string(); var your2 = testObjectVariant.get_child_value(1).get_child_value(1).get_variant().get_int64(); var object = testObjectVariant.get_child_value(2).get_child_value(0).get_string(); fortyTwo = testObjectVariant.get_child_value(2).get_child_value(1).get_variant().get_int64(); testsuite.assert(_let == "Let"); testsuite.assert(me == "me"); testsuite.assert(be == "be"); testsuite.assert(your2 == your); testsuite.assert(object == "object"); testsuite.assert(fortyTwo == 42); // variant -> object tests var testObject2 = testObjectVariant.to_js(); testsuite.assert(testObject2.Let); testsuite.assert(testObject2.Let == testObject.Let); testsuite.assert(testObject2.be); testsuite.assert(testObject2.be == testObject.be); testsuite.assert(testObject2.object); testsuite.assert(testObject2.object == testObject.object); testsuite.checkAsserts(21); seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/gobject-scope.js000077500000000000000000000003121303774616400252170ustar00rootroot00000000000000#!/usr/bin/env seed // TODO: this test doesn't actually test anything... Gtk = imports.gi.Gtk Gtk.init(Seed.argv) for(var i = 0; i < 100; i++) { var button = new Gtk.Button({label: "Test!"}) } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/gtypes/000077500000000000000000000000001303774616400234515ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/gtypes/Makefile.am000066400000000000000000000013661303774616400255130ustar00rootroot00000000000000 TESTS_ENVIRONMENT = PATH=$(top_builddir)/src:$$PATH workingtests = \ gtype-class-init-exception.js \ gtype-typerror.js \ gtype.js \ gtype-gtype.js \ gtype-signal-args.js \ gtype-signal-order-bug663289.js \ gtype-property-construct.js \ gtype-property-nice.js \ gtype-self.js \ gtype-extraprop.js \ gtype-gtype-class-init.js \ gtype-signal.js failingtests = \ $(NULL) otherfiles = testsuite.js installingtests_DATA = $(workingtests) $(otherfiles) installingtestsdir = $(datadir)/seed@SEED_GTK_VERSION@-tests/javascript/gtypes/ EXTRA_DIST = \ $(workingtests) \ $(failingtests) \ $(otherfiles) \ $(NULL) TESTS = \ $(workingtests) \ $(failingtests) \ $(NULL) XFAIL_TESTS = \ $(failingtests) \ $(NULL) -include $(top_srcdir)/git.mk seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/gtypes/gtype-class-init-exception.js000077500000000000000000000007321303774616400312040ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite Gtk = imports.gi.Gtk Gtk.init(Seed.argv) HelloWindowType = { parent: Gtk.Window.type, name: "HelloWindow", class_init: function(klass, prototype) { prototype = notAVariable.notAProperty }, init: function(klass) { } } try { HelloWindow = new GType(HelloWindowType) w = new HelloWindow() } catch(e) { testsuite.assert(e instanceof ReferenceError) } testsuite.checkAsserts(1) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/gtypes/gtype-extraprop.js000077500000000000000000000005721303774616400271700ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite Gtk = imports.gi.Gtk Gtk.init(Seed.argv) HelloWindow = new GType({ parent: Gtk.Window.type, name: "HelloWindow", init: function(self) { testsuite.assert(self.test == 2) testsuite.assert(self.testAgain == "arst") } }) w = new HelloWindow({test: 2, testAgain: "arst"}) testsuite.checkAsserts(2) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/gtypes/gtype-gtype-class-init.js000077500000000000000000000007571303774616400303450ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite Gtk = imports.gi.Gtk Gtk.init(Seed.argv) HelloWindow = new GType({ parent: Gtk.Window.type, name: "HelloWindow", init: function() { } }) w = new HelloWindow() InheritedWindow = new GType({ parent: HelloWindow.type, name: "InheritedWindow", class_init: function(klass, prototype) { testsuite.assert(1) }, init: function() { } }) b = new InheritedWindow() testsuite.checkAsserts(1) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/gtypes/gtype-gtype.js000077500000000000000000000007531303774616400262750ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite Gtk = imports.gi.Gtk Gtk.init(Seed.argv) HelloWindow = new GType({ parent: Gtk.Window.type, name: "HelloWindow", init: function(self) { self.id = 5 } }) InheritedWindow = new GType({ parent: HelloWindow.type, name: "InheritedWindow", init: function(self) { self.id = 10 } }) w = new HelloWindow() b = new InheritedWindow() testsuite.assert(w.id == 5) testsuite.assert(b.id == 10) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/gtypes/gtype-property-construct.js000077500000000000000000000014431303774616400310500ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite Gtk = imports.gi.Gtk GObject = imports.gi.GObject Gtk.init(Seed.argv) HelloWindow = new GType({ parent: Gtk.Window.type, name: "HelloWindow", properties: [ { name: "test", type: GObject.TYPE_BOOLEAN, nick: "test property", blurb: "A test property!", default_value: false, flags: (GObject.ParamFlags.CONSTRUCT | GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE) } ], init: function() { testsuite.assert(this.test == true) } }) w = new HelloWindow({test: true}) testsuite.assert(w.test == true) try { w.test = "arst" } catch(e) { testsuite.assert(e.name == "ConversionError") } testsuite.checkAsserts(3) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/gtypes/gtype-property-nice.js000077500000000000000000000013351303774616400277420ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite GObject = imports.gi.GObject Gtk = imports.gi.Gtk Gtk.init(Seed.argv) HelloWindow = new GType({ parent: Gtk.Window.type, name: "HelloWindow", properties: [{ name: "randomproperty", type: GObject.TYPE_BOOLEAN, nick: "randomproperty", blurb: "longer blurb about property", default_value: true, flags: (GObject.ParamFlags.CONSTRUCT | GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE)}], init: function(klass) { } }) w = new HelloWindow() testsuite.assert(w.randomproperty == 1) w.randomproperty = 5 testsuite.assert(w.randomproperty == 1) w.randomproperty = 0 testsuite.assert(w.randomproperty == 0) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/gtypes/gtype-self.js000077500000000000000000000004531303774616400260730ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite Gtk = imports.gi.Gtk Gtk.init(Seed.argv) HelloWindow = new GType({ parent: Gtk.Window.type, name: "HelloWindow", init: function(self) { testsuite.assert(this == self) } }) w = new HelloWindow() testsuite.checkAsserts(1) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/gtypes/gtype-signal-args.js000077500000000000000000000012441303774616400273500ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite Gtk = imports.gi.Gtk GObject = imports.gi.GObject Gtk.init(Seed.argv) HelloWindow = new GType({ parent: Gtk.Window.type, name: "HelloWindow", signals: [{name: "hello", parameters: [GObject.TYPE_INT, GObject.TYPE_STRING], return_type: Gtk.Window.type}] }) w = new HelloWindow() w.signal.hello.connect(function(object, number, string) { var win = new Gtk.Window() testsuite.assert(number == 2) testsuite.assert(string == "Test") return win }) testsuite.assert(w.signal.hello.emit(2, "Test") instanceof Gtk.Window) testsuite.checkAsserts(3) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/gtypes/gtype-signal-order-bug663289.js000077500000000000000000000010351303774616400310020ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite GObject = imports.gi.GObject TestObject = new GType({ parent: GObject.Object.type, name: "TestObject", signals: [{name: "more_args", parameters: [GObject.TYPE_INT, GObject.TYPE_STRING]}, {name: "less_args", return_type: GObject.TYPE_BOOLEAN}] }) t = new TestObject() t.signal.less_args.connect(function(object) { return true }) testsuite.assert(t.signal.less_args.emit()) testsuite.checkAsserts(1) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/gtypes/gtype-signal.js000077500000000000000000000007521303774616400264210ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite Gtk = imports.gi.Gtk Gtk.init(Seed.argv) HelloWindowType = { parent: Gtk.Window.type, name: "HelloWindow", signals: [{name: "hello"}, {name: "goodbye"}] } HelloWindow = new GType(HelloWindowType) w = new HelloWindow() w.signal.hello.connect(function(){hello = 5}) w.signal.goodbye.connect(function(){goodbye = 10}) w.signal.hello.emit() w.signal.goodbye.emit() testsuite.assert(hello == 5) testsuite.assert(goodbye == 10) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/gtypes/gtype-typerror.js000077500000000000000000000004371303774616400270320ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite Gtk = imports.gi.Gtk HelloWindowType = { parent: "Mom", name: "HelloWindow" } try { HelloWindow = new GType(HelloWindowType) } catch (e) { testsuite.assert(e.message == "GType constructor expected GType for parent") } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/gtypes/gtype.js000077500000000000000000000010541303774616400251420ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite Gtk = imports.gi.Gtk Gtk.init(Seed.argv) HelloWindow = new GType({ parent: Gtk.Window.type, name: "HelloWindow", class_init: function(klass, prototype) { prototype.message = "Prototypes!" }, init: function(self) { this.title = "Hello!" } }) w = new HelloWindow() testsuite.assert(w.message == "Prototypes!") w.signal.map.connect( function(widget) { testsuite.assert(widget.title == "Hello!") }) w.show() testsuite.checkAsserts(2) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/gtypes/testsuite.js000077500000000000000000000011051303774616400260400ustar00rootroot00000000000000assertCount = 0 function assert(a, err) { assertCount++ if(!a) { if(err) print("Assertion " + assertCount + " failed: " + err + ".") else print("Assertion " + assertCount + " failed.") Seed.quit(assertCount) } } function unreachable(err) { if(err) print("Unreachable code reached: " + err.toString() + ".") else print("Unreachable code reached.") Seed.quit(1) } function checkAsserts(n) { if(assertCount != n) assert(0, "Some assertions failed to run") } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/gvalue-argument.js000077500000000000000000000005671303774616400256120ustar00rootroot00000000000000#!/usr/bin/env seed Gtk = imports.gi.Gtk; GObject = imports.gi.GObject Gtk.init(Seed.argv); var s = new Gtk.ListStore(); s.set_column_types([GObject.TYPE_STRING, GObject.TYPE_INT, Gtk.Label.type]); var ret = {}; s.append(ret); s.set_value(ret.iter, 0, "Hi"); s.set_value(ret.iter, 1, [GObject.TYPE_INT, 10] ); l = new Gtk.Label.c_new("Hi"); s.set_value(ret.iter, 2, l); seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/include-syntax.js000077500000000000000000000003351303774616400254470ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite try { Seed.include("syntax-test-noasserts.js") testsuite.unreachable() } catch(e) { testsuite.assert(e instanceof SyntaxError) } testsuite.checkAsserts(1) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/include.js000077500000000000000000000000621303774616400241200ustar00rootroot00000000000000#!/usr/bin/env seed Seed.include("included.js"); seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/included.js.in000066400000000000000000000000561303774616400246710ustar00rootroot00000000000000#!/usr/bin/env seed included_varaiable = 42; seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/introspect.js000077500000000000000000000004771303774616400247010ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite Gtk = imports.gi.Gtk JSON = imports.JSON Gtk.init(Seed.argv) win = new Gtk.Window() info = Seed.introspect(win.set_opacity) testsuite.assert(info.name == "set_opacity") testsuite.assert(info.return_type == "void") testsuite.assert(info.args[0].type == "gdouble") seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/json-constructor.js000077500000000000000000000003441303774616400260340ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite Gtk = imports.gi.Gtk GLib = imports.gi.GLib Gtk.init(Seed.argv) window = new Gtk.Window({title: "JSON Win!"}) window.show_all() testsuite.assert(window.title == "JSON Win!") seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/json.js000077500000000000000000000007101303774616400234460ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite; JSON = imports.JSON; a = {test: 3, hello: "Goodbye", more: {a: "1", b: 2, c:"d"}} json = JSON.stringify(a) object = JSON.parse(json) json2 = JSON.stringify(object) testsuite.assert(json == json2) testsuite.assert(object.test == 3) testsuite.assert(object.hello == "Goodbye") testsuite.assert(object.more.a == "1") testsuite.assert(object.more.b == 2) testsuite.assert(object.more.c == "d") seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/list-test.js000077500000000000000000000006461303774616400244350ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite Gtk = imports.gi.Gtk Gtk.init(Seed.argv) b1 = new Gtk.Button() b2 = new Gtk.Button() vbox = new Gtk.VBox() vbox.pack_start(b1) vbox.pack_start(b2) children = vbox.get_children() testsuite.assert(children[0] instanceof Gtk.Button) testsuite.assert(children[1] instanceof Gtk.Button) testsuite.assert(children[0] != children[1]) testsuite.assert(children.length == 2) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/modules-noasserts.js.in000077500000000000000000000010431303774616400265710ustar00rootroot00000000000000#!/usr/bin/env seed // This test is merely to appease the coverage checker (calls init in each // module); it will also catch unresolved symbol errors in the modules. try { cairo = imports.cairo; canvas = imports.canvas; dbus = imports.dbus; example = imports.example; gettext = imports.gettext; gtkbuilder = imports.gtkbuilder; libxml = imports.libxml; mpfr = imports.mpfr; Multiprocessing = imports.Multiprocessing; os = imports.os; readline = imports.readline; sandbox = imports.sandbox; sqlite = imports.sqlite; } catch(e) { } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/modules.js000077500000000000000000000002601303774616400241450ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite input = Seed.spawn(Seed.argv[0] + " modules-noasserts.js"); testsuite.assert(input.stdout == "Hello Seed Module World\n") seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/native-closure-exception.js000077500000000000000000000010261303774616400274320ustar00rootroot00000000000000#!/usr/bin/env seed // TODO: shouldn't the exception be passed back to the caller? testsuite = imports.testsuite Gtk = imports.gi.Gtk Gtk.init(Seed.argv) w = new Gtk.Window() vbox = new Gtk.VBox() closure = function(widget){a.a.a} w.add(vbox) vbox.pack_start(new Gtk.Label()) try { vbox.foreach(closure) // ARST testsuite.unreachable() } catch(e) { testsuite.assert(e instanceof ReferenceError) } //testsuite.checkAsserts print("This test doesn't work yet... since callbacks might be async - should it ever work?") seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/native-closure.js000077500000000000000000000005741303774616400254450ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite Gtk = imports.gi.Gtk Gtk.init(Seed.argv) w = new Gtk.Window() vbox = new Gtk.VBox() closure = function(widget) { testsuite.assert(widget instanceof Gtk.Label || widget instanceof Gtk.Button) } w.add(vbox) vbox.pack_start(new Gtk.Label()) vbox.pack_start(new Gtk.Button()) vbox.foreach(closure) testsuite.checkAsserts(2) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/object-info.js000077500000000000000000000010701303774616400246740ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite Gtk = imports.gi.Gtk GIRepository = imports.gi.GIRepository gir = GIRepository.Repository.get_default() info = gir.find_by_gtype(Gtk.Window.type) testsuite.assert(info.get_name() == "Window") n = GIRepository.object_info_get_n_interfaces(info) for (i = 0; i < n; i++) { property = GIRepository.object_info_get_interface(info, i) propertyname = property.get_name(); testsuite.assert(propertyname == "Buildable" || propertyname == "ImplementorIface") } testsuite.checkAsserts(3) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/out-test.js000077500000000000000000000004131303774616400242610ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite Gtk = imports.gi.Gtk Gtk.init(Seed.argv) w = new Gtk.Window({width_request: 5, height_request: 100}) o1 = { } o2 = { } w.get_size_request(o1, o2) testsuite.assert(o1.value == 5) testsuite.assert(o2.value == 100) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/property-benchmark.js000077500000000000000000000003561303774616400263170ustar00rootroot00000000000000#!/usr/bin/env seed // TODO: this test doesn't do anything Gtk = imports.gi.Gtk; Gtk.init(Seed.argv); window = new Gtk.Window(); window.title="HI"; window.name="HI"; for (i = 0; i < 10000; i++) { a = window.title; b = window.name; } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/property-glib-exception.js000077500000000000000000000005761303774616400273020ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite Gtk = imports.gi.Gtk Gtk.init(Seed.argv) window = new Gtk.Window() try { window.opacity = 3 } catch(e) { testsuite.assert(e.name == "PropertyError") testsuite.assert(e.message == "value \"3,000000\" of type 'gdouble' is invalid or out of range for property 'opacity' of type 'gdouble'") } testsuite.checkAsserts(2) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/quit.js000077500000000000000000000001021303774616400234520ustar00rootroot00000000000000#!/usr/bin/env seed Seed.quit(0) imports.testsuite.unreachable() seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/signals/000077500000000000000000000000001303774616400235765ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/signals/Makefile.am000066400000000000000000000011751303774616400256360ustar00rootroot00000000000000 TESTS_ENVIRONMENT = PATH=$(top_builddir)/src:$$PATH workingtests = \ signal-connect.js \ signal-disconnect.js \ signal-exception.js \ signal-expects.js \ signal-invalid.js \ signal.js \ signal-nofunc.js \ signal-userdata.js failingtests = \ $(NULL) otherfiles = testsuite.js installingtests_DATA = $(workingtests) $(otherfiles) installingtestsdir = $(datadir)/seed@SEED_GTK_VERSION@-tests/javascript/signals/ EXTRA_DIST = \ $(workingtests) \ $(failingtests) \ $(otherfiles) \ $(NULL) TESTS = \ $(workingtests) \ $(failingtests) \ $(NULL) XFAIL_TESTS = \ $(failingtests) \ $(NULL) -include $(top_srcdir)/git.mk seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/signals/signal-connect.js000077500000000000000000000012561303774616400270470ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite Gtk = imports.gi.Gtk Gtk.init(Seed.argv) function handle_opacity_change(obj, gobject, user_data) { testsuite.assert(user_data instanceof Gtk.Button) testsuite.assert(user_data === button) // XXX: The following test got replaced because of a probably bug in Gtk. // widget_set_opacity(X) gets rounded, so when you ask for get_opacity the // number might not be the same //testsuite.assert(obj.opacity == 0.5) testsuite.assert(Math.abs(obj.opacity - 0.5) < 0.01) } win = new Gtk.Window() button = new Gtk.Button() win.signal.connect("notify::opacity", handle_opacity_change, button) win.opacity = 0.5 testsuite.checkAsserts(3) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/signals/signal-disconnect.js000077500000000000000000000004511303774616400275430ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite Gtk = imports.gi.Gtk Gtk.init(Seed.argv) myglobal = 0 function test() { myglobal += 1234 } w = new Gtk.Window() id = w.signal.map.connect(test) w.show_all() w.hide() w.signal.disconnect(id) w.show_all() testsuite.assert(myglobal == 1234) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/signals/signal-exception.js000077500000000000000000000005631303774616400274140ustar00rootroot00000000000000#!/usr/bin/env seed // Returns: 0 // STDIN: // STDOUT: // STDERR:\n\*\* \(seed:[0-9]+\): WARNING \*\*: Exception in closure .* testsuite = imports.testsuite Gtk = imports.gi.Gtk; Gtk.init(Seed.argv); w = new Gtk.Window(); //w.signal.map.connect(function(){3 = undefined}); //w.show(); print("This is another one of those tests that probably doesn't chain right yet") seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/signals/signal-expects.js000077500000000000000000000004611303774616400270660ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite Gtk = imports.gi.Gtk Gtk.init(Seed.argv) function expects_test(widget, user_data) { testsuite.assert(widget == w) testsuite.assert(user_data == null) } w = new Gtk.Window() w.signal.map.connect(expects_test) w.show() testsuite.checkAsserts(2) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/signals/signal-invalid.js000077500000000000000000000004371303774616400270440ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite Gtk = imports.gi.Gtk Gtk.init(Seed.argv) w = new Gtk.Window() try { a = w.signal.notasignal; testsuite.unreachable(); } catch(e) { testsuite.assert(e.message == "Failed to connect to notasignal. Invalid signal name."); } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/signals/signal-nofunc.js000077500000000000000000000004751303774616400267100ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite Gtk = imports.gi.Gtk; Gtk.init(Seed.argv); w = new Gtk.Window(); try { w.signal.map.connect(3); testsuite.unreachable() } catch (e) { testsuite.assert(e.message == "Signal connection requires a function as first argument") } testsuite.checkAsserts(1) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/signals/signal-userdata.js000077500000000000000000000005071303774616400272240ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite Gtk = imports.gi.Gtk; JSON = imports.JSON; Gtk.init(Seed.argv); function userdata_test(widget, user_data) { testsuite.assert(user_data.Hello == "World") } w = new Gtk.Window(); w.signal.map.connect(userdata_test, {Hello: "World"}); w.show(); testsuite.checkAsserts(1) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/signals/signal.js000077500000000000000000000003671303774616400254220ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite Gtk = imports.gi.Gtk Gtk.init(Seed.argv) function mapped(window) { testsuite.assert(window == w) } w = new Gtk.Window() w.signal.map.connect(mapped) w.show_all() testsuite.checkAsserts(1) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/signals/testsuite.js000077500000000000000000000011051303774616400261650ustar00rootroot00000000000000assertCount = 0 function assert(a, err) { assertCount++ if(!a) { if(err) print("Assertion " + assertCount + " failed: " + err + ".") else print("Assertion " + assertCount + " failed.") Seed.quit(assertCount) } } function unreachable(err) { if(err) print("Unreachable code reached: " + err.toString() + ".") else print("Unreachable code reached.") Seed.quit(1) } function checkAsserts(n) { if(assertCount != n) assert(0, "Some assertions failed to run") } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/sqlite.js000077500000000000000000000017411303774616400240030ustar00rootroot00000000000000#!/usr/bin/env seed // this may not be the real build location... - but push it on the stack imports.searchPath.unshift('../../modules/sqlite/.libs'); testsuite = imports.testsuite Gio = imports.gi.Gio sqlite = imports.sqlite JSON = imports.JSON try { Gio.file_new_for_path("/tmp/.seed_test.db")["delete"]() } catch(e) { // We don't care if we fail to delete the (probably nonexistent) file... } d = new sqlite.Database("/tmp/.seed_test.db") d.exec("create table t1 (t1key INTEGER PRIMARY KEY,data TEXT,num double,timeEnter DATE)") d.exec("insert into t1 (data,num) values ('This is sample data',3)") d.exec("insert into t1 (data,num) values ('More sample data',6)") d.exec("insert into t1 (data,num) values ('And a little more',9)") d.exec("select * from t1 where num = 6", function(results) { testsuite.assert(results.t1key == "2") testsuite.assert(results.data == "More sample data") testsuite.assert(results.num == 6.0) }) d.close() testsuite.checkAsserts(3) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/structs/000077500000000000000000000000001303774616400236455ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/structs/Makefile.am000066400000000000000000000012231303774616400256770ustar00rootroot00000000000000 TESTS_ENVIRONMENT = PATH=$(top_builddir)/src:$$PATH workingtests = \ struct-functions.js \ struct-set-member.js \ struct-constructor.js \ struct-nested-set.js \ struct-null.js \ struct-union-enumerate.js \ struct-enumerate.js \ struct-offsets.js failingtests = \ $(NULL) otherfiles = testsuite.js installingtests_DATA = $(workingtests) $(otherfiles) installingtestsdir = $(datadir)/seed@SEED_GTK_VERSION@-tests/javascript/stucts/ EXTRA_DIST = \ $(workingtests) \ $(failingtests) \ $(otherfiles) \ $(NULL) TESTS = \ $(workingtests) \ $(failingtests) \ $(NULL) XFAIL_TESTS = \ $(failingtests) \ $(NULL) -include $(top_srcdir)/git.mk seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/structs/struct-constructor.js000077500000000000000000000003521303774616400301150ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite Gdk = imports.gi.Gdk c = new Gdk.Color({red: 100}) testsuite.assert(c.red == 100) c = new Gdk.Color({red: 90, blue: 80}) testsuite.assert(c.red == 90) testsuite.assert(c.blue == 80) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/structs/struct-enumerate.js000077500000000000000000000004321303774616400275140ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite; Gdk = imports.gi.Gdk; cairo = imports.gi.cairo; r = new cairo.RectangleInt() for (prop in r) { testsuite.assert(prop == "x" || prop == "y" || prop == "width" || prop == "height") } testsuite.checkAsserts(4) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/structs/struct-functions.js000077500000000000000000000002571303774616400275440ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite GConf = imports.gi.GConf GConf.init(Seed.argv) client = GConf.Client.get_default() testsuite.assert(client != undefined) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/structs/struct-nested-set.js000077500000000000000000000006371303774616400276110ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite; Gdk = imports.gi.Gdk; cairo = imports.gi.cairo; e = new Gdk.Event(); testsuite.assert(e.toString() == "[object seed_union]"); e.type = Gdk.EventType.EXPOSE; testsuite.assert(Gdk.EventType.EXPOSE == e.type); r = new cairo.RectangleInt() r.x = 300 e.rectangle = r testsuite.assert(e.rectangle.x == 300) e.rectangle.x = 400 testsuite.assert(e.rectangle.x == 400) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/structs/struct-null.js000077500000000000000000000004231303774616400265010ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite; Gtk = imports.gi.Gtk; Gtk.init(Seed.argv); var iconTheme = Gtk.IconTheme.get_default(); // returns NULL if icon not found var iconInfo = iconTheme.lookup_icon("fake icon name", 32); testsuite.assert(iconInfo === null) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/structs/struct-offsets.js000077500000000000000000000002531303774616400272010ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite Pango = imports.gi.Pango c = new Pango.Color() c.red = 17 testsuite.assert(c.red == 17) testsuite.assert(c.blue == 0) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/structs/struct-set-member.js000077500000000000000000000002651303774616400275730ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite Gdk = imports.gi.Gdk color = new Gdk.Color() testsuite.assert(color.red == 0) color.red = 200 testsuite.assert(color.red == 200) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/structs/struct-union-enumerate.js000077500000000000000000000014141303774616400306430ustar00rootroot00000000000000#!/usr/bin/env seed // The way this test stood, it didn't make any sense. It still doesn't, but // at least now it's not fragile based on Gdk version, and will still be // triggered by the only flaw this test has ever caught... testsuite = imports.testsuite Gdk = imports.gi.Gdk maxindent = 0 propcount = 0 function enum_structlike(indent, e) { if(indent > maxindent) maxindent = indent for (prop in e) { propcount++ try { if (e[prop] && e[prop].toString() && (e[prop].toString().search("struct") > 0 || e[prop].toString().search("union") > 0)) enum_structlike(indent + 1, e[prop]) } catch(e) { } } } e = new Gdk.Event() enum_structlike(0, e) testsuite.assert(maxindent >= 2) testsuite.assert(propcount >= 50) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/structs/testsuite.js000077500000000000000000000011051303774616400262340ustar00rootroot00000000000000assertCount = 0 function assert(a, err) { assertCount++ if(!a) { if(err) print("Assertion " + assertCount + " failed: " + err + ".") else print("Assertion " + assertCount + " failed.") Seed.quit(assertCount) } } function unreachable(err) { if(err) print("Unreachable code reached: " + err.toString() + ".") else print("Unreachable code reached.") Seed.quit(1) } function checkAsserts(n) { if(assertCount != n) assert(0, "Some assertions failed to run") } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/syntax-test-noasserts.js.in000077500000000000000000000000101303774616400274150ustar00rootroot00000000000000new = 3 seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/syntax-test.js000077500000000000000000000003031303774616400247760ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite try { eval("new = 3") testsuite.unreachable() } catch(e) { testsuite.assert(e instanceof SyntaxError) } testsuite.checkAsserts(1) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/testsuite.js000077500000000000000000000011051303774616400245250ustar00rootroot00000000000000assertCount = 0 function assert(a, err) { assertCount++ if(!a) { if(err) print("Assertion " + assertCount + " failed: " + err + ".") else print("Assertion " + assertCount + " failed.") Seed.quit(assertCount) } } function unreachable(err) { if(err) print("Unreachable code reached: " + err.toString() + ".") else print("Unreachable code reached.") Seed.quit(1) } function checkAsserts(n) { if(assertCount != n) assert(0, "Some assertions failed to run") } seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tests/javascript/type-conversion.js000077500000000000000000000007221303774616400256440ustar00rootroot00000000000000#!/usr/bin/env seed testsuite = imports.testsuite Gtk = imports.gi.Gtk Gtk.init(Seed.argv) actor = new Gtk.Window() try { actor.accept_focus = 'hello' testsuite.unreachable() } catch(e) { testsuite.assert(e.message = "Can not convert Javascript value to boolean") } try { actor.default_width = actor testsuite.unreachable() } catch(e) { testsuite.assert(e.message = "Can not convert Javascript value to int") } testsuite.checkAsserts(2) seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tools/000077500000000000000000000000001303774616400177665ustar00rootroot00000000000000seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tools/check-release.sh000077500000000000000000000021121303774616400230140ustar00rootroot00000000000000#!/usr/bin/env bash # First, make sure all files are being included in the tarball... cd /tmp echo "Checking out Seed from Git..." git clone git://git.gnome.org/seed > /tmp/seed-build.log cp -r seed seed-svn cd seed version=`cat configure.ac | perl -e "while(<>){if(/AC_INIT/){ \\$a = \\$_; \\$a =~ s/.*\s(.*)\)/\\$1/; print \\$a;}}"` echo "Found seed-$version. Making tarball." ./autogen.sh --enable-gtk-doc >> /tmp/seed-build.log make -j2 make dist >> /tmp/seed-build.log mv "seed-$version.tar.gz" .. cd .. rm -rf /tmp/seed tar -xzf "seed-$version.tar.gz" diff -rq seed-svn "seed-$version" | grep -v "Common subdirectories" | grep -v "Only in seed-$version" | grep -v "Files .* differ" | grep -v ".git*" | grep -v ".cvs*" | grep -v "autogen.sh" | grep -v "debian" | grep -v "MAINTAINERS" | grep -v "OPEN_QUESTIONS" | grep -v "tools" | less echo "Attempting to build and test..." cd "seed-$version" ./configure >> /tmp/seed-build.log make -j5 >> /tmp/seed-build.log PATH="src:$PATH" make test | less rm -rf /tmp/seed-svn rm -rf "/tmp/seed-$version" rm -rf "/tmp/seed-$version.tar.gz" seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tools/indent.sh000077500000000000000000000006601303774616400216100ustar00rootroot00000000000000indent -nbad -bap -nbc -bbo -hnl -br -brs -c33 -cd33 -ncdb -nce -ci4 \ -cli0 -d0 -di1 -nfc1 -i4 -ip0 -l80 -lp -npcs -nprs -npsl -sai \ -saf -saw -ncs -nsc -sob -nfca -cp33 -ss -ts4 -il1 -bl -bli0 *.c ; \ indent -nbad -bap -nbc -bbo -hnl -br -brs -c33 -cd33 -ncdb -nce -ci4 \ -cli0 -d0 -di1 -nfc1 -i4 -ip0 -l80 -lp -npcs -nprs -npsl -sai \ -saf -saw -ncs -nsc -sob -nfca -cp33 -ss -ts4 -il1 -bl -bli0 *.h seed-webkit2-4.0.0+20161014+6c77960+dfsg1/tools/run-lint.js000077500000000000000000000012621303774616400221000ustar00rootroot00000000000000#!/usr/bin/env seed Gio = imports.gi.Gio; Seed.include("jslint.js"); function runLint(filename) { var read_file = Gio.simple_read(filename); read_file = read_file.replace("#!/usr/bin/env seed",""); if(JSLINT(read_file, {white:false, passfail: false, eqeqeq: false, forin: false})) return; print("################################################################################"); print(" " + filename); for(no in JSLINT.errors) { var err = JSLINT.errors[no]; if(!err || !err.reason) continue; printf("%d:%d\t%s",err.line,err.character,err.reason); } return JSLINT.errors.length; } for(a in Seed.argv) { if(a >= 2) runLint(Seed.argv[a]); }