Full Code of vmagnin/gtk-fortran for AI

gtk4 f96d3279b2d7 cached
154 files
7.4 MB
1.9M tokens
42 symbols
1 requests
Download .txt
Showing preview only (7,771K chars total). Download the full file or copy to clipboard to get everything.
Repository: vmagnin/gtk-fortran
Branch: gtk4
Commit: f96d3279b2d7
Files: 154
Total size: 7.4 MB

Directory structure:
gitextract__o02a7ce/

├── .github/
│   └── ISSUE_TEMPLATE/
│       └── bug_report.md
├── .gitignore
├── CHANGELOG.md
├── CITATION.cff
├── CMakeLists.txt
├── INSTALL.md
├── LICENSE
├── LICENSE_EXCEPTION
├── README-high-level.md
├── README.md
├── VERSIONS
├── cmake/
│   ├── DefaultFlags.cmake
│   ├── README.md
│   └── cmake_uninstall.cmake.in
├── codemeta.json
├── examples/
│   ├── CMakeLists.txt
│   ├── README.md
│   ├── bazaar.f90
│   ├── cairo-basics-click.f90
│   ├── cairo-basics.f90
│   ├── cairo-tests.f90
│   ├── demo_sound.ogg
│   ├── gio_demo.f90
│   ├── gtkbuilder.cmb
│   ├── gtkbuilder.ui
│   ├── gtkbuilder2.f90
│   ├── gtkhello.f90
│   ├── gtkzero_gapp.f90
│   ├── hl_assistant.f90
│   ├── hl_cairo1.f90
│   ├── hl_cairo_clock.f90
│   ├── hl_cairo_viewer.f90
│   ├── hl_choosers.f90
│   ├── hl_combo.f90
│   ├── hl_containers.f90
│   ├── hl_dialog.f90
│   ├── hl_infobar.f90
│   ├── hl_list1.f90
│   ├── hl_list_n.f90
│   ├── hl_list_renderers.f90
│   ├── hl_pbar.f90
│   ├── hl_sliders.f90
│   ├── hl_sliders2.f90
│   ├── hl_textview.f90
│   ├── hl_tree.f90
│   ├── julia_pixbuf.f90
│   ├── list_demo.f90
│   ├── mandelbrot_pixbuf.f90
│   ├── mandelbrot_pixbuf_zoom.f90
│   ├── menubar.f90
│   ├── notebooks.f90
│   ├── pixbuf_without_gui.f90
│   ├── regex.f90
│   ├── tests.f90
│   └── tests_gtk_sup.f90
├── fpm.toml
├── logo/
│   └── README.md
├── plplot/
│   ├── CMakeLists.txt
│   ├── README.md
│   ├── hl_plplot17e.f90
│   ├── hl_plplot17e_gto.f90
│   ├── hl_plplot1e.f90
│   ├── hl_plplot30e.f90
│   ├── hl_plplot4e.f90
│   └── hl_plplot8e.f90
├── screenshots/
│   ├── README.md
│   ├── bazaar_about_box.tiff
│   ├── cairo-basics_MacOSX.tiff
│   └── julia_pixbuf.tiff
├── sketcher/
│   ├── CMakeLists.txt
│   ├── README.md
│   ├── data/
│   │   ├── apache2.0.lic
│   │   ├── bsd.lic
│   │   ├── freeware.lic
│   │   ├── gnu-gpl-v2.lic
│   │   ├── gnu-gpl-v3.lic
│   │   ├── gnu-lgpl-v2.1.lic
│   │   ├── gnu-lgpl-v2.lic
│   │   └── zlib.lic
│   ├── default.options
│   ├── example.glade
│   ├── gtkf-sketcher.f90
│   └── gtkf-sketcher.glade
├── src/
│   ├── CMakeLists.txt
│   ├── README.md
│   ├── alt_build_test.sh
│   ├── api_compatibility.f90
│   ├── build.sh
│   ├── cairo-auto.f90
│   ├── cfwrapper/
│   │   ├── README.md
│   │   ├── analyze.py
│   │   ├── cfwrapper.py
│   │   ├── cleaning.py
│   │   ├── enums.py
│   │   ├── errors.py
│   │   ├── fortran.py
│   │   ├── globals_const.py
│   │   ├── gtk-fortran-hash.pkl
│   │   ├── lib_versions.py
│   │   ├── run_tests.py
│   │   ├── scan_types_and_enums.py
│   │   └── stats.py
│   ├── extract_enums.pl
│   ├── extract_events.pl
│   ├── extract_hl_doc.py
│   ├── gdk-auto.f90
│   ├── gdk-pixbuf-auto.f90
│   ├── gdk-pixbuf-hl.f90
│   ├── gdkevents-auto.f90
│   ├── glib-auto.f90
│   ├── graphene-auto.f90
│   ├── gsk-auto.f90
│   ├── gtk-auto.in
│   ├── gtk-draw-hl.f90
│   ├── gtk-enumerators.lis
│   ├── gtk-fortran-index.csv
│   ├── gtk-fortran-modscan.man
│   ├── gtk-fortran.f90
│   ├── gtk-fortran.pc.in
│   ├── gtk-fortran_funptr.csv
│   ├── gtk-fortran_types.csv
│   ├── gtk-hl-assistant.f90
│   ├── gtk-hl-button.f90
│   ├── gtk-hl-chooser.f90
│   ├── gtk-hl-combobox.f90
│   ├── gtk-hl-container.f90
│   ├── gtk-hl-dialog.f90
│   ├── gtk-hl-entry.f90
│   ├── gtk-hl-infobar.f90
│   ├── gtk-hl-misc.f90
│   ├── gtk-hl-progress.f90
│   ├── gtk-hl-spin-slider.f90
│   ├── gtk-hl-tree.f90
│   ├── gtk-hl.f90
│   ├── gtk-sup.f90
│   ├── gtk.f90
│   ├── gtkenums-auto.in
│   ├── pango-auto.f90
│   ├── plplot_extra.f90
│   ├── screenshots.sh
│   ├── show_versions.sh
│   ├── test_extra.sh
│   ├── tools.py
│   ├── unix-print-auto.f90
│   ├── usemodules.pl
│   └── usemodules.py
└── tutorials/
    ├── README.md
    ├── my_first_gtk_app1.f90
    ├── my_first_gtk_app2.f90
    ├── my_first_gtk_app3.f90
    ├── my_first_gtk_app4.f90
    ├── my_first_gtk_app5.f90
    ├── my_first_gtk_app6.f90
    └── my_first_gtk_app7.f90

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: Bug
assignees: vmagnin

---

**Describe the bug**
A clear and concise description of what the bug is. Tell which branch of the project is concerned (e.g. gtk3).

**Expected behavior**
A clear and concise description of what you expected to happen.
If applicable, add screenshots to help explain your problem.

**To Reproduce**
Steps to reproduce the behavior:
1. 
2. 
...

**Your system:**
 - OS version: [e.g. Ubuntu 18.04 64 bits]
 - Compiler version: [e.g. gfortran 8.2.0]
 - GTK branch: [e.g gtk4]

**Additional context**
Add any other context about the problem here.



================================================
FILE: .gitignore
================================================
*.out
*.mod
*.o
*~
*.bak
*.backup
*.old
*.directory
*__pycache__*
cfwrapper-errors.csv
usemodules.txt
build/


================================================
FILE: CHANGELOG.md
================================================
# Changelog
All notable changes to the gtk-fortran project are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

## [gtk-fortran 4.9.0] 2025-11-20

This release offers interfaces to GTK 4.20 and GLib 2.86 (generated under Fedora 43 with GTK 4.20.2 and GLib 2.86.1).

### Added
- In `CMakeLists.txt`:
  - support for Flang and LFortran. Their unsupported flags are filtered. Note however that LFortran 0.56 alpha is not yet ready to compile gtk-fortran.
  - A few errors (issue [#300](https://github.com/vmagnin/gtk-fortran/issues/300)) and warnings detected by Flang 20.1.3 were fixed. Flang now compiles entirely gtk-fortran (last tested with Flang 21.1.5).
  - Improved messages (linker version, compilation flags, GTK and PLplot dirs, installation dirs...).
- In `src/alt_build_test.sh`: support for Flang and LFortran (when it will be ready to compile gtk-fortran). And messages were improved.

### Changed
- `src/gtk-sup.f90`: the function `fdate()` was renamed `fmt_date()` to avoid confusion with the GNU intrinsic subroutine.

### Removed
- In `src/gtk-sup.f90`: removed the `f_c_string` interface, which is an aliases of `convert_f_string`, because `f_c_string()` is now also a function defined in the Fortran 2023 standard. See [Issue #294](https://github.com/vmagnin/gtk-fortran/issues/294) and [PR #295](https://github.com/vmagnin/gtk-fortran/pull/295).
- In `cmake/DefaultFlags.cmake`: the GFortran flags were reviewed and simplified. In DEBUG mode, `-std=f2008 -pedantic` were removed and also `-Wtabs` which is already implied by `-Wall`. And `-pthread` is already included into the GTK flags.

### Fixed
- `cmake/DefaultFlags.cmake`: the GNU ld `-rdynamic` option is now passed to all Fortran compilers in UNIX-like systems. Fixes the [Issue #236](https://github.com/vmagnin/gtk-fortran/issues/236): "With Intel ifort/ifx, gtkbuilder, gtkbuilder2 and gtkf-sketcher could not open gtkbuilder.glade".
- gtk-fortran can now be used as an external library via CMake FetchContent. Fixes the [Issue #301](https://github.com/vmagnin/gtk-fortran/issues/301) related to the current binary and source dirs.


## [gtk-fortran 4.8.0] 2025-04-25

This release offers interfaces to GTK 4.18 and GLib 2.84 (generated under Fedora 42 with GTK 4.18.4 and GLib 2.84.1).

### Added
- In `examples/tests_gtk_sup.f90`: added `test_gvalue_routines()`.

### Changed
- CMake 3.10 is now required (it was released in Nov. 2017).

### Fixed
- `src/gtk-sup.f90`: the `GValue` structure is now defined as three 64 bits variables. It fixes the Windows [issue #244](https://github.com/vmagnin/gtk-fortran/issues/244). See the discussion in the gtk3 branch [PR](https://github.com/vmagnin/gtk-fortran/commit/60992129c024e27134f4f31744282311a1656426). Regression tests have been added in `examples/tests_gtk_sup.f90`.


## [gtk-fortran 4.7.1] 2025-03-04

### Fixed
- cfwrapper: the interfaces of 98 functions are fixed ([Issue #290](https://github.com/vmagnin/gtk-fortran/issues/290)). In `cfwrapper/fortran.py`, the block treating the enums was not placed at the end of the `iso_c_binding()` function: first, C pointers toward enums were not recognized as pointers, and secondly enums having a name included in a GTK type name could cause bad bindings (for example `GtkSelectionMode` and `GtkSelectionModel`).


## [gtk-fortran 4.7.0] 2024-11-05
This release offers interfaces to GTK 4.16 and GLib 2.82 (generated under Fedora 41 with GTK 4.16.3 and GLib 2.82.2).

### Added
- `src/gtk-hl-dialog.f90`: can now manage the logo via `gtk_about_dialog_set_logo()`. Contributed by Florian Ober.
- `cfwrapper.py`: the gtk3 branch now also uses `gtkenums-auto.in` and `gtk-auto.in`, following the fpm feature backport.

### Fixed
- cfwrapper: Variant and GVariantType types are now correctly used when declared with a double `*` in C. [Issue #289](https://github.com/vmagnin/gtk-fortran/issues/289).
- `src/gtk-hl-dialog.f90`: if providing artists or documenters, the `cptr` length was erroneously calculated from the number of authors. Contributed by Florian Ober.


## [gtk-fortran 4.6.0] 2024-04-19
This release offers interfaces to GTK 4.14 and GLib 2.80 (generated under Fedora 40 with GTK 4.14.2 and GLib 2.80.0).

### Added
- The `examples/bazaar.f90` program plays a little melody `demo_sound.ogg` when you click on Button1, by using a GtkMediaStream. The GTK 4 GStreamer backend must be installed (`libgtk-4-media-gstreamer` package in Ubuntu). It was tested with `.ogg`, `.wav` and `.mid` files.

### Changed
- `cmake/cmake_uninstall.cmake.in`: improved the code layout.

### Fixed
- `src/gtk-fortran.pc.in`: the line `Libs:` was modified to fix a problem with the macOS linker (which is not GNU ld and does not accept the `-R` option).


## [gtk-fortran 4.5.0] 2023-11-08
This release offers interfaces to GTK 4.12 and GLib 2.78 (generated under Fedora 39 with GTK 4.12.3 and GLib 2.78.1).

### Added
- In `gtk-sup.f90`: the function `convert_f_string_aa()` (interface `f_c_string`) converts a fortran string array into an array of null-terminated C strings.

## [gtk-fortran 4.4.1] 2023-08-31

### Added
- New types (enums) in `src/cfwrapper/scan_types_and_enums.py`, useful for other GNOME libraries.
- Initializes `types_enums.gtk_funptr` list in `src/cfwrapper/scan_types_and_enums.py` with a few funptr types, and removes possibly duplicated ones.
- `examples/menubar.f90`: an accelerator `<Ctrl>q` was added for quitting the application.

### Changed
- `examples/bazaar.f90`: modified the font and background of the textview.

### Fixed
- `src/cfwrapper/fortran.py`: declarations like `const char * const *` must be declared in Fortran as `type(c_ptr), dimension(*) ::`, as they are arrays of C strings (previously, only `**` was considered).


## [gtk-fortran 4.4.0] 2023-05-02
This release offers interfaces to GTK 4.10.3 and GLib 2.76.2.

### Added
- `examples/cairo-tests.f90` now draws the circle *period-2 bulb* and the main cardioid over the Mandelbrot set. More text is also put in the figure.
- `examples/cairo-basics.f90` now also saves the drawing in a SVG file and a PDF file.
- `screenshots/hl_cairo_viewer-fedora38.png`: showing "modern Fortran" written with a New Alphabet font.
- a [new example](https://github.com/vmagnin/gtk-fortran-extra/tree/main/saville_code) has been added in the gtk-fortran-extra repository (MIT license). It is a gtk-fortran application to encode a text using Peter Saville's color code.
- `src/test_extra.sh`: an interactive script to test projects gtk-fortran-extra and gtkzero_fpm before gtk-fortran release.
- `src/cfwrapper/` can be used more easily with other C libraries (see the [tutorial](https://github.com/vmagnin/gtk-fortran/wiki/How-to-hack-the-cfwrapper)):
  - added a `-l` option to add the directories containing the header files and a `-m` option to add the corresponding Fortran modules.
  - added a `-s` option to add a suffix to the functions names.
- `src/cfwrapper/run_tests.py`: for testing some functions of the cfwrapper.
- `src/scan_types_and_enums.py`: the pass 1 was refactored in that class.
- `src/gtk-fortran_types.csv`: list of all the GLib / GTK types used in the prototypes of the C functions. Generated by the `cfwrapper/cfwrapper.py` script.
- `src/gtk-fortran_funptr.csv`: list of all the `funptr` types used in the prototypes of the C functions. Generated by the `cfwrapper/cfwrapper.py` script, which will also print the number of `funptr` in its statistics.
- `LICENSE_EXCEPTION`: the text of the GCC Runtime Library Exception, version 3.1. Note that this exception was chosen in 2011 and was already cited in the header of each source file with the URL of the GNU licenses. Putting the text in the repository is a better practice.

### Changed
- `logo/`: the blue color of the GTK cube, whose HSL (hue, saturation, lightness) values are (211, 49, 63), was replaced by a purple whose hue (270) is the same as the hue of the Fortran logo.
- `src/build.sh` is now an interactive script proposing to build, test and install gtk-fortran. It uses the default Fortran compiler, then build and test with Intel ifx.
- `src/cfwrapper/cleaning.py`: code cleaning and improved layout.

### Fixed
- `examples/hl_cairo_viewer.f90`: the image is now redrawn when the window is resized. And the "Next>" button becomes sensitive when a second file is added.
- `examples/menubar.f90`: the compilation was failing on 32 bits systems, due to an `int64` kind used instead of `c_size_t` (for `gssize`).
- `examples/gio_demo.f90`: a `_c_size_t` suffix added (for a `gssize`).
- `implicit none` was added in all C/Fortran interfaces, as the `implicit none` of the modules do no apply to the interfaces blocks. It will harden the code by allowing the compiler to verify more deeply the coherence of the interfaces generated by the Python wrapper.


## [gtk-fortran 4.3.0] 2022-11-10
This release offers interfaces to GTK 4.8.2 and GLib 2.74.1.

### Added
- `screenshots/Julia_gtk-fortran_animated.gif`: four Julia sets in four OS (Fedora, macOS, FreeBSD, MSYS2/Windows).
- `CITATION.cff` file, used by the GitHub interface.
- `src/extract_hl_doc.py`: generates markdown files for the HL gtk-fortran documentation. Fixes [issue #259](https://github.com/vmagnin/gtk-fortran/issues/259).
- Intel ifx compiler is now supported by CMake (>=3.20), with the id `IntelLLVM`.
- `examples/tests_gtk_sup.f90`: for testing functions of the gtk_sup module.
- `examples/notebooks.f90`: notebooks are now scrollable. And a popup menu appears when clicking with the right button on tabs.
- A new example has been added in the `gtk-fortran-extra` repository (MIT license). It demonstrates how you can use modern Fortran parallel features (coarrays, events, teams, collective routines) with gtk-fortran. It computes a Buddhabrot.
- A new *How to start my own project from a gtk-fortran example?* tutorial, including license considerations.

### Changed
- The Python scripts received minor code improvements suggested by pylint.
- `CMakeLists.txt` files: several minor improvements.
- `examples/notebooks.f90` improved: notebooks are now scrollable, added a popup menu when clicking with the right button on tabs.
- The `examples/gtkbuilder.glade` UI file has been regenerated with Cambalache (`gtkbuilder.cmb` file) and renamed `gtkbuilder.ui`. The widgets were also improved (tooltips, URL link...).
- `gtk-auto.inc` and `gtkenums-auto.inc` are renamed with the `.in` extension because GitHub believes `.inc` is C++. Fixes issue #263.
- Improved code layout in some files, code cleaning, improvements.
- Uses allocatable strings instead of long strings.
- The HL gtk-fortran documentation has been fully reviewed and updated.
- The Wiki documentation has been fully reviewed and refactored: it now uses the Diátaxis framework (Tutorials, How-to, Reference, Explanation).

### Fixed
- `src/cfwrapper/enums.py`: prepared for GTK 4.8 and GLib 2.74. Two regex were  modified to remove correctly three constants. See [issue #266](https://github.com/vmagnin/gtk-fortran/issues/266).
- `cmake/DefaultFlags.cmake`: release and debug flags for non-GFortran compilers were inverted.

## [gtk-fortran 4.2.1] 2022-04-24

### Fixed
- [Issue #257](https://github.com/vmagnin/gtk-fortran/issues/257): `examples/tests.f90`, `examples/bazaar.f90` and `src/gtk-fortran.f90` were crashing (segmentation fault) on macOS because the GLib `g_get_os_info()` function returns NULL on that OS.


## [gtk-fortran 4.2] 2022-04-23
This release offers interfaces to GTK 4.6.2 and GLib 2.72.1.

### Added
- gtk-fortran can now be used as a simple [fpm](https://fpm.fortran-lang.org) dependency (gtk4 branch only). See the [gtkzero_fpm example](https://github.com/vmagnin/gtkzero_fpm). It implied some changes:
    * `gtk-auto.f90` and `gtkenums-auto.f90` are renamed with the `.inc` extension.
    * Removed `mswindowsonly-auto.f90` and `unixonly-auto.f90`, and added `api_compatibility.f90` with the module `gtk_os_dependent` to keep API compatibility.
    * `plplot/plplot_extra_ndef.f90` renamed `plplot_extra.f90` and moved to `src/`.
- `examples/bazaar.f90`: the About button credits the authors of that file. The call to `gtk_about_dialog_set_license()` is replaced by the more convenient `gtk_about_dialog_set_license_type()`.
- A `tutorials/` directory contains the GTK 4 sources used in the Wiki first tutorial.
- `src/gtk-fortran.f90`: prints the GTK and GLib version of the release.
- A [conda repository](https://github.com/conda-forge/gtk-4-fortran-feedstock) for gtk-4-fortran.

### Changed
- Better handling of default compiler flags, using flags like `CMAKE_Fortran_FLAGS_RELEASE_INIT` (CMake>=3.7 required). A file `cmake/DefaultFlags.cmake` was added. Backported to gtk3 branch.
- `gtkbuilder2.f90`: replaced `gtk_builder_add_from_file()` by `gtk_builder_new_from_file()`.
- The syntax was modernized in many places (Fortran 2008).

### Fixed
- `g_application_run()` should be called with an array `[c_null_ptr]` as third argument instead of `c_null_ptr`. Needed with the NAG Fortran compiler. Backported to gtk3 branch.
- `examples/tests.f90`: loop undefined with ifort. And now uses `g_variant_unref()`.
- Various bug fixes.


## [gtk-fortran 3.24.31] 2022-04-21
- The gtk-3-fortran library offers interfaces to GTK 3.24.31 and GLib 2.72.1 (generated with Fedora 36).

### Changed
- Better handling of default compiler flags, using flags like `CMAKE_Fortran_FLAGS_RELEASE_INIT` (CMake>=3.7 required). A file `cmake/DefaultFlags.cmake` was added.

### Fixed
- `g_application_run()` should be called with an array `[c_null_ptr]` as third argument instead of `c_null_ptr`. Needed with the NAG Fortran compiler.


## [gtk-fortran 4.1] 2021-10-22
The gtk-4-fortran library has been generated from GTK 4.4.0 and GLib 2.70.0 under Fedora 35.

### Added
- The cfwrapper has a new required parameter `-v` to set the gtk-fortran semantic version (major.minor.patch). It is written in the `VERSIONS` file (used by CMake, `src/extract_events.pl`, `src/alt_build_test.sh`) and `codemeta.json`. Backported to the gtk3 branch.

### Changed
- The compiler flags for release is now `-O3` instead of `-O3 -mtune=native -march=native`.
- The `-warn nounused` flag was added for ifort.
- The Fortran / C interfaces now use the `import ::` statement instead of `use, intrinsic :: iso_c_binding, only:`.
- In some examples, a module was added to contain the scientific subroutines: `julia_pixbuf.f90`, `mandelbrot_pixbuf.f90`, `cairo-tests.f90`.

### Removed
- `examples/gtkbuilder.f90`: `gtk_builder_connect_signals_full` being removed from GTK 4, this example has become identical to `gtkbuilder2.f90`.


## [gtk-fortran 3.24.30] 2021-09-08
- The gtk-3-fortran library has been generated from GTK 3.24.30 and GLib 2.68.4 under Fedora 34.

### Added
- The cfwrapper has a new required parameter `-v` to set the gtk-fortran semantic version (major.minor.patch). It is written in the `VERSIONS` file (used by CMake, `src/extract_events.pl`, `src/alt_build_test.sh`) and `codemeta.json`.
- A `tutorials/` directory contains the sources and screenshots used in the Wiki new tutorials.

### Changed
- The compiler flags for release is now `-O3` instead of `-O3 -mtune=native -march=native`.
- The Fortran / C interfaces now use the `import ::` statement instead of `use, intrinsic :: iso_c_binding, only:`.


## [gtk-fortran 4.0] 2021-04-28
- The gtk-4-fortran library has been generated from GTK 4.2.0 and GLib 2.68.1 under Fedora 34.
- Starting from this 4.0 release, the project will adhere to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
- All the improvements included in the simultaneously released gtk-fortran 3.24.28 (gtk3 branch) are also in the gtk4 branch.

### Added
- GTK 4 now includes the GSK and graphene libraries: src/gsk-auto.f90 and src/graphene-auto.f90 (see https://developer.gnome.org/gtk4/stable/gtk.html)
- src/gtk.f90: historically, in gtk-fortran g\_signal\_connect() was declared as a subroutine, because the handler\_id returned by the GLib function is usually never used. Here we define both a g\_signal\_connect() function and a subroutine. You will generally use the subroutine in your programs. The function\_g\_signal\_connect\_swapped and g\_signal\_connect\_swapped procedure were also added.
- examples/menubar.f90: a new menu example based on GMenu and GAction.

### Changed
- examples/gtkzero_gapp.f90 is now working.
- examples/gtkhello.f90: new version using GtkApplication.
- Most examples are now using GtkApplication.
- sketcher/sketcher.f90 has been ported to GTK 4, but some problems remains due to deprecated functions: it can not detect signals in the UI file and the toplevel widget detection need improvement.

### Removed
- examples/gtkzero.f90: replaced by gtkzero_gapp.f90.
- examples/gtkhello2.f90: replaced by gtkhello.f90.
- examples/menu.f90 & menu2.f90: based on deprecated APIs.
- examples/hl_radio.f90: based on the GtkRadioButton deprecated API.
- src/atk-auto.f90: removed from GTK 4 (deprecated API).
- src/gtk-hl-accelerator.f90: deprecated API.
- src/gtk-hl-menu.f90 and examples/hl_menu.f90: deprecated API.
- src/gtk-hl-chooser.f90, bazaar.f90, hl_choosers.f90: GtkFileChooserButton has been removed from GTK 4.
- meson.build experimental files were removed. They are now apart in the gtk4-dev-meson branch.


## [gtk-fortran 3.24.28] - 2021-04-28

### Added
- examples/regex.f90: a new example demonstrating GLib regular expressions functions.
- src/gtk-fortran.f90: a gtk-?-fortran command to show information about the library.
- examples/pixbuf\_without\_gui.f90: a new example drawing a Sierpinski triangle in a PNG file, without using a GUI.

### Changed
- cfwrapper.py is now writing the path and name of each C header file in the *-auto.f90 files.
- cfwrapper.py is now systematically launching extract_events.pl.
- cfwrapper.py is now updating the codemeta.json file (dateModified field).
- VERSIONS: the name of the distribution used to generate gtk-fortran is now automatically found.

### Fixed
- src/CMakeLists.txt: added unix-print-auto.f90 which was missing.

### Security
- For intrinsic modules, all the `use` statements have been replaced by `use, intrinsic ::`.


## [gtk-fortran 20.04] - 2020-05-07
The main objective of this release was to clean up the code and prepare it for the future GTK 4 branch.

### Changed
- gtk3 branch based on **GTK 3.24.18, GLib 2.64.2,** generated under Lubuntu 20.04 x86_64.
- CMake>=3.4 required.
- cmake/cmake_uninstall.cmake.in: updated with the latest code from https://gitlab.kitware.com/cmake/community/-/wikis/FAQ#can-i-do-make-uninstall-with-cmake
- CMake now uses GNUInstallDirs for the lib dir. On some systems, like Fedora, it will be lib64, on others lib.
- bash scripts syntax has been improved, using shellcheck.
- test.sh has been renamed alt_build_test.sh
- The master branch has been renamed gtk2.
- src/gdkevents-auto3.f90: no reason to indicate the GTK version for that file. The "3" was removed.
- src/gtk-3-fortran.pc.in => src/gtk-fortran.pc.in: improved pkg-config file.
- README-high-level now using Markdown: README-high-level.md
- src/usemodules.pl: can now be used directly from that directory, without make install.
- Examples: code clean up. Some deprecated GTK 3 functions have been removed to prepare for GTK 4.

### Added
- Experimental and uncomplete `meson.build` files have been added. Meson>=0.53 is needed. Commands are `meson buildmeson` and `ninja -C buildmeson`. The gtk-fortran library can be inst	alled using `sudo ninja -C buildmeson install`, but there is still some problems for installing the `.mod` files (see https://github.com/mesonbuild/meson/issues/5374). Please use CMake for production !
- examples/menu2.f90: the menu.f90 example is based on deprecated functions.
- examples/gtkzero_gapp.f90: an empty GTK window based on GtkApplication and GApplication.
- CMake -D NO_BUILD_HL=true option to disable building the High Level sub-library (which includes PLplot and sketcher).
- VERSIONS: a CSV file with the gtk-fortran, GTK, GLib and Ubuntu versions. Automatically created by the cfwrapper.py script. It will be used by the building system of the project.

### Removed
- Gtkextra directory: that directory was not maintained for 9 years, the gtkextra library is not maintained anymore and is based on GTK 2. The gtksheet part was forked (https://github.com/fpaquet/gtksheet), but it is necessary to reduce the amount of work to maintain gtk-fortran. So it was removed from the gtk3 branch.
- Doxygen dependence. It was introduced at the beginning of the gtk-fortran project but never used.
- win32_install.bat: this file was last updated in 2013 and may be brokken. You should instead install MSYS2 under Windows and follow the instructions on the wiki.
- cmake/FindPlplotF95.cmake: deprecated module to find the PLplot library (does not work with PLplot>=5.11 released the 2015-04-12).
- cmake/CheckFortranSourceCompiles.cmake: this macro is included in CMake since 3.1 version.
- cmake/FindGTK3.cmake: PkgConfig is used instead.
- test.bat: a deprecated script to build gtk-fortran (GTK 2) under Windows.
- The test/ directory containing the run_all.pl script. You can use CTest instead (see the wiki).
- Deprecated functions, to be ready for GTK 4.
- gtk-\*hl-\*-tmpl.f90 files: the gtk-\*hl-\*.f90 will be fully managed by git, instead of being generated from these templates.
- mk_gtk_hl.pl: that script was used to manage GTK 2 & 3 differences in the gtk-\*hl-\*.f90 files.

### Fixed
- src/usemodules.py was printing false deprecated functions alerts in the hl files of the src directory.
- Updated gtkbuilder.glade to use GTK 3 interface.


## [gtk-fortran 19.04] - 2019-04-24
### Added
- The `cfwrapper.py` detects the status of each function (AVAILABLE or DEPRECATED) and writes it in the `*-auto.f90` files and in `gtk-fortran-index.csv`. It will help to remove deprecated functions during the GTK 4 migration. Developers can use the `-d` argument to remove DEPRECATED functions from the library: using `make -i` will then show errors for each deprecated function used in the project.
- The `usemodules.py` script prints warnings when deprecated functions are found in Fortran files, and tries to split `USE` lines cleanly.
- A `show_versions.sh` script that shows the versions of the main tools and libraries used in gtk-fortran. Useful for gtk-fortran developers or for reporting bugs.
- A `README` file in each directory, explaining the role of each file.
- Parallel building (gtk3) using `make -j` or `make --jobs`. On some systems, like FreeBSD, the number of jobs must be given: `make -j 4` for example. By [@ChinouneMehdi](https://github.com/ChinouneMehdi).
- A video quickstart guide on the Wiki.
- A `is_UNIX_OS()` function in `gtk-sup.f90`.
- This `CHANGELOG.md` file.
- gtk-fortran can now be cited: Vincent MAGNIN, James TAPPIN, Jens HUNGER, Jerry DE LISLE, "gtk-fortran: a GTK+ binding to build Graphical User Interfaces in Fortran", Journal of Open Source Software, 4(34), 1109, 12th January 2019, https://doi.org/10.21105/joss.01109

### Changed
- gtk3 branch based on **GTK 3.24.8, GLib 2.60.0,** generated with Ubuntu 19.04 x86_64, PLplot>=5.13.
- master (GTK 2) branch based on **GTK 2.24.32, GLib 2.60.0,** generated with Ubuntu 19.04 x86_64, PLplot<=5.10.
- The `cfwrapper.py` script has been moved in the `src/cfwrapper` directory, and splitted
in several modules to ease maintenance.
- Major revision of the PLplot part (code and documentation) in the gtk3 branch: PLplot>=5.13 is now required. And it runs under MSYS2/Windows. The gtk2 branch will keep PLplot<=5.10.
- Major update of the Wiki documentation.
- New examples: `gtkzero.f90` (just a window) and `gtkhello.f90` (two buttons).
- Updated examples.
- The default branch is now gtk3. The master (gtk2) branch should not be used for new projects.
- The gtk-fortran repository URL is now https://github.com/vmagnin/gtk-fortran. The URL https://github.com/jerryd/gtk-fortran is automatically redirected to the new URL. So it is transparent to the user. You are not obliged to modify it in your git settings, but if you want, type: `git remote set-url origin git@github.com:vmagnin/gtk-fortran.git`
- Doxygen (not yet used in the project) is optional.

### Removed
- old stuff in the `plplot/` directory.
- `old-cfwrapper.py`: a previous Python 2 version of the wrapper, last modified in 2013.

### Deprecated
- `cmake/FindPlplotF95.cmake`: deprecated module to find the PLplot<=5.10 library.

### Fixed
- The `cfwrapper.py` script can now scan the `gstdio.h` and `giochannel.h` files, except for the `g_io_channel_win32_new_messages()` function which can be declared with two different parameters types.
- Less warnings in Debug mode.
- Fixed some bugs in examples.
- The PLplot examples now work under MSYS2.
- `gtkf-sketcher.f90` now works under MSYS2.


## [gtk-fortran 17.10] - 2018-05-01
### Changed
- GTK 3.22.25, GLib 2.54.1
- GTK 2.24.31, GLib 2.54.1

## [gtk-fortran 16.10] - 2017-01-09
### Changed
- GTK 3.20.9,  GLib 2.50.2
- GTK 2.24.30, GLib 2.50.2
- The code of the heart of gtk-fortran, the `cfwrapper.py` script, has been refactored and improved in order to ease maintenance.
- CMake files have been unified in master (gtk2) and gtk3 branches.

## [gtk-fortran 16.04] - 2016-06-15
### Changed
- GTK 3.18.9,  GLib 2.48.0
- GTK 2.24.30, GLib 2.48.0

## [gtk-fortran 13.10]
### Changed
- GTK 3.10.1
- GTK 2.24.22

## [first commit] - 2011-01-10
### Added
- Creation of the github repository by [@jerryd](https://github.com/jerryd/).


================================================
FILE: CITATION.cff
================================================
# This CITATION.cff file was generated with cffinit.
# Visit https://bit.ly/cffinit to generate yours today!

cff-version: 1.2.0
title: gtk-fortran
message: >-
  If you use this software, please cite it using the
  metadata from this file.
type: software
authors:
  - given-names: Vincent
    family-names: Magnin
    email: vincent.magnin@univ-lille.fr
    affiliation: Lille University (France)
    orcid: 'https://orcid.org/0000-0002-9016-9955'
  - given-names: James
    family-names: Tappin
    affiliation: >-
      RAL Space, STFC Rutherford Appleton Laboratory,
      Harwell Campus​, Didcot,Oxfordshire OX11 0QX,
      United Kingdom
    orcid: 'https://orcid.org/0000-0002-1878-5243'
  - given-names: Jens
    family-names: Hunger
    affiliation: >-
      Technische Universität Dresden, Department of
      Chemistry and Food Chemistry, Dresden, Germany
    orcid: 'https://orcid.org/0000-0001-7639-1229'
  - given-names: Jerry
    name-particle: De
    family-names: Lisle
    affiliation: 'GFortran team, USA'
identifiers:
  - type: doi
    value: 10.21105/joss.01109
    description: The paper about gtk-fortran
repository-code: 'https://github.com/vmagnin/gtk-fortran'
url: 'https://github.com/vmagnin/gtk-fortran/wiki'
abstract: >-
  The gtk-fortran project provides bindings to the
  Fortran language for the GTK libraries (GTK, Cairo,
  GdkPixbuf, GLib...) and is licensed under GNU GPLv3
  (with GCC Runtime Library Exception 3.1, see Licenses for more details). 
  Like GTK and Fortran, it is cross-platform (Linux, macOS, BSD, Windows).
keywords:
  - Fortran GTK binding GUI
license: GPL-3.0-or-later WITH GCC-exception-3.1
preferred-citation:
  type: article
  authors:
  - given-names: Vincent
    family-names: Magnin
    email: vincent.magnin@univ-lille.fr
    affiliation: Lille University (France)
    orcid: 'https://orcid.org/0000-0002-9016-9955'
  - given-names: James
    family-names: Tappin
    affiliation: >-
      RAL Space, STFC Rutherford Appleton Laboratory,
      Harwell Campus​, Didcot,Oxfordshire OX11 0QX,
      United Kingdom
    orcid: 'https://orcid.org/0000-0002-1878-5243'
  - given-names: Jens
    family-names: Hunger
    affiliation: >-
      Technische Universität Dresden, Department of
      Chemistry and Food Chemistry, Dresden, Germany
    orcid: 'https://orcid.org/0000-0001-7639-1229'
  - given-names: Jerry
    name-particle: De
    family-names: Lisle
    affiliation: 'GFortran team, USA'
  doi: "10.21105/joss.01109"
  journal: "Journal of Open Source Software"
  month: 1
  start: 1 # First page number
  end: 3 # Last page number
  title: "gtk-fortran: a GTK+ binding to build Graphical User Interfaces in Fortran"
  issue: 34
  volume: 4
  year: 2019


================================================
FILE: CMakeLists.txt
================================================
# This file is part of gtk-fortran, a GTK / Fortran interface library.
# Copyright (C) 2011 The gtk-fortran team
#
# This is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# This software is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# Under Section 7 of GPL version 3, you are granted additional
# permissions described in the GCC Runtime Library Exception, version
# 3.1, as published by the Free Software Foundation.
#
# You should have received a copy of the GNU General Public License along with
# this program; see the files LICENSE and LICENSE_EXCEPTION respectively.
# If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# Contributed by Kyle Horne: 05.11.2011
# Last modifications: James Tappin 8/17/2012, Jens Hunger 01/07/2018,
# vmagnin 2025-05-28
#
# CMAKE build file for gtk-fortran
# Options:
# -D CMAKE_BUILD_TYPE=debug
# -D EXCLUDE_PLPLOT=true
# -D NO_BUILD_EXAMPLES=true
# -D NO_BUILD_HL=true
# -D INSTALL_EXAMPLES=true

# CMake 3.10 was released in November 2017:
cmake_minimum_required(VERSION 3.10)

# Include overwrites before setting up the project
set(CMAKE_USER_MAKE_RULES_OVERRIDE ${CMAKE_CURRENT_SOURCE_DIR}/cmake/DefaultFlags.cmake)

project(gtk-fortran Fortran)

set(CMAKE_PROJECT_DESCRIPTION "A GTK / Fortran binding")
set(CMAKE_PROJECT_HOMEPAGE_URL "https://github.com/vmagnin/gtk-fortran/wiki/")

message(STATUS "Compiler: ${CMAKE_Fortran_COMPILER_ID} ${CMAKE_Fortran_COMPILER_VERSION} ${CMAKE_Fortran_COMPILER}")
message(STATUS "Linker: ${CMAKE_Fortran_COMPILER_LINKER_ID} ${CMAKE_Fortran_COMPILER_LINKER_VERSION} ${CMAKE_Fortran_COMPILER_LINKER}")
# Print system, version and path:
message(STATUS "System: ${CMAKE_SYSTEM_NAME} ${CMAKE_SYSTEM_VERSION} ${CMAKE_SYSTEM_PROCESSOR}")

#===============================================================================
# Version of gtk-fortran for the current branch (from VERSIONS file):
#===============================================================================
file(STRINGS VERSIONS OneLine REGEX "gtk-fortran;(.*)")
string(REGEX REPLACE "gtk-fortran;" "" SEMANTIC_VERSION ${OneLine})
# Major, minor and patch versions of gtk-fortran:
string(REGEX MATCH "[0-9]+" GTKv ${SEMANTIC_VERSION})
string(REGEX REPLACE "[0-9]+\.([0-9]+)\.[0-9]+" "\\1" MINOR_VERSION ${SEMANTIC_VERSION})
string(REGEX REPLACE "[0-9]+\.[0-9]+\.([0-9]+)" "\\1" PATCH_VERSION ${SEMANTIC_VERSION})

set(gtk_V_fortran "gtk-${GTKv}-fortran")
message(STATUS "Building ${gtk_V_fortran} ${SEMANTIC_VERSION}")

if (${GTKv} LESS_EQUAL 3)
    set(GTKname "gtk+-${GTKv}.0")
else()
    set(GTKname "gtk${GTKv}")
endif()

set(CMAKE_PROJECT_VERSION_MAJOR ${GTKv})
set(CMAKE_PROJECT_VERSION_MINOR ${MINOR_VERSION})
set(CMAKE_PROJECT_VERSION_PATCH ${PATCH_VERSION})

# Extracting the GTK and GLib versions from the VERSIONS file:
file(STRINGS VERSIONS OneLine REGEX "GTK;(.*)")
string(REGEX REPLACE "GTK;" "" GTK_SEMANTIC_VERSION ${OneLine})
file(STRINGS VERSIONS OneLine REGEX "GLib;(.*)")
string(REGEX REPLACE "GLib;" "" GLIB_SEMANTIC_VERSION ${OneLine})
message(STATUS "  offering interfaces to GTK ${GTK_SEMANTIC_VERSION} and GLib ${GLIB_SEMANTIC_VERSION}")

#===============================================================================
# Default build type is release
# Uncomment this to debug or use "cmake -D CMAKE_BUILD_TYPE=debug .."
#===============================================================================
# set(CMAKE_BUILD_TYPE debug)
if (NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE release)
endif()

#===============================================================================
# Setting compilation flags for various compilers and build types:
#===============================================================================
string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE)
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")

# Print compilation flags :
if(CMAKE_Fortran_FLAGS OR CMAKE_Fortran_FLAGS_${CMAKE_BUILD_TYPE})
  message(STATUS "Compilation flags (general and build type specific):")
  message(STATUS "  CMAKE_Fortran_FLAGS: ${CMAKE_Fortran_FLAGS}")
  message(STATUS "  CMAKE_Fortran_FLAGS_${CMAKE_BUILD_TYPE}: ${CMAKE_Fortran_FLAGS_${CMAKE_BUILD_TYPE}}")
endif()

#===============================================================================
# Package generation:
#===============================================================================
set(CPACK_PACKAGE_CHECKSUM SHA256)
set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
set(CPACK_RESOURCE_FILE_README "${PROJECT_SOURCE_DIR}/README.md")
set(CPACK_GENERATOR "TGZ")
set(CPACK_SOURCE_GENERATOR "TGZ")
include(CPack)

#===============================================================================
# "Path for CMake modules to be loaded by the include() or find_package()
# commands before checking the default modules that come with CMake"
#===============================================================================
set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")

#===============================================================================
# Uninstall target:
# Generic code adapted from
# https://gitlab.kitware.com/cmake/community/-/wikis/FAQ#can-i-do-make-uninstall-with-cmake
#===============================================================================
if(NOT TARGET uninstall)
    # configure_file() copies a file and substitutes @VAR@ or ${VAR}
    # @ONLY means only @VAR@ will be sustituted
    # https://cmake.org/cmake/help/latest/command/configure_file.html
    configure_file(
        "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
        "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
        @ONLY)

    add_custom_target(uninstall
        COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
endif()

#===============================================================================
# Examples can be tested via make test:
#===============================================================================
enable_testing()

#===============================================================================
# Find all GTK libraries:
#===============================================================================
# Use PkgConfig:
find_package(PkgConfig REQUIRED)
pkg_check_modules(GTK REQUIRED ${GTKname})
# Setup CMake to use GTK, tell the compiler where to look for headers
# and to the linker where to look for libraries:
include_directories(${GTK_INCLUDE_DIRS})
link_directories(${GTK_LIBRARY_DIRS})

#===============================================================================
# Add other flags to the compiler
#===============================================================================
# https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_COMPILER_ID.html
# For the new Flang compiler and LFortran, first remove unknown flags (no ";" if at the end):
if(CMAKE_Fortran_COMPILER_ID STREQUAL "LLVMFlang")
  string(REGEX REPLACE "-mfpmath=sse;?" "" GTK_CFLAGS_OTHER "${GTK_CFLAGS_OTHER}")
  string(REGEX REPLACE "-msse2;?" "" GTK_CFLAGS_OTHER "${GTK_CFLAGS_OTHER}")
  # Order matters for the following regex!
  string(REGEX REPLACE "-msse;?" "" GTK_CFLAGS_OTHER "${GTK_CFLAGS_OTHER}")
elseif(CMAKE_Fortran_COMPILER_ID STREQUAL "LFortran")
  string(REGEX REPLACE "-mfpmath=sse;?" "" GTK_CFLAGS_OTHER "${GTK_CFLAGS_OTHER}")
  string(REGEX REPLACE "-msse2;?" "" GTK_CFLAGS_OTHER "${GTK_CFLAGS_OTHER}")
  # Order matters for the following regex!
  string(REGEX REPLACE "-msse;?" "" GTK_CFLAGS_OTHER "${GTK_CFLAGS_OTHER}")
  string(REGEX REPLACE "-pthread;?" "" GTK_CFLAGS_OTHER "${GTK_CFLAGS_OTHER}")
endif()
# TODO: replace add_definitions() by add_compile_options() when CMake>=3.12 will be required: https://cmake.org/cmake/help/latest/command/add_compile_options.html#command:add_compile_options
add_definitions(${GTK_CFLAGS_OTHER})

message(STATUS "Other compilation flags needed by GTK: ${GTK_CFLAGS_OTHER}")
message(STATUS "GTK_INCLUDE_DIRS: ${GTK_INCLUDE_DIRS}")
message(STATUS "GTK_LIBRARY_DIRS: ${GTK_LIBRARY_DIRS}")

#===============================================================================
# PLplot integration (>=5.13 needed)
# ----------------------------------
# A lot of changes have occured in PLplot 5.11, 5.12 and 5.13: the libraries
# have been renamed (plplot and plplot-fortran) and the ISO_C_BINDING has been
# adopted.
# By now (March 2019), the find_package(plplot) command gives a lot of errors
# in Debian/Ubuntu distributions because of some renaming in Debian packages.
# As a temporary (?) workaround, we are now using pkg-config.
# If a CMake error occurs, add -D EXCLUDE_PLPLOT=true to your CMake command.
#===============================================================================
if (NOT EXCLUDE_PLPLOT AND NOT NO_BUILD_HL)
    pkg_check_modules(PLPLOT-FORTRAN REQUIRED plplot-fortran)
    pkg_check_modules(PLPLOT REQUIRED plplot)

    # Setup CMake to use PLplot, tell the compiler where to look for headers
    # and to the linker where to look for libraries:
    include_directories(${PLPLOT-FORTRAN_INCLUDE_DIRS})
    link_directories(${PLPLOT-FORTRAN_LIBRARY_DIRS})
    # Add other flags to the compiler:
    add_definitions(${PLPLOT-FORTRAN_CFLAGS_OTHER})
    message(STATUS "Other compilation flags needed by PLplot: ${PLPLOT-FORTRAN_CFLAGS_OTHER}")
    message(STATUS "PLPLOT-FORTRAN_INCLUDE_DIRS: ${PLPLOT-FORTRAN_INCLUDE_DIRS}")
    message(STATUS "PLPLOT-FORTRAN_LIBRARY_DIRS: ${PLPLOT-FORTRAN_LIBRARY_DIRS}")

    set(LIBRARIES ${LIBRARIES} ${PLPLOT_LIBRARIES})
    include_directories(${PLPLOT_INCLUDE_DIRS})
    message(STATUS "PLPLOT_INCLUDE_DIRS: ${PLPLOT_INCLUDE_DIRS}")
    set(CMAKE_REQUIRED_LIBRARIES "${PLPLOT_LIBRARIES}")
    set(CMAKE_REQUIRED_INCLUDES "${PLPLOT-FORTRAN_INCLUDE_DIRS}")
else(NOT EXCLUDE_PLPLOT AND NOT NO_BUILD_HL)
    message(STATUS ">>> PLPLOT excluded as command option")
endif(NOT EXCLUDE_PLPLOT AND NOT NO_BUILD_HL)

#===============================================================================
# Define GNU standard installation directories:
#===============================================================================
include(GNUInstallDirs)
message(STATUS "GNUInstallDirs: ${CMAKE_INSTALL_PREFIX} ${CMAKE_INSTALL_LIBDIR} ${CMAKE_INSTALL_INCLUDEDIR} ${CMAKE_INSTALL_BINDIR} ${CMAKE_INSTALL_DATAROOTDIR} ${CMAKE_INSTALL_MANDIR}")

#===============================================================================
# Add subdirectories to build:
#===============================================================================
add_subdirectory(src)
add_subdirectory(examples)

if(NOT NO_BUILD_HL)
    add_subdirectory(sketcher)

    if(PLPLOT_FOUND AND NOT EXCLUDE_PLPLOT)
        add_subdirectory(plplot)
    endif(PLPLOT_FOUND AND NOT EXCLUDE_PLPLOT)
else(NOT NO_BUILD_HL)
    message(STATUS ">>> High Level API excluded as command option")
endif(NOT NO_BUILD_HL)


================================================
FILE: INSTALL.md
================================================
Last update: 2025-03-07

Dependencies
================================

If you want to use gtk-fortran as a fpm dependency, you just need:
- A modern Fortran compiler (>= Fortran 2008 standard), for example gfortran, ifort, ifx...
- GTK and the associated development files. For 4.x use the "gtk4" branch.
- The Fortran Package Manager [fpm](https://fpm.fortran-lang.org).

If you want to build and install the whole project (library, tools, examples...), you also need:
- CMake (>=3.10) and pkg-config.
- PLplot (>=5.13) is used if available (you need the development files).

Using gtk-fortran as a fpm dependency
================================

Starting from version 4.2, gtk-fortran can be used as a [fpm](https://fpm.fortran-lang.org) dependency. You simply need to add gtk-fortran in the dependencies section of the `fpm.toml` manifest of your project:

```toml
[dependencies]
gtk-fortran = { git = "https://github.com/vmagnin/gtk-fortran.git", branch = "gtk4" }
```

See the [gtkzero_fpm example](https://github.com/vmagnin/gtkzero_fpm) (MIT license) for a demonstration.


Building & installing gtk-fortran
================================

The build install system uses `cmake`. This file gives quick instructions to install gtk-fortran. **See the [Wiki documentation](https://github.com/vmagnin/gtk-fortran/wiki#installation-and-building) for more detailed instructions.**

UNIX/Linux
----------

To do an "out of source" build from the top-level directory on a
Unix/Linux system:

    mkdir build && cd build
    cmake ..
    make
    sudo make install

If the building of some examples causes an error, you can ignore them with
the `-i` option:

    make -i

cmake variables are set by using `-D<variable>=<value>`, for example to change the default install directory from `/usr/local` to `/usr`:

    cmake -DCMAKE_INSTALL_DIR=/usr ..

Useful variables that are specific to gtk-fortran are:

       EXCLUDE_PLPLOT -- set this to disable building the plplot
         integration even if PLplot is found.
       NO_BUILD_HL -- set this to disable building the High Level sub-library
         (includes PLplot and sketcher).
       NO_BUILD_EXAMPLES -- set this to prevent compiling the example
         programs, also mostly useful for packagers.
       INSTALL_EXAMPLES -- set this to install the source code of the
         examples into
         ${CMAKE_INSTALL_DATAROOTDIR/gtk-fortran/examples<gtkversion>,
         this would for example be useful if you were making a binary
         package of gtk-fortran.

To interactively control the build, use `ccmake` in place of `cmake`

Default compiler options can be overridden, for example:

    cmake -D CMAKE_Fortran_FLAGS_RELEASE="-O2 -std=f2018" ..

The system default Fortran compiler can be overridden, for example to use the Intel ifx compiler:

    cmake -D CMAKE_Fortran_COMPILER:FILEPATH=$(which ifx) ..

**************************************************************************
Sometimes it can help to clean out the build directory and re-run `cmake`:

     cd build
     rm -r *   ## MAKE SURE YOU ARE IN THE BUILD DIRECTORY BEFORE DOING THIS
     cmake ..
**************************************************************************

Other systems (Windows, macOS, FreeBSD...)
-------

See the Wiki documentation for specific and detailed instructions.

Known issues
------------

You can see or post issues on this page:

https://github.com/vmagnin/gtk-fortran/issues

Building your application
=========================

On Linux and Unix systems the build system generates a pkg-config file
and installs it. So building a single source file application should be
as simple as:

    gfortran my_app.f90 $(pkg-config --cflags --libs gtk-4-fortran)

If you have made a default install to `/usr/local` you *may* need to run:

    export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig

(Or

    setenv PKG_CONFIG_PATH /usr/local/lib/pkgconfig

if you use csh or one of its derivatives)

this will depend on your distribution, Ubuntu looks there by default,
Pardus and Manjaro don't.

Uninstalling gtk-fortran
========================

    sudo make uninstall

See https://gitlab.kitware.com/cmake/community/-/wikis/FAQ#can-i-do-make-uninstall-with-cmake

More informations
=================

See the documentation: https://github.com/vmagnin/gtk-fortran/wiki


================================================
FILE: LICENSE
================================================
                    GNU GENERAL PUBLIC LICENSE
                       Version 3, 29 June 2007

 Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

                            Preamble

  The GNU General Public License is a free, copyleft license for
software and other kinds of works.

  The licenses for most software and other practical works are designed
to take away your freedom to share and change the works.  By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.  We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors.  You can apply it to
your programs, too.

  When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.

  To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights.  Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.

  For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received.  You must make sure that they, too, receive
or can get the source code.  And you must show them these terms so they
know their rights.

  Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.

  For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software.  For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.

  Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so.  This is fundamentally incompatible with the aim of
protecting users' freedom to change the software.  The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable.  Therefore, we
have designed this version of the GPL to prohibit the practice for those
products.  If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.

  Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary.  To prevent this, the GPL assures that
patents cannot be used to render the program non-free.

  The precise terms and conditions for copying, distribution and
modification follow.

                       TERMS AND CONDITIONS

  0. Definitions.

  "This License" refers to version 3 of the GNU General Public License.

  "Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.

  "The Program" refers to any copyrightable work licensed under this
License.  Each licensee is addressed as "you".  "Licensees" and
"recipients" may be individuals or organizations.

  To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy.  The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.

  A "covered work" means either the unmodified Program or a work based
on the Program.

  To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy.  Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.

  To "convey" a work means any kind of propagation that enables other
parties to make or receive copies.  Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.

  An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License.  If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.

  1. Source Code.

  The "source code" for a work means the preferred form of the work
for making modifications to it.  "Object code" means any non-source
form of a work.

  A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.

  The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form.  A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.

  The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities.  However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work.  For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.

  The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.

  The Corresponding Source for a work in source code form is that
same work.

  2. Basic Permissions.

  All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met.  This License explicitly affirms your unlimited
permission to run the unmodified Program.  The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work.  This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.

  You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force.  You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright.  Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.

  Conveying under any other circumstances is permitted solely under
the conditions stated below.  Sublicensing is not allowed; section 10
makes it unnecessary.

  3. Protecting Users' Legal Rights From Anti-Circumvention Law.

  No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.

  When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.

  4. Conveying Verbatim Copies.

  You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.

  You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.

  5. Conveying Modified Source Versions.

  You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:

    a) The work must carry prominent notices stating that you modified
    it, and giving a relevant date.

    b) The work must carry prominent notices stating that it is
    released under this License and any conditions added under section
    7.  This requirement modifies the requirement in section 4 to
    "keep intact all notices".

    c) You must license the entire work, as a whole, under this
    License to anyone who comes into possession of a copy.  This
    License will therefore apply, along with any applicable section 7
    additional terms, to the whole of the work, and all its parts,
    regardless of how they are packaged.  This License gives no
    permission to license the work in any other way, but it does not
    invalidate such permission if you have separately received it.

    d) If the work has interactive user interfaces, each must display
    Appropriate Legal Notices; however, if the Program has interactive
    interfaces that do not display Appropriate Legal Notices, your
    work need not make them do so.

  A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit.  Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.

  6. Conveying Non-Source Forms.

  You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:

    a) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by the
    Corresponding Source fixed on a durable physical medium
    customarily used for software interchange.

    b) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by a
    written offer, valid for at least three years and valid for as
    long as you offer spare parts or customer support for that product
    model, to give anyone who possesses the object code either (1) a
    copy of the Corresponding Source for all the software in the
    product that is covered by this License, on a durable physical
    medium customarily used for software interchange, for a price no
    more than your reasonable cost of physically performing this
    conveying of source, or (2) access to copy the
    Corresponding Source from a network server at no charge.

    c) Convey individual copies of the object code with a copy of the
    written offer to provide the Corresponding Source.  This
    alternative is allowed only occasionally and noncommercially, and
    only if you received the object code with such an offer, in accord
    with subsection 6b.

    d) Convey the object code by offering access from a designated
    place (gratis or for a charge), and offer equivalent access to the
    Corresponding Source in the same way through the same place at no
    further charge.  You need not require recipients to copy the
    Corresponding Source along with the object code.  If the place to
    copy the object code is a network server, the Corresponding Source
    may be on a different server (operated by you or a third party)
    that supports equivalent copying facilities, provided you maintain
    clear directions next to the object code saying where to find the
    Corresponding Source.  Regardless of what server hosts the
    Corresponding Source, you remain obligated to ensure that it is
    available for as long as needed to satisfy these requirements.

    e) Convey the object code using peer-to-peer transmission, provided
    you inform other peers where the object code and Corresponding
    Source of the work are being offered to the general public at no
    charge under subsection 6d.

  A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.

  A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling.  In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage.  For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product.  A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.

  "Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source.  The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.

  If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information.  But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).

  The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed.  Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.

  Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.

  7. Additional Terms.

  "Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law.  If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.

  When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it.  (Additional permissions may be written to require their own
removal in certain cases when you modify the work.)  You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.

  Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:

    a) Disclaiming warranty or limiting liability differently from the
    terms of sections 15 and 16 of this License; or

    b) Requiring preservation of specified reasonable legal notices or
    author attributions in that material or in the Appropriate Legal
    Notices displayed by works containing it; or

    c) Prohibiting misrepresentation of the origin of that material, or
    requiring that modified versions of such material be marked in
    reasonable ways as different from the original version; or

    d) Limiting the use for publicity purposes of names of licensors or
    authors of the material; or

    e) Declining to grant rights under trademark law for use of some
    trade names, trademarks, or service marks; or

    f) Requiring indemnification of licensors and authors of that
    material by anyone who conveys the material (or modified versions of
    it) with contractual assumptions of liability to the recipient, for
    any liability that these contractual assumptions directly impose on
    those licensors and authors.

  All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10.  If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term.  If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.

  If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.

  Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.

  8. Termination.

  You may not propagate or modify a covered work except as expressly
provided under this License.  Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).

  However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.

  Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.

  Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License.  If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.

  9. Acceptance Not Required for Having Copies.

  You are not required to accept this License in order to receive or
run a copy of the Program.  Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance.  However,
nothing other than this License grants you permission to propagate or
modify any covered work.  These actions infringe copyright if you do
not accept this License.  Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.

  10. Automatic Licensing of Downstream Recipients.

  Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License.  You are not responsible
for enforcing compliance by third parties with this License.

  An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations.  If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.

  You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License.  For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.

  11. Patents.

  A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based.  The
work thus licensed is called the contributor's "contributor version".

  A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version.  For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.

  Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.

  In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement).  To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.

  If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients.  "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.

  If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.

  A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License.  You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.

  Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.

  12. No Surrender of Others' Freedom.

  If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all.  For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.

  13. Use with the GNU Affero General Public License.

  Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work.  The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.

  14. Revised Versions of this License.

  The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time.  Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.

  Each version is given a distinguishing version number.  If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation.  If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.

  If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.

  Later license versions may give you additional or different
permissions.  However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.

  15. Disclaimer of Warranty.

  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

  16. Limitation of Liability.

  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.

  17. Interpretation of Sections 15 and 16.

  If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.

                     END OF TERMS AND CONDITIONS

            How to Apply These Terms to Your New Programs

  If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.

  To do so, attach the following notices to the program.  It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.

    <one line to give the program's name and a brief idea of what it does.>
    Copyright (C) <year>  <name of author>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

Also add information on how to contact you by electronic and paper mail.

  If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:

    <program>  Copyright (C) <year>  <name of author>
    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
    This is free software, and you are welcome to redistribute it
    under certain conditions; type `show c' for details.

The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License.  Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".

  You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.

  The GNU General Public License does not permit incorporating your program
into proprietary programs.  If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library.  If this is what you want to do, use the GNU Lesser General
Public License instead of this License.  But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.


================================================
FILE: LICENSE_EXCEPTION
================================================
GCC RUNTIME LIBRARY EXCEPTION

Version 3.1, 31 March 2009

Copyright (C) 2009 Free Software Foundation, Inc. <http://fsf.org/>

Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.

This GCC Runtime Library Exception ("Exception") is an additional
permission under section 7 of the GNU General Public License, version
3 ("GPLv3"). It applies to a given file (the "Runtime Library") that
bears a notice placed by the copyright holder of the file stating that
the file is governed by GPLv3 along with this Exception.

When you use GCC to compile a program, GCC may combine portions of
certain GCC header files and runtime libraries with the compiled
program. The purpose of this Exception is to allow compilation of
non-GPL (including proprietary) programs to use, in this way, the
header files and runtime libraries covered by this Exception.

0. Definitions.

A file is an "Independent Module" if it either requires the Runtime
Library for execution after a Compilation Process, or makes use of an
interface provided by the Runtime Library, but is not otherwise based
on the Runtime Library.

"GCC" means a version of the GNU Compiler Collection, with or without
modifications, governed by version 3 (or a specified later version) of
the GNU General Public License (GPL) with the option of using any
subsequent versions published by the FSF.

"GPL-compatible Software" is software whose conditions of propagation,
modification and use would permit combination with GCC in accord with
the license of GCC.

"Target Code" refers to output from any compiler for a real or virtual
target processor architecture, in executable form or suitable for
input to an assembler, loader, linker and/or execution
phase. Notwithstanding that, Target Code does not include data in any
format that is used as a compiler intermediate representation, or used
for producing a compiler intermediate representation.

The "Compilation Process" transforms code entirely represented in
non-intermediate languages designed for human-written code, and/or in
Java Virtual Machine byte code, into Target Code. Thus, for example,
use of source code generators and preprocessors need not be considered
part of the Compilation Process, since the Compilation Process can be
understood as starting with the output of the generators or
preprocessors.

A Compilation Process is "Eligible" if it is done using GCC, alone or
with other GPL-compatible software, or if it is done without using any
work based on GCC. For example, using non-GPL-compatible Software to
optimize any GCC intermediate representations would not qualify as an
Eligible Compilation Process.

1. Grant of Additional Permission.

You have permission to propagate a work of Target Code formed by
combining the Runtime Library with Independent Modules, even if such
propagation would otherwise violate the terms of GPLv3, provided that
all Target Code was generated by Eligible Compilation Processes. You
may then convey such a combination under terms of your choice,
consistent with the licensing of the Independent Modules.

2. No Weakening of GCC Copyleft.

The availability of this Exception does not imply any general
presumption that third-party software is unaffected by the copyleft
requirements of the license of GCC.



================================================
FILE: README-high-level.md
================================================
# gtk-fortran -- High level interfaces

The high level interface for gtk-fortran is in the source file
gtk-hl.f90. This provides a number of higher level interfaces to the
GTK widget system, with the intent of making GUI construction more
accessible to scientific programmers (the feel should not be too alien
to anyone who has developed GUIs in IDL). The routines make use of the
optional arguments in Fortran>=90 to simplify creating and initializing widgets.

## Modules list:

* gtk_hl: A wrapper that includes all of the other modules.

* gtk_hl_assistant: A bundled interface for the assistant widget.

* gtk_hl_button: Implements interfaces to various kinds of button.

* gtk_hl_chooser: Implements file choosers that do not need variadic
       arguments.

* gtk_hl_combobox: Implements interfaces to text comboboxes.

* gtk_hl_container: Implements interfaces to: Window, box, table
       (implemented as grid in GTK 3.x), notebook and scrolled window.

* gtk_hl_dialog: Implements a message dialog widget that does not require
       variadic calls.

* gtk_hl_entry: Implements interfaces to entry and textview widgets.

* gtk_hl_infobar: An interface to the infobar widget. Removes much of the
       complexity of putting a message into the widget.

* gtk_hl_misc: Miscellaneous interfaces, mostly used by other modules.

* gtk_hl_progress: Implements progress bars, including "m of n" settings
       and automated text addition.

* gtk_hl_spin_slider: Implements spin boxes and sliders (including
       convenient integer interfaces).

* gtk_hl_tree: Implements interfaces to the list & tree widgets.


In addition two graphics modules are available, but are not automatically
included with the gtk_hl module:

* gtk_draw_hl: Implements interfaces to drawing areas and their
       relationship to Cairo. (N.B. The reversed naming convention is a
       historical accident). Drawing areas created with this module
       have the necessary features to be used as drawing surfaces by
       plplot.

* gdk_pixbuf_hl: Implements convenient interfaces to GDK pixbufs and
       formats.

Several demos are provided in the examples/ directory: they have the
prefix hl_.


================================================
FILE: README.md
================================================
# gtk-fortran

**This branch is for GTK 4**

The gtk-fortran project aims to offer scientists programming in Fortran a cross-platform library to build Graphical User Interfaces (GUI). Gtk-fortran is a partial GTK / Fortran binding 100% written in Fortran, thanks to the C / Fortran interoperability features introduced in the Fortran 2003 standard.

To install gtk-fortran, you can follow the quick instructions in the `INSTALL` file or the more [detailed instructions](https://github.com/vmagnin/gtk-fortran/wiki/Installation) on the wiki documentation.

Full documentation (wiki tab):
[https://github.com/vmagnin/gtk-fortran/wiki](https://github.com/vmagnin/gtk-fortran/wiki)

Please post bugs on GitHub:
[https://github.com/vmagnin/gtk-fortran/issues](https://github.com/vmagnin/gtk-fortran/issues)


# Files in this directory

* `README.md`: the present file.
* `CHANGELOG.md`: list of the releases with main changes.
* `CITATION.cff`: file used by the GitHub interface (button "Cite this repository").
* `CMakeLists.txt`: main CMake instructions to build the project.
* `codemeta.json`: metadata about the project.
* `fpm.toml`: Fortran Package Manager manifest.
* `INSTALL`: quick installation instructions (see the Wiki for more details).
* `LICENSE`: text of the GNU GPL v3 license.
* `LICENSE_EXCEPTION`: text of the GCC Runtime Library Exception version 3.1.
* `README-high-level`: about the High Level part of the gtk-fortran library.
* `VERSIONS`: a CSV file with the gtk-fortran, GTK, GLib and distribution versions.


# Citing gtk-fortran

Please acknowledge the use of gtk-fortran by citing the following publication:

Vincent MAGNIN, James TAPPIN, Jens HUNGER, Jerry DE LISLE, "gtk-fortran: a GTK+ binding to build Graphical User Interfaces in Fortran", _Journal of Open Source Software,_ 4(34), 1109, 12th January 2019, [https://doi.org/10.21105/joss.01109](https://doi.org/10.21105/joss.01109)


================================================
FILE: VERSIONS
================================================
gtk-fortran;4.9.0
GTK;4.20.2
GLib;2.86.1
Fedora;43


================================================
FILE: cmake/DefaultFlags.cmake
================================================
# Copyright (C) 2011
# Free Software Foundation, Inc.
#
# This file is part of the gtk-fortran GTK Fortran Interface library.
#
# This is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# This software is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# Under Section 7 of GPL version 3, you are granted additional
# permissions described in the GCC Runtime Library Exception, version
# 3.1, as published by the Free Software Foundation.
#
# You should have received a copy of the GNU General Public License along with
# this program; see the files LICENSE and LICENSE_EXCEPTION respectively.
# If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# Contributed by @awvwgk (2022)
# Last modifications: vmagnin 2025-05-28
#===============================================================================

# Linker flags:
if(UNIX)
  # GNU ld -rdynamic option:
  # Pass the flag -export-dynamic to the ELF linker, on targets that support it.
  # This instructs the linker to add all symbols, not only used ones, to the dynamic symbol table.
  # It is especially needed for programs using the GtkBuilder API.
  # Fails with LFortran at the moment.
  if (NOT (CMAKE_Fortran_COMPILER_ID STREQUAL "LFortran"))
    set(CMAKE_EXE_LINKER_FLAGS_INIT "-rdynamic")
  endif()
endif()

# Compilers flags:
if(CMAKE_Fortran_COMPILER_ID STREQUAL "GNU")
  # gfortran compiler:
  set(
    CMAKE_Fortran_FLAGS_RELEASE_INIT
    "-O3"
    "-mtune=native"
    "-march=native"
  )
  set(
    CMAKE_Fortran_FLAGS_DEBUG_INIT
    "-g"
    "-Wall"
    "-Wextra"
    "-fcheck=all"
    "-fbacktrace"
    "-Wno-unused-dummy-argument"
  )
elseif((CMAKE_Fortran_COMPILER_ID STREQUAL "Intel") OR (CMAKE_Fortran_COMPILER_ID STREQUAL "IntelLLVM"))
  # ifort and ifx compilers (OneAPI):
  if(WIN32)
    set(
      CMAKE_Fortran_FLAGS_RELEASE_INIT
      "/O2"
    )
    set(
      CMAKE_Fortran_FLAGS_DEBUG_INIT
      "/debug:full"
      "/Od"
      "/warn:all"
      "/warn:nounused"
    )
  else()
    set(
      CMAKE_Fortran_FLAGS_RELEASE_INIT
      "-O3"
    )
    set(
      CMAKE_Fortran_FLAGS_DEBUG_INIT
      "-g"
      "-O0"
      "-warn all"
      "-warn nounused"
    )
  endif()
elseif(CMAKE_Fortran_COMPILER_ID STREQUAL "LLVMFlang")
  # -fPIC is necessary to avoid a linking error
  set(
    CMAKE_Fortran_FLAGS_RELEASE_INIT
    "-O3"
    "-fPIC"
  )
  set(
    CMAKE_Fortran_FLAGS_DEBUG_INIT
    "-g"
    "-fPIC"
    "-Wall"
    "-pedantic"
  )
else()
  # Standard flags for all the other compilers:
  set(
    CMAKE_Fortran_FLAGS_RELEASE_INIT
    "-O3"
  )
  set(
    CMAKE_Fortran_FLAGS_DEBUG_INIT
    "-g"
  )
endif()

string(REPLACE ";" " " CMAKE_Fortran_FLAGS_RELEASE_INIT "${CMAKE_Fortran_FLAGS_RELEASE_INIT}")
string(REPLACE ";" " " CMAKE_Fortran_FLAGS_DEBUG_INIT "${CMAKE_Fortran_FLAGS_DEBUG_INIT}")
string(REPLACE ";" " " CMAKE_EXE_LINKER_FLAGS_INIT "${CMAKE_EXE_LINKER_FLAGS_INIT}")


================================================
FILE: cmake/README.md
================================================
# CMake additional modules

This directory contains the modules to be loaded by `include()` or `find_package()` before checking the default CMake modules:

- `cmake_uninstall.cmake.in`: generic code from https://gitlab.kitware.com/cmake/community/-/wikis/FAQ#can-i-do-make-uninstall-with-cmake
- `DefaultFlags.cmake`: defines default Release and Debug flags for compilers.


================================================
FILE: cmake/cmake_uninstall.cmake.in
================================================
# Source:
# https://gitlab.kitware.com/cmake/community/-/wikis/FAQ#can-i-do-make-uninstall-with-cmake

if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt")
    message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt")
endif()

file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files)
# Building a list from the lines of the .txt file:
string(REGEX REPLACE "\n" ";" files "${files}")

foreach(file ${files})
    message(STATUS "Uninstalling $ENV{DESTDIR}${file}")

    if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
        exec_program(
            "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
            OUTPUT_VARIABLE rm_out
            RETURN_VALUE rm_retval
            )

        if(NOT "${rm_retval}" STREQUAL 0)
            message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
        endif()
    else()
        message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
    endif()
endforeach(file)


================================================
FILE: codemeta.json
================================================
{
  "@context": "https://raw.githubusercontent.com/codemeta/codemeta/master/codemeta.jsonld",
  "@type": "Code",
  "applicationCategory": "Graphical User Interface",
  "author": [
    {
      "@id": "",
      "@type": "Person",
      "email": "",
      "name": "Vincent Magnin",
      "affiliation": "Univ. Lille, CNRS, Centrale Lille, ISEN, Univ. Valenciennes, UMR 8520 - IEMN, F-59000 Lille,France"
    },
    {
      "@id": "",
      "@type": "Person",
      "email": "",
      "name": "James Tappin",
      "affiliation": ""
    },
    {
      "@id": "",
      "@type": "Person",
      "email": "",
      "name": "Jens Hunger",
      "affiliation": ""
    },
    {
      "@id": "",
      "@type": "Person",
      "email": "",
      "name": "Jerry De Lisle",
      "affiliation": ""
    }
  ],
  "codeRepository": "https://github.com/vmagnin/gtk-fortran",
  "buildInstructions": "https://github.com/vmagnin/gtk-fortran/wiki",
  "issueTracker": "https://github.com/vmagnin/gtk-fortran/issues",
  "copyrightYear": "2011",
  "dateCreated": "2011-01-10",
  "dateModified": "2025-11-20",
  "developmentStatus": "Active",
  "description": "The gtk-fortran project aims to offer scientists programming in Fortran a cross-platform library to build Graphical User Interfaces (GUI). Gtk-fortran is a partial GTK / Fortran binding 100% written in Fortran, thanks to the ISO_C_BINDING module for interoperability between C and Fortran, which is a part of the Fortran 2003 standard.",
  "isAccessibleForFree": true,
  "keywords": "GTK, Fortran, Graphical User Interface",
  "license": "GPL-3.0-or-later WITH GCC-exception-3.1",
  "name": "gtk-fortran",
  "version": "4.9.0",
  "operatingSystem": "Linux, MacOS, MSYS2/Windows, BSD...",
  "programmingLanguage": "Fortran",
  "softwareRequirements": "GTK, CMake",
  "softwareSuggestions": "PLplot",
  "referencePublication": "Vincent MAGNIN, James TAPPIN, Jens HUNGER, Jerry DE LISLE, 'gtk-fortran: a GTK+ binding to build Graphical User Interfaces in Fortran', Journal of Open Source Software, 4(34), 1109, 12th January 2019, [https://doi.org/10.21105/joss.01109](https://doi.org/10.21105/joss.01109)",
  "datePublished": "2019-04-24"
}


================================================
FILE: examples/CMakeLists.txt
================================================
# This file is part of gtk-fortran, a GTK / Fortran interface library.
# Copyright (C) 2011 The gtk-fortran team
#
# This is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# This software is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# Under Section 7 of GPL version 3, you are granted additional
# permissions described in the GCC Runtime Library Exception, version
# 3.1, as published by the Free Software Foundation.
#
# You should have received a copy of the GNU General Public License along with
# this program; see the files LICENSE and LICENSE_EXCEPTION respectively.
# If not, see <http://www.gnu.org/licenses/>.
#=============================================================================
# Contributed by Kyle Horne: 05.11.2011
# Tests redesigned, James Tappin 05/17/2011
# Last modifications: Jens Hunger: 03/06/2013, Vincent Magnin: 2025-06-17
#
# CMAKE build file for gtk-fortran

include_directories("${CMAKE_CURRENT_BINARY_DIR}/../src/modules")

if (NOT NO_BUILD_EXAMPLES)
  #==========================
  # Build the main examples:
  #==========================
  set(examples_list gtkzero_gapp gtkhello list_demo gio_demo tests tests_gtk_sup
    notebooks julia_pixbuf  mandelbrot_pixbuf mandelbrot_pixbuf_zoom
    menubar cairo-tests cairo-basics cairo-basics-click bazaar
    pixbuf_without_gui regex
  )

  if(NOT NO_BUILD_HL)
    set(examples_list ${examples_list}
        hl_assistant hl_choosers hl_combo hl_containers hl_dialog hl_list1
        hl_list_n hl_list_renderers hl_pbar
        hl_sliders hl_sliders2 hl_textview hl_tree hl_cairo1 hl_cairo_clock
        hl_cairo_viewer hl_infobar
    )
  endif(NOT NO_BUILD_HL)

  foreach(example ${examples_list})
    add_executable(${example} "${example}.f90")
    target_link_libraries(${example} gtk-fortran_static ${GTK_LIBRARIES})
    set_target_properties(${example} PROPERTIES Fortran_MODULE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${example}_mod/ )
    add_test(${example} ./${example})
  endforeach(example)

  # Copy this media file that will be played by the bazaar.f90 example:
  configure_file(demo_sound.ogg demo_sound.ogg COPYONLY)

  #====================================
  # Build the gtkbuilder example:
  #====================================
  # With this command, CMake will detect the updates of gtkbuilder.ui:
  configure_file(gtkbuilder.ui gtkbuilder.ui COPYONLY)

  add_executable(gtkbuilder2 "gtkbuilder2.f90")
  target_link_libraries(gtkbuilder2 gtk-fortran_static ${GTK_LIBRARIES})
  set_target_properties(gtkbuilder2 PROPERTIES Fortran_MODULE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/gtkbuilder2_mod/ )
  # This test is excluded because the directories don't match up.
  # add_test(gtkbuilder2 gtkbuilder2)
endif(NOT NO_BUILD_EXAMPLES)

# If the INSTALL_EXAMPLES variable is set, then copy the examples
# to ${CMAKE_INSTALL_DATAROOTDIR/gtk-fortran/examples<gtkversion>
# useful (e.g.) for building binary packages.
if (INSTALL_EXAMPLES)
  install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/
    DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/gtk-fortran/examples${GTKv}
    PATTERN "CMakeLists.txt" EXCLUDE
    REGEX "\.backup$" EXCLUDE
    REGEX "~$" EXCLUDE
    REGEX "/Testing" EXCLUDE
  )
endif(INSTALL_EXAMPLES)


================================================
FILE: examples/README.md
================================================
# Gtk-fortran Example Programs

This directory contains example programs for the GTK 4 version of gtk-fortran. They are automatically built by CMake but any example may also be individually built on a system with `gtk-4-fortran` installed with the command:

```bash
$ gfortran <name>.f90 -o <name> $(pkg-config --cflags --libs gtk-4-fortran)
```

Among those examples:

- `gtkzero_gapp.f90` just opens an empty GTK window. Based on GtkApplication and GApplication.
- `gtkhello.f90` opens a window with two buttons.
- The `*pixbuf*.f90` examples demonstrate pixel drawing (bitmap drawing). The `pixbuf_without_gui.f9`0 example draws a Sierpinski triangle in a PNG file, without using a GUI.
- The `cairo*.f90` examples demonstrates vectorial drawing using Cairo. And `cairo-basics.f90` also saves the drawing in a SVG file and a PDF file.
- `bazaar.f90` is used for testing various widgets and functions.
    - `demo_sound.ogg` will be played when you click on Button1.
- `gio_demo.f90`: this is a very basic demo to get started with GIO. It uses
Fortran I/O to read text from the keyboard & writes it to the file `gio_demo.dat` in the current directory.
- `gtkbuilder2.f90` demonstrates how you can use an UI XML file to create your graphical user interface.
- `list_demo.f90` demonstrates how to use GtkTreeView for displaying trees and lists.
- `menubar.f90` demonstrates a menubar based on GMenu and GAction. It also uses CSS styles.
- `notebooks.f90` demonstrates how to use GtkNotebook, a tabbed notebook container.
- `regex.f90` (no GUI) demonstrates how to use GLib regular expressions functions.
- `hl_*` examples use the "high-level" interface.
    - `hl_pbar.f90`: a progress bar.
    - ...
- `tests.f90` (no GUI) is testing things about ISO_C_BINDING and the relations between Fortran types and GLib types.
- `tests_gtk_sup.f90` (no GUI) is testing functions and structures defined in the `gtk_sup` module.


================================================
FILE: examples/bazaar.f90
================================================
! This file is part of gtk-fortran, a GTK / Fortran interface library.
! Copyright (C) 2011 The gtk-fortran team
!
! This is free software; you can redistribute it and/or modify
! it under the terms of the GNU General Public License as published by
! the Free Software Foundation; either version 3, or (at your option)
! any later version.
!
! This software is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
! GNU General Public License for more details.
!
! Under Section 7 of GPL version 3, you are granted additional
! permissions described in the GCC Runtime Library Exception, version
! 3.1, as published by the Free Software Foundation.
!
! You should have received a copy of the GNU General Public License along with
! this program; see the files LICENSE and LICENSE_EXCEPTION respectively.
! If not, see <http://www.gnu.org/licenses/>.
!------------------------------------------------------------------------------
! This program is used to test various GTK widgets and functions
! Contributors: Vincent Magnin, James Tappin
! GTK 4 version: vmagnin 2020-05-28, 2025-05-05
!------------------------------------------------------------------------------

module various_functions
  use, intrinsic :: iso_c_binding
  use gtk_sup, only: c_f_string_copy_alloc
  implicit none

  contains

  subroutine some_glib_functions()
    use g, only: g_get_user_name, g_get_application_name, g_get_host_name, &
               & g_get_home_dir, g_get_current_dir, g_format_size, &
               & g_get_os_info

    ! Automatic reallocation is used for that string:
    character(:), allocatable :: my_string
    type(c_ptr) :: ret

    call c_f_string_copy_alloc(g_get_user_name(), my_string)
    print *, "Hello ", my_string

    call c_f_string_copy_alloc(g_get_host_name(), my_string)
    print *, "Host name: ", my_string

    call c_f_string_copy_alloc(g_get_application_name(), my_string)
    print *, "Application name: ", my_string

    call c_f_string_copy_alloc(g_get_home_dir(), my_string)
    print *, "Home dir: ", my_string

    call c_f_string_copy_alloc(g_get_current_dir(), my_string)
    print *, "Current dir: ", my_string
    if (my_string(1:1) == "/") then
        print *, "UNIX OS"
    else
        print *, "Not UNIX OS"
    endif

    ! That function may return NULL with some OS:
    ret = g_get_os_info("PRETTY_NAME"//c_null_char)
    if (c_associated(ret)) then
      call c_f_string_copy_alloc(ret, my_string)
    else
      my_string = "?"
    end if
    print *, "Your OS: ", my_string

    call c_f_string_copy_alloc(g_format_size (123456789_c_int64_t), my_string)
    print *, "g_format_size: ", my_string
  end subroutine some_glib_functions
end module various_functions


module my_widgets
  use, intrinsic :: iso_c_binding

  implicit none
  type(c_ptr) :: window
  type(c_ptr) :: box1, table
  type(c_ptr) :: button1, button2, button3, button4, label1
  type(c_ptr) :: entry1
  type(c_ptr) :: progress
  type(c_ptr) :: view, buffer, scrolled_window
  type(c_ptr) :: my_drawing_area, my_pixbuf
  type(c_ptr) :: dialog
  type(c_ptr) :: media
end module


module handlers
  use gtk, only: gtk_about_dialog_new, gtk_about_dialog_set_authors, &
  & gtk_about_dialog_set_comments, &
  & gtk_about_dialog_set_license_type, GTK_LICENSE_GPL_3_0, &
  & gtk_about_dialog_set_program_name, gtk_application_window_new, &
  & gtk_about_dialog_set_website, gtk_window_set_transient_for, &
  & gtk_button_new, gtk_button_new_with_label, &
  & gtk_window_set_child, gtk_scrolled_window_set_child, &
  & gtk_drawing_area_new, gtk_drawing_area_set_draw_func, &
  & gtk_entry_get_buffer, gtk_entry_buffer_get_text, gtk_entry_new, &
  & gtk_label_new, &
  & gtk_progress_bar_new, gtk_progress_bar_pulse, &
  & gtk_progress_bar_set_fraction, gtk_progress_bar_set_text, &
  & gtk_scrolled_window_new,&
  & gtk_grid_attach, gtk_grid_new, gtk_text_buffer_set_text,&
  & gtk_text_view_get_buffer, gtk_text_view_new, gtk_window_destroy, &
  & gtk_widget_show, gtk_window_set_title, &
  & g_signal_connect, g_signal_connect_swapped, &
  & FALSE, TRUE, GDK_COLORSPACE_RGB, GDK_COLORSPACE_RGB,&
  & gtk_grid_set_row_homogeneous, &
  & gtk_grid_set_column_homogeneous, &
  & gtk_widget_set_margin_start, gtk_widget_set_margin_end, &
  & gtk_widget_set_margin_top, gtk_widget_set_margin_bottom, &
  & gtk_get_major_version, gtk_get_minor_version, gtk_get_micro_version, &
  & gtk_widget_set_name, gtk_css_provider_new, gtk_widget_get_display, &
  & gtk_css_provider_load_from_data, gtk_style_context_add_provider_for_display

  use g, only: g_object_unref

  use cairo, only: cairo_create, cairo_curve_to, cairo_destroy, cairo_line_to, &
  & cairo_move_to, cairo_paint, cairo_set_line_width, cairo_set_source, &
  & cairo_set_source_rgb, cairo_stroke

  use gdk, only: gdk_cairo_set_source_pixbuf

  use gdk_pixbuf, only: gdk_pixbuf_get_has_alpha, gdk_pixbuf_get_n_channels, &
  & gdk_pixbuf_get_pixels, gdk_pixbuf_get_rowstride, gdk_pixbuf_new

  use my_widgets

  implicit none

contains
  !*************************************
  ! User defined event handlers go here
  !*************************************

  ! Callback function for the signal "activate" emitted by g_application_run().
  ! We use a subroutine because it should return void.
  ! The GUI is defined here.
  subroutine activate(app, gdata) bind(c)
    use various_functions, only: some_glib_functions

    type(c_ptr), value, intent(in)  :: app, gdata
    type(c_ptr) :: css_provider, gdk_display

    ! Create the window:
    window = gtk_application_window_new(app)
    ! Don't forget that C strings must end with a null char:
    call gtk_window_set_title(window, "A great bazaar to test widgets..."//&
                                     & c_null_char)

    print '(A4,I0,A1,I0,A1,I0)', "GTK ", gtk_get_major_version(),".", &
         & gtk_get_minor_version(), ".", gtk_get_micro_version()
    call some_glib_functions()

    !******************************************************************
    ! Adding widgets in the window:
    !******************************************************************
    table = gtk_grid_new ()
    call gtk_grid_set_column_homogeneous(table, TRUE)
    call gtk_grid_set_row_homogeneous(table, TRUE)
    ! Set the border width around the container:
    call gtk_widget_set_margin_start (table, 10_c_int)
    call gtk_widget_set_margin_end (table, 10_c_int)
    call gtk_widget_set_margin_top (table, 10_c_int)
    call gtk_widget_set_margin_bottom (table, 10_c_int)
    call gtk_window_set_child(window, table)

    button1 = gtk_button_new_with_label ("Button1"//c_null_char)
    call gtk_grid_attach(table, button1, 0_c_int, 0_c_int, 1_c_int, 1_c_int)
    call g_signal_connect (button1, "clicked"//c_null_char, c_funloc(firstbutton))

    button2 = gtk_button_new_with_label ("Button2"//c_null_char)
    call gtk_grid_attach(table, button2, 1_c_int, 0_c_int, 1_c_int, 1_c_int)
    call g_signal_connect (button2, "clicked"//c_null_char, c_funloc(secondbutton))

    button3 = gtk_button_new_with_label ("Exit"//c_null_char)
    call gtk_grid_attach(table, button3, 2_c_int, 0_c_int, 1_c_int, 1_c_int)
    call g_signal_connect (button3, "clicked"//c_null_char, c_funloc(destroy))

    button4 = gtk_button_new_with_label ("About"//c_null_char)
    call gtk_grid_attach(table, button4, 3_c_int, 0_c_int, 1_c_int, 1_c_int)
    call g_signal_connect (button4, "clicked"//c_null_char, c_funloc(aboutbutton))

    label1 = gtk_label_new("My label"//c_null_char)
    call gtk_grid_attach(table, label1, 0_c_int, 1_c_int, 1_c_int, 1_c_int)

    entry1 = gtk_entry_new()
    call gtk_grid_attach(table, entry1, 1_c_int, 1_c_int, 1_c_int, 1_c_int)

    progress = gtk_progress_bar_new()
    call gtk_progress_bar_set_fraction (progress, 0.15d0)
    call gtk_progress_bar_set_text (progress, "My progress bar"//c_null_char)
    call gtk_grid_attach(table, progress, 1_c_int, 2_c_int, 3_c_int, 1_c_int)

    ! https://docs.gtk.org/gtk4/ctor.TextView.new.html
    view = gtk_text_view_new()
    buffer = gtk_text_view_get_buffer(view)
    call gtk_text_buffer_set_text(buffer, &
        & "This is just a great bazaar where I can test widgets."//c_new_line//&
        & "Click on Button1 to hear a little melody"//c_new_line//&
        & "composed with the ForSynth Fortran project:"//c_new_line//&
        & "https://github.com/vmagnin/forsynth"//c_new_line//c_new_line//&
        & "You can edit this text. And it is scrollable."//c_null_char, -1_c_int)

    ! Let's change the background color and the font of the TextView:
    call gtk_widget_set_name (view, "my_TextView"//c_null_char)
    css_provider = gtk_css_provider_new()
    gdk_display = gtk_widget_get_display(window)
    call gtk_css_provider_load_from_data(css_provider, &
        & "textview#my_TextView {background-color: Ivory;font-family: monospace;font-size:14px;}", -1_c_size_t)
    call gtk_style_context_add_provider_for_display(gdk_display, css_provider, 800_c_int)

    scrolled_window = gtk_scrolled_window_new()
    call gtk_scrolled_window_set_child(scrolled_window, view)
    call gtk_grid_attach(table, scrolled_window, 0_c_int, 3_c_int, 3_c_int, 3_c_int)

    my_drawing_area = gtk_drawing_area_new()
    ! https://docs.gtk.org/gtk4/method.DrawingArea.set_draw_func.html
    call gtk_drawing_area_set_draw_func(my_drawing_area, &
                     & c_funloc(my_draw_function), c_null_ptr, c_null_funptr)
    call gtk_grid_attach(table, my_drawing_area, 0_c_int, 6_c_int, 3_c_int, 6_c_int)

    call gtk_widget_show(window)
  end subroutine activate

  ! "It is called whenever GTK needs to draw the contents of the drawing area
  ! to the screen."
  subroutine my_draw_function(widget, my_cairo_context, width, height, gdata) bind(c)
    use, intrinsic :: iso_fortran_env, only: wp=>real64

    type(c_ptr), value, intent(in)    :: widget, my_cairo_context, gdata
    integer(c_int), value, intent(in) :: width, height
    type(c_ptr) :: my_pixbuf
    character(kind=c_char), dimension(:), pointer :: pixel
    integer(c_int) :: i, nch, rowstride
    integer :: j
    integer :: x, y

    print *, "my_draw_function()"

    ! A black horizontal line:
    call cairo_set_source_rgb(my_cairo_context, 0d0, 0d0, 0d0)
    call cairo_set_line_width(my_cairo_context, 1d0)
    call cairo_move_to(my_cairo_context, 100d0, 20d0)
    call cairo_line_to(my_cairo_context, 300d0, 20d0)
    call cairo_stroke(my_cairo_context)
    ! A red diagonal line:
    call cairo_set_source_rgb(my_cairo_context, 1d0, 0d0, 0d0)
    call cairo_set_line_width(my_cairo_context, 0.5d0)
    call cairo_move_to(my_cairo_context, 50d0, 0d0)
    call cairo_line_to(my_cairo_context, 150d0, 100d0)
    call cairo_stroke(my_cairo_context)

    !*************
    ! Pixbuffers :
    !*************
    my_pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8_c_int, width, height)
    nch = gdk_pixbuf_get_n_channels(my_pixbuf)
    rowstride = gdk_pixbuf_get_rowstride(my_pixbuf)
    print *, rowstride, nch, gdk_pixbuf_get_has_alpha(my_pixbuf)
    call c_f_pointer(gdk_pixbuf_get_pixels(my_pixbuf), pixel, [width*height*nch])

    ! pixel is an array with 4 bytes per pixel (RGBA)
    ! We use chars because we need unsigned integers
    do i=1, width*height*nch, nch
      pixel(i)   = char(0)    ! Red
      pixel(i+1) = char(0)    ! Green
      pixel(i+2) = char(255)  ! Blue
      pixel(i+3) = char(100)  ! Opacity (Alpha channel)
    end do

    ! (0,0) is the top left corner
    ! 0<=x<width, 0<=y<height

    ! Green sinus:
    do j=0, width-1
      x = j
      y = height/2 + int(50 * sin(j/10.0_wp))
      i = x * nch + y * rowstride + 1
      pixel(i)   = char(0)    ! Red
      pixel(i+1) = char(255)  ! Green
      pixel(i+2) = char(0)    ! Blue
      pixel(i+3) = char(255)  ! Opacity (Alpha channel)
    end do

    ! We redraw the pixbuf:
    call gdk_cairo_set_source_pixbuf(my_cairo_context, my_pixbuf, 20d0, 0d0)

    ! Another Cairo element (will also appear below the pixbuf):
    ! A red cubic Bézier spline:
    ! https://cairographics.org/manual/cairo-Paths.html#cairo-curve-to
    call cairo_set_line_width(my_cairo_context, 3d0)
    call cairo_move_to(my_cairo_context, 360d0, 20d0)
    call cairo_curve_to(my_cairo_context, 60d0, 50d0, 135d0, 45d0, 400d0, 150d0)
    call cairo_stroke(my_cairo_context)

    call cairo_paint(my_cairo_context)
  end subroutine my_draw_function

  ! GtkObject signal:
  subroutine destroy (widget, gdata) bind(c)
    use gtk_sup, only: c_f_string_copy_alloc

    type(c_ptr), value, intent(in) :: widget, gdata
    type(c_ptr) :: buffer
    character(:), allocatable :: my_string

    print *, "my destroy"

    buffer = gtk_entry_get_buffer(entry1)
    call c_f_string_copy_alloc(gtk_entry_buffer_get_text(buffer), my_string)
    print *, "Entry box: ", my_string

    ! This is the end of the program:
    call gtk_window_destroy(window)
  end subroutine destroy

  ! Callback function for the signal "notify::ended" emitted by the media stream.
  ! We use a subroutine because it should return void.
  subroutine sound_ended(object, gdata) bind(c)
    type(c_ptr), value, intent(in) :: object, gdata
    ! Free the media pointer both on C and Fortran sides:
    call g_object_unref(object)
    media = c_null_ptr
  end subroutine

  ! GtkButton signal:
  subroutine firstbutton (widget, gdata) bind(c)
    use gtk, only: gtk_media_file_new_for_filename, gtk_media_stream_set_volume, gtk_media_stream_play, &
                 & gtk_media_stream_get_playing
    type(c_ptr), value, intent(in) :: widget, gdata

    print *, "Is there anybody in there? Just nod if you can hear me"

    if (.not.c_associated(media)) then
      ! It plays a little melody
      ! https://docs.gtk.org/gtk4/class.MediaFile.html
      media = gtk_media_file_new_for_filename("demo_sound.ogg"//c_null_char)
      call gtk_media_stream_set_volume(media, 1.0_c_double)
      call gtk_media_stream_play(media)
      call g_signal_connect(media, "notify::ended"//c_null_char, c_funloc(sound_ended), c_null_ptr)

      if (gtk_media_stream_get_playing(media) == FALSE) print *, "ERROR: have you installed the libgtk-4-media-gstreamer backend?"
    else
      print *, "Be patient, the music is not yet ended!"
    end if
  end subroutine firstbutton

  ! GtkButton signal:
  subroutine secondbutton (widget, gdata) bind(c)
    type(c_ptr), value, intent(in) :: widget, gdata

    call gtk_progress_bar_pulse (progress)
  end subroutine secondbutton

  ! GtkButton signal:
  subroutine aboutbutton (widget, gdata) bind(c)
    use gtk_sup, only: convert_f_string

    type(c_ptr), value, intent(in) :: widget, gdata
    ! Authors of bazaar.f90 (list returned by git blame bazaar.f90):
    character(len=14, kind=c_char), dimension(2), parameter :: authors = &
                                          & ["Vincent MAGNIN", "James TAPPIN  "]
    character(kind=c_char), dimension(:), allocatable :: string
    character(kind=c_char), pointer, dimension(:) :: credit
    type(c_ptr), dimension(:), allocatable :: c_ptr_array
    integer :: i

    dialog = gtk_about_dialog_new()
    ! https://docs.gtk.org/gtk4/method.Window.set_transient_for.html
    call gtk_window_set_transient_for(dialog, window)
    call gtk_about_dialog_set_program_name(dialog, "The gtk-fortran bazaar"//c_null_char)
    call gtk_about_dialog_set_license_type(dialog, GTK_LICENSE_GPL_3_0)
    call gtk_about_dialog_set_comments(dialog, "The gtk-fortran project &
    & aims to offer scientists programming in Fortran a cross-platform library &
    &to build Graphical User Interfaces (GUI)."//c_new_line//" Gtk-fortran&
    & is a partial GTK / Fortran binding 100% written in Fortran, thanks&
    & to the ISO_C_BINDING module for interoperability between C and Fortran,&
    & which is a part of the Fortran 2003 standard."//c_new_line//" GTK &
    &is a free software cross-platform graphical library available for &
    &Linux, UNIX, Windows and MacOs."//c_null_char)
    call gtk_about_dialog_set_website(dialog, &
                  & "https://github.com/vmagnin/gtk-fortran/wiki"//c_null_char)

    ! To add authors we need a pointer toward a null terminated array of strings.
    ! This code comes from src/gtk-hl-dialog.f90:
    allocate(c_ptr_array(size(authors)+1))

    do i = 1, size(authors)
      call convert_f_string(authors(i), string)
      allocate(credit(size(string)))
      ! A Fortran pointer toward the Fortran string:
      credit(:) = string(:)
      ! Store the C address in the array:
      c_ptr_array(i) = c_loc(credit(1))
      nullify(credit)
    end do
    ! The array must be null terminated:
    c_ptr_array(size(authors)+1) = c_null_ptr
    ! https://docs.gtk.org/gtk4/method.AboutDialog.set_authors.html
    call gtk_about_dialog_set_authors(dialog, c_ptr_array)
    deallocate(c_ptr_array)

    call gtk_widget_show(dialog)
  end subroutine aboutbutton
end module handlers

!*******************************************************************************
! In the main program, we declare the GTK application, connect it to its
! "activate" function which will create the GUI,
! and finally call the GLib main loop.
!*******************************************************************************
program bazaar
  use, intrinsic :: iso_c_binding
  use gtk, only: gtk_application_new, G_APPLICATION_FLAGS_NONE, g_signal_connect
  use g, only: g_application_run, g_object_unref
  use handlers, only: activate

  implicit none
  integer(c_int) :: status
  type(c_ptr)    :: app

  app = gtk_application_new("gtk-fortran.examples.bazaar"//c_null_char, &
                          & G_APPLICATION_FLAGS_NONE)
  call g_signal_connect(app, "activate"//c_null_char, c_funloc(activate), &
                      & c_null_ptr)
  status = g_application_run(app, 0_c_int, [c_null_ptr])
  call g_object_unref(app)
end program bazaar


================================================
FILE: examples/cairo-basics-click.f90
================================================
! This file is part of gtk-fortran, a GTK / Fortran interface library.
! Copyright (C) 2011 The gtk-fortran team
!
! This is free software; you can redistribute it and/or modify
! it under the terms of the GNU General Public License as published by
! the Free Software Foundation; either version 3, or (at your option)
! any later version.
!
! This software is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
! GNU General Public License for more details.
!
! Under Section 7 of GPL version 3, you are granted additional
! permissions described in the GCC Runtime Library Exception, version
! 3.1, as published by the Free Software Foundation.
!
! You should have received a copy of the GNU General Public License along with
! this program; see the files LICENSE and LICENSE_EXCEPTION respectively.
! If not, see <http://www.gnu.org/licenses/>.
!
! GTK 4 version contributed by Vincent Magnin
! Last modification: vmagnin 2020-05-28, 2022-04-05

module handlers
  use, intrinsic :: iso_fortran_env, only: wp=>real64
  use, intrinsic :: iso_c_binding, only: c_int, c_ptr, c_null_ptr, c_null_funptr, &
                         & c_funloc, c_null_char, c_double, c_bool

  use gtk, only: gtk_application_window_new, gtk_drawing_area_new, &
  & gtk_drawing_area_set_content_width, gtk_drawing_area_set_content_height, &
  & gtk_drawing_area_set_draw_func, gtk_window_set_child, gtk_widget_show, &
  & gtk_window_set_default_size, gtk_window_set_title, FALSE, &
  & gtk_gesture_click_new, gtk_widget_add_controller, &
  & gtk_event_controller_get_widget, g_signal_connect, &
  & gtk_widget_get_width, gtk_widget_get_height, &
  & gtk_gesture_single_get_current_button, gtk_gesture_single_set_button, &
  & gtk_event_controller_scroll_new, GTK_EVENT_CONTROLLER_SCROLL_VERTICAL, &
  & gtk_widget_queue_draw

  use cairo, only: cairo_arc, cairo_line_to, cairo_move_to, &
  & cairo_set_line_width, cairo_set_source_rgb, cairo_stroke, &
  & cairo_get_target, cairo_surface_write_to_png

  implicit none
  ! Circle radius:
  real(wp) :: radius = 100.0_wp

contains
  ! The GUI is defined here:
  subroutine activate(app, gdata) bind(c)
    type(c_ptr), value, intent(in)  :: app, gdata
    type(c_ptr)     :: window
    type(c_ptr)     :: my_drawing_area, controller, controller2
    integer(c_int)  :: width, height

    window = gtk_application_window_new(app)
    width  = 700
    height = 700
    call gtk_window_set_default_size(window, width, height)
    call gtk_window_set_title(window, "Click or scroll and I will tell you..."//c_null_char)

    my_drawing_area = gtk_drawing_area_new()
    call gtk_drawing_area_set_content_width(my_drawing_area, width)
    call gtk_drawing_area_set_content_height(my_drawing_area, height)
    call gtk_drawing_area_set_draw_func(my_drawing_area, &
                   & c_funloc(my_draw_function), c_null_ptr, c_null_funptr)

    ! We need a gesture controller to detect mouse clicks:
    ! https://developer.gnome.org/gtk4/stable/GtkGestureClick.html
    ! https://developer.gnome.org/gtk4/stable/GtkWidget.html#gtk-widget-add-controller
    controller = gtk_gesture_click_new()
    ! 0 to listen to all buttons (button 1 by default):
    call gtk_gesture_single_set_button (controller, 0_c_int)
    call g_signal_connect(controller, "pressed"//c_null_char, &
                                        & c_funloc(click_cb))
    call gtk_widget_add_controller(my_drawing_area, controller)

    ! And a controller for scrolling (modifies the circle radius):
    ! https://developer.gnome.org/gtk4/stable/GtkEventControllerScroll.html
    controller2 = gtk_event_controller_scroll_new (GTK_EVENT_CONTROLLER_SCROLL_VERTICAL)
    call g_signal_connect(controller2, "scroll"//c_null_char, &
                                        & c_funloc(scroll_cb))
    call gtk_widget_add_controller(my_drawing_area, controller2)

    call gtk_window_set_child(window, my_drawing_area)
    call gtk_widget_show(window)
  end subroutine activate

  ! Click callback function ("pressed" signal):
  subroutine click_cb(gesture, n_press, x, y, gdata) bind(c)
    type(c_ptr), value, intent(in)    :: gesture, gdata
    integer(c_int), value, intent(in) :: n_press
    real(c_double), value, intent(in) :: x, y
    type(c_ptr) :: widget
    integer(c_int) :: width, height
    real(wp) :: d

    print *, "Button ", gtk_gesture_single_get_current_button(gesture)

    widget = gtk_event_controller_get_widget(gesture)
    print *, n_press, " click(s) at ", int(x), int(y)

    width  = gtk_widget_get_width(widget)
    height = gtk_widget_get_height(widget)
    d = sqrt((x - width/2.0_wp)**2 + (y - height/2.0_wp)**2)
    print *, "Distance from the centre of the circle: ", d
  end subroutine click_cb

  ! Scroll callback function ("scroll" signal):
  subroutine scroll_cb(controller, x, y, gdata) bind(c)
    type(c_ptr), value, intent(in)    :: controller, gdata
    real(c_double), value, intent(in) :: x, y
    type(c_ptr) :: widget

    radius = radius + y
    print *, "Scroll and new circle radius: ", x, y, radius
    ! We need to redraw the area:
    widget = gtk_event_controller_get_widget(controller)
    call gtk_widget_queue_draw(widget)
  end subroutine scroll_cb

  ! "It is called whenever GTK needs to draw the contents of the drawing area
  ! to the screen."
  ! https://developer.gnome.org/gtk4/stable/GtkDrawingArea.html#gtk-drawing-area-set-draw-func
  subroutine my_draw_function(widget, my_cairo_context, width, height, gdata) bind(c)
    type(c_ptr), value, intent(in)    :: widget, my_cairo_context, gdata
    integer(c_int), value, intent(in) :: width, height
    integer(c_int)                    :: cstatus
    integer                           :: t
    real(wp), parameter               :: pi = acos(-1.0_wp)

    print *, "draw"

    ! https://cairographics.org/manual/
    ! Note that Cairo numerical parameters are generally doubles.

    ! Horizontal and vertical thin blue lines:
    call cairo_set_source_rgb(my_cairo_context, 0d0, 0d0, 1d0)
    call cairo_set_line_width(my_cairo_context, 1d0)

    do t = 0, height, +100
      ! https://cairographics.org/manual/cairo-Paths.html#cairo-move-to
      call cairo_move_to(my_cairo_context, 0d0,       t*1d0)
      call cairo_line_to(my_cairo_context, width*1d0, t*1d0)
      call cairo_stroke(my_cairo_context)
    end do

    do t = 0, width, +100
      call cairo_move_to(my_cairo_context, t*1d0, 0d0)
      call cairo_line_to(my_cairo_context, t*1d0, height*1d0)
      call cairo_stroke(my_cairo_context)
    end do

    ! A thick red circle at the centre:
    call cairo_set_source_rgb(my_cairo_context, 1d0, 0d0, 0d0)
    call cairo_set_line_width(my_cairo_context, 5d0)
    call cairo_arc(my_cairo_context, width/2d0, height/2d0, radius, 0d0, 2*pi)
    call cairo_stroke(my_cairo_context)

    ! Save the image as a PNG
    ! https://cairographics.org/manual/cairo-PNG-Support.html#cairo-surface-write-to-png
    cstatus = cairo_surface_write_to_png(cairo_get_target(my_cairo_context), &
                                       & "cairo-basics-click.png"//c_null_char)
  end subroutine my_draw_function
end module handlers

! We create a GtkApplication:
program cairo_basics_click
  use, intrinsic :: iso_c_binding, only: c_int, c_ptr, c_funloc, c_null_char, c_null_ptr
  use gtk, only: gtk_application_new, g_signal_connect, G_APPLICATION_FLAGS_NONE
  use g, only: g_application_run, g_object_unref
  use handlers, only: activate

  implicit none
  integer(c_int) :: exit_status
  type(c_ptr)    :: app

  app = gtk_application_new("gtk-fortran.examples.cairo-basics-click"//c_null_char, &
                            & G_APPLICATION_FLAGS_NONE)
  call g_signal_connect(app, "activate"//c_null_char, c_funloc(activate), &
                      & c_null_ptr)
  exit_status = g_application_run(app, 0_c_int, [c_null_ptr])
  call g_object_unref(app)
end program cairo_basics_click



================================================
FILE: examples/cairo-basics.f90
================================================
! This file is part of gtk-fortran, a GTK / Fortran interface library.
! Copyright (C) 2011 The gtk-fortran team
!
! This is free software; you can redistribute it and/or modify
! it under the terms of the GNU General Public License as published by
! the Free Software Foundation; either version 3, or (at your option)
! any later version.
!
! This software is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
! GNU General Public License for more details.
!
! Under Section 7 of GPL version 3, you are granted additional
! permissions described in the GCC Runtime Library Exception, version
! 3.1, as published by the Free Software Foundation.
!
! You should have received a copy of the GNU General Public License along with
! this program; see the files LICENSE and LICENSE_EXCEPTION respectively.
! If not, see <http://www.gnu.org/licenses/>.
!
! Contributed by Jerry DeLisle and Vincent Magnin
! Last modification: vmagnin 2023-04-23

module handlers
  use, intrinsic :: iso_c_binding

  use gtk, only: gtk_application_window_new, gtk_drawing_area_new, &
  & gtk_drawing_area_set_content_width, gtk_drawing_area_set_content_height, &
  & gtk_drawing_area_set_draw_func, gtk_window_set_child, gtk_widget_show, &
  & gtk_window_set_default_size, gtk_window_set_title, CAIRO_SVG_VERSION_1_2, &
  & FALSE, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL

  use cairo, only: cairo_arc, cairo_create, cairo_curve_to, cairo_destroy, &
  & cairo_get_target, cairo_line_to, cairo_move_to, cairo_new_sub_path, &
  & cairo_select_font_face, cairo_set_font_size, cairo_set_line_width, &
  & cairo_set_source, cairo_set_source_rgb, cairo_show_text, cairo_stroke, &
  & cairo_surface_write_to_png, cairo_svg_surface_create, &
  & cairo_svg_surface_restrict_to_version, cairo_surface_destroy, &
  & cairo_pdf_surface_create

  implicit none

contains
  ! The GUI is defined here:
  subroutine activate(app, gdata) bind(c)
    type(c_ptr), value, intent(in)  :: app, gdata
    type(c_ptr)     :: window
    type(c_ptr)     :: my_drawing_area
    integer(c_int)  :: width, height

    window = gtk_application_window_new(app)
    width  = 700
    height = 700
    call gtk_window_set_default_size(window, width, height)
    call gtk_window_set_title(window, "Cairo basics demo"//c_null_char)

    my_drawing_area = gtk_drawing_area_new()
    call gtk_drawing_area_set_content_width(my_drawing_area, width)
    call gtk_drawing_area_set_content_height(my_drawing_area, height)
    call gtk_drawing_area_set_draw_func(my_drawing_area, &
                   & c_funloc(my_draw_function), c_null_ptr, c_null_funptr)

    call gtk_window_set_child(window, my_drawing_area)
    call gtk_widget_show(window)
  end subroutine activate

  ! "It is called whenever GTK needs to draw the contents of the drawing area
  ! to the screen."
  ! https://docs.gtk.org/gtk4/class.DrawingArea.html
  subroutine my_draw_function(widget, my_cairo_context, width, height, gdata) bind(c)
    use, intrinsic :: iso_c_binding, only: dp=>c_double
    type(c_ptr), value, intent(in)    :: widget, my_cairo_context, gdata
    integer(c_int), value, intent(in) :: width, height
    integer :: cstatus
    integer :: rendering
    type(c_ptr) :: surface_svg, surface_pdf, cr_svg, cr_pdf

    ! We will draw three times, once for screen, once in a SVG file, once in a PDF:
    do rendering = 1, 3
      if (rendering == 1) then
        ! Rendering on screen:
        call draw(my_cairo_context, width, height)
        ! Save the image as a PNG:
        cstatus = cairo_surface_write_to_png(cairo_get_target(my_cairo_context), &
                                          & "cairo-basics.png"//c_null_char)
        call cairo_destroy(my_cairo_context)
        print *, "Saved in cairo-basics.png"
      else if (rendering == 2) then
        ! Rendering in a SVG file:
        surface_svg = cairo_svg_surface_create("cairo-basics.svg"//c_null_char, &
                                  & real(width, KIND=dp), real(height, KIND=dp))
        cr_svg = cairo_create(surface_svg)
        call cairo_svg_surface_restrict_to_version(surface_svg, CAIRO_SVG_VERSION_1_2)
        call draw(cr_svg, width, height)
        call cairo_destroy(cr_svg)
        call cairo_surface_destroy(surface_svg)
        print *, "Saved in cairo-basics.svg"
      else
        ! Rendering in a PDF file:
        surface_pdf = cairo_pdf_surface_create("cairo-basics.pdf"//c_null_char, &
                                  & real(width, KIND=dp), real(height, KIND=dp))
        cr_pdf = cairo_create(surface_pdf)
        call draw(cr_pdf, width, height)
        call cairo_surface_destroy(surface_pdf)
        print *, "Saved in cairo-basics.pdf"
      end if
    end do
  end subroutine my_draw_function

  ! It will be called two time, for screen and SVG file:
  subroutine draw(cr, width, height)
    use, intrinsic :: iso_c_binding, only: dp=>c_double

    type(c_ptr), value, intent(in)    :: cr
    integer(c_int), value, intent(in) :: width, height
    integer                           :: t
    real(dp), parameter               :: pi = acos(-1.0_dp)

    ! Bezier curve:
    call cairo_set_source_rgb(cr, 0.9_dp, 0.8_dp, 0.8_dp)
    call cairo_set_line_width(cr, 4._dp)
    call cairo_move_to(cr, 0._dp, 0._dp)
    call cairo_curve_to(cr, 600._dp, 50._dp, 115._dp, 545._dp, &
                      & width*1._dp, height*1._dp)
    call cairo_stroke(cr)

    ! Lines:
    call cairo_set_source_rgb(cr, 0._dp, 0.5_dp, 0.5_dp)
    call cairo_set_line_width(cr, 2._dp)
    do t = 0, height, +20
      call cairo_move_to(cr, 0._dp, t*1._dp)
      call cairo_line_to(cr, t*1._dp, height*1._dp)
      call cairo_stroke(cr)
    end do

    ! Text:
    call cairo_set_source_rgb(cr, 0._dp, 0._dp, 1._dp)
    call cairo_select_font_face(cr, "Times"//c_null_char, &
                            & CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL)
    call cairo_set_font_size (cr, 40._dp)
    call cairo_move_to(cr, 100._dp, 30._dp)
    call cairo_show_text (cr, "gtk-fortran"//c_null_char)
    call cairo_move_to(cr, 100._dp, 75._dp)
    call cairo_show_text (cr, &
                        & "Cairo & Fortran are good friends"//c_null_char)

    ! Circles:
    call cairo_new_sub_path(cr)
    do t = 1, 50
        call cairo_set_source_rgb(cr, t/50._dp, 0._dp, 0._dp)
        call cairo_set_line_width(cr, 5._dp*t/50._dp)
        call cairo_arc(cr, 353._dp + 200._dp*cos(t*2._dp*pi/50), &
                     & 350._dp + 200._dp*sin(t*2._dp*pi/50), 50._dp, 0._dp, 2*pi)
        call cairo_stroke(cr)
    end do
  end subroutine draw

end module handlers

! We create a GtkApplication:
program cairo_basics
  use, intrinsic :: iso_c_binding
  use gtk, only: gtk_application_new, g_signal_connect, G_APPLICATION_FLAGS_NONE
  use g, only: g_application_run, g_object_unref
  use handlers, only: activate

  implicit none
  integer(c_int) :: exit_status
  type(c_ptr)    :: app

  app = gtk_application_new("gtk-fortran.examples.cairo-basics"//c_null_char, &
                            & G_APPLICATION_FLAGS_NONE)
  call g_signal_connect(app, "activate"//c_null_char, c_funloc(activate), &
                      & c_null_ptr)
  exit_status = g_application_run(app, 0_c_int, [c_null_ptr])
  call g_object_unref(app)
end program cairo_basics



================================================
FILE: examples/cairo-tests.f90
================================================
! This file is part of gtk-fortran, a GTK / Fortran interface library.
! Copyright (C) 2011 The gtk-fortran team
!
! This is free software; you can redistribute it and/or modify
! it under the terms of the GNU General Public License as published by
! the Free Software Foundation; either version 3, or (at your option)
! any later version.
!
! This software is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
! GNU General Public License for more details.
!
! Under Section 7 of GPL version 3, you are granted additional
! permissions described in the GCC Runtime Library Exception, version
! 3.1, as published by the Free Software Foundation.
!
! You should have received a copy of the GNU General Public License along with
! this program; see the files LICENSE and LICENSE_EXCEPTION respectively.
! If not, see <http://www.gnu.org/licenses/>.
!------------------------------------------------------------------------------
! Contributed by Jerry DeLisle and Vincent Magnin
! GTK 4 version: vmagnin 2020-05-19
! Last modifications: vmagnin 2023-04-25
!------------------------------------------------------------------------------

module handlers
  use gtk, only: gtk_application_window_new, gtk_window_set_child, &
  & gtk_drawing_area_set_content_width, gtk_drawing_area_set_content_height, &
  & gtk_drawing_area_set_draw_func, gtk_drawing_area_new, &
  & gtk_widget_queue_draw, gtk_widget_show, gtk_window_set_default_size, &
  & gtk_window_set_title, gtk_window_set_resizable, &
  & TRUE, FALSE, GDK_COLORSPACE_RGB, g_signal_connect, &
  & CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL

  use cairo, only: cairo_arc, cairo_create, cairo_curve_to, cairo_destroy, &
  & cairo_get_target, cairo_line_to, cairo_move_to, cairo_new_sub_path, &
  & cairo_paint, cairo_select_font_face, cairo_set_font_size, &
  & cairo_set_line_width, cairo_set_source, cairo_set_source_rgb, &
  & cairo_show_text, cairo_stroke, cairo_surface_write_to_png

  use gdk, only: gdk_cairo_set_source_pixbuf

  use gdk_pixbuf, only: gdk_pixbuf_get_n_channels, gdk_pixbuf_get_pixels, &
  & gdk_pixbuf_get_rowstride, gdk_pixbuf_new

  use g, only: g_main_context_iteration, g_main_context_pending

  use, intrinsic :: iso_fortran_env, only: wp=>real64, dp=>real64, int8
  use, intrinsic :: iso_c_binding

  implicit none
  type(c_ptr)    :: my_gmainloop
  integer(c_int) :: run_status = TRUE
  integer(c_int) :: boolresult
  type(c_ptr)    :: my_pixbuf
  character(kind=c_char), dimension(:), pointer :: pixel
  integer(c_int) :: nch, rowstride, width, height, pwidth, pheight
  logical :: write_png
  ! Mathematical window:
  real(wp), parameter :: xmin = -2.0_wp
  real(wp), parameter :: xmax = +1.0_wp
  real(wp), parameter :: ymin = -1.5_wp
  real(wp), parameter :: ymax = +1.5_wp

contains
  ! This function is needed to update the GUI during long computations.
  ! https://docs.gtk.org/glib/main-loop.html
  subroutine pending_events ()
    do while(IAND(g_main_context_pending(c_null_ptr), run_status) /= FALSE)
      ! FALSE for non-blocking:
      boolresult = g_main_context_iteration(c_null_ptr, FALSE)
    end do
  end subroutine pending_events

  ! "It is called whenever GTK needs to draw the contents of the drawing area
  ! to the screen."
  ! https://docs.gtk.org/gtk4/method.DrawingArea.set_draw_func.html
  subroutine my_draw_function(widget, my_cairo_context, width, height, gdata) bind(c)
    type(c_ptr), value, intent(in)    :: widget, my_cairo_context, gdata
    integer(c_int), value, intent(in) :: width, height
    integer :: cstatus, i
    real(dp), parameter :: pi = acos(-1._dp)
    real(dp) :: Ox, Oy, X_circle
    real(dp) :: X_cardio, teta, ro

    print *, "Entering my_draw_function()"

    ! Pixel coordinates of the mathematical origin:
    Ox = width  * (0._dp - xmin) / (xmax - xmin)
    Oy = height * (ymax - 0._dp) / (ymax - ymin)

    ! We draw the Mandelbrot set pixbuf in the Cairo context, starting from
    ! the top left corner:
    call gdk_cairo_set_source_pixbuf(my_cairo_context, my_pixbuf, 0._dp, 0._dp)
    call cairo_paint(my_cairo_context)

    ! Text:
    call cairo_select_font_face(my_cairo_context, "Arial"//c_null_char, &
                            & CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL)

    ! Draw cartesian axes, in white:
    call cairo_set_source_rgb(my_cairo_context, 1._dp, 1._dp, 1._dp)
    call cairo_set_line_width(my_cairo_context, 2._dp)
    ! Horizontal axis:
    call cairo_move_to(my_cairo_context, 0._dp,                Oy)
    call cairo_line_to(my_cairo_context, real(width, KIND=dp), Oy)
    ! Vertical axis:
    call cairo_move_to(my_cairo_context, Ox, 0._dp)
    call cairo_line_to(my_cairo_context, Ox, real(height, KIND=dp))
    call cairo_stroke(my_cairo_context)
    ! Texts on the axes:
    call cairo_set_font_size (my_cairo_context, 20._dp)
    call cairo_move_to(my_cairo_context, width - 20._wp, Oy - 10._dp)
    call cairo_show_text (my_cairo_context, "x"//c_null_char)
    call cairo_move_to(my_cairo_context, Ox - 20._wp, +20._dp)
    call cairo_show_text (my_cairo_context, "y"//c_null_char)
    call cairo_move_to(my_cairo_context, Ox - 20._wp, Oy + 20._dp)
    call cairo_show_text (my_cairo_context, "O"//c_null_char)
    call cairo_set_font_size (my_cairo_context, 32._dp)
    call cairo_move_to(my_cairo_context, width / 10._dp, height / 10._dp)
    call cairo_show_text (my_cairo_context, "Mandelbrot set"//c_null_char)

    ! Circle of radius 1/4 centered around −1, in yellow:
    call cairo_set_source_rgb(my_cairo_context, 1._dp, 1._dp, 0._dp)
    call cairo_set_line_width(my_cairo_context, 3._dp)
    call cairo_new_sub_path(my_cairo_context)
    X_circle = width  * (-1._dp - xmin) / (xmax - xmin)
    call cairo_arc(my_cairo_context, X_circle, Oy, width / (xmax-xmin) / 4._dp, 0._dp, 2._dp*pi)
    call cairo_stroke(my_cairo_context)
    call cairo_set_font_size (my_cairo_context, 20._dp)
    call cairo_move_to(my_cairo_context, X_circle, Oy - 10._dp)
    call cairo_show_text (my_cairo_context, "circle"//c_null_char)

    ! Main cardioid centered on A(1/4, 0) with polar equation ro(teta) = 1/2*(1 − cos teta)
    X_cardio = width  * (1._dp/4._dp - xmin) / (xmax - xmin)
    call cairo_move_to(my_cairo_context, X_cardio, Oy)
    do i = 1, 100
      teta = (i * 2._dp * pi) / 100._dp
      ro = (1._dp - cos(teta)) / 2._dp
      ro = ro * width / (xmax - xmin)
      call cairo_line_to(my_cairo_context, X_cardio + ro*cos(teta), Oy + ro*sin(teta))
    end do
    call cairo_stroke(my_cairo_context)
    call cairo_move_to(my_cairo_context, Ox + 5._dp, Oy - 10._dp)
    call cairo_show_text (my_cairo_context, "cardioid"//c_null_char)

    ! The image is written to PNG only one time:
    if (write_png) then
      cstatus = cairo_surface_write_to_png(cairo_get_target(my_cairo_context),&
                                         & "cairo-tests.png"//c_null_char)
      print *, "Writing cairo-tests.png: ", cstatus
      write_png = .false.
    end if
  end subroutine my_draw_function

  ! The GUI is defined here:
  subroutine activate(app, gdata) bind(c)
    type(c_ptr), value, intent(in)  :: app, gdata
    type(c_ptr)     :: my_window
    type(c_ptr)     :: my_drawing_area
    integer(c_int)  :: width, height
    integer         :: bytes

    ! Properties of the main window:
    my_window = gtk_application_window_new(app)
    width  = 748
    height = 748
    call gtk_window_set_default_size(my_window, width, height)
    call gtk_window_set_resizable(my_window, FALSE)
    call gtk_window_set_title(my_window, "Cairo tests: mixing vector graphics with a pixbuf (gtk-fortran)"//c_null_char)

    my_drawing_area = gtk_drawing_area_new()
    call gtk_drawing_area_set_content_width(my_drawing_area, width)
    call gtk_drawing_area_set_content_height(my_drawing_area, height)
    call gtk_drawing_area_set_draw_func(my_drawing_area, &
                        & c_funloc(my_draw_function), c_null_ptr, c_null_funptr)

    ! Dimensions of the Mandelbrot set picture:
    pwidth  = width
    pheight = height
    ! "Creates a new GdkPixbuf structure and allocates a buffer for it":
    ! RGB, no alpha channel (FALSE), 8 bits per color sample, width, height
    my_pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8_c_int, pwidth, pheight)
    ! Queries the number of channels of a pixbuf:
    nch = gdk_pixbuf_get_n_channels(my_pixbuf)
    print *, "Number of channels of the pixbuf: ", nch
    ! "Queries the rowstride of a pixbuf, which is the number of bytes between
    ! the start of a row and the start of the next row":
    rowstride = gdk_pixbuf_get_rowstride(my_pixbuf)
    print *, "Rowstride of the pixbuf: ", rowstride
    bytes = pwidth * pheight * nch
    print *, "Size (bytes) of the pixbuf: ", bytes

    call c_f_pointer(gdk_pixbuf_get_pixels(my_pixbuf), pixel, [bytes])
    ! Drawing the whole set:
    call Mandelbrot_set(my_drawing_area, 1000_4)
    write_png = .true.

    call gtk_window_set_child(my_window, my_drawing_area)

    call gtk_widget_show(my_window)
  end subroutine activate

  !*********************************************
  ! A tribute to Benoit MANDELBROT (1924-2010)
  ! http://en.wikipedia.org/wiki/Mandelbrot_set
  !*********************************************
  subroutine Mandelbrot_set(my_drawing_area, itermax)
    type(c_ptr)   :: my_drawing_area
    integer       :: i, j, k, p, itermax
    real(wp)      :: x, y    ! coordinates in the complex plane
    complex(wp)   :: c, z
    real(wp)      :: scx, scy             ! scales
    real(wp)      :: t0, t1
    integer(int8) :: red, green, blue     ! rgb color
    integer, parameter :: factor = 8

    print *, "Entering Mandelbrot_set() subroutine"

    call cpu_time(t0)
    scx = (xmax - xmin) / pwidth   ! x scale
    scy = (ymax - ymin) / pheight  ! y scale

    do i = 0, pwidth-1
      x = xmin + scx * i

      do j = 0, pheight-1
        y = ymin + scy * j

        c = cmplx(x, y, kind=wp)    ! Starting point
        z = (0.0_wp, 0.0_wp)        ! z0
        k = 1
        do while ((k <= itermax) .and. ((z%re**2 + z%im**2) < 4.0_wp))
          z = z*z + c
          k = k + 1
        end do

        if (k > itermax) then
          ! Black pixel:
          red   = 0
          green = 0
          blue  = 0
        else
          ! Fortran purple is #734f96 : (115, 79, 150)
          red   = int(min(255, factor*k),  int8)
          green = int(min(255, nint(factor*k*79./115.)),  int8)
          blue  = int(min(255, nint(factor*k*150./115.)), int8)
        end if

        p = i * nch + j * rowstride + 1
        pixel(p)   = char(red)
        pixel(p+1) = char(green)
        pixel(p+2) = char(blue)
      end do
      ! This subroutine processes GTK events as needed during the computation
      ! (not really useful in that fast computation example)
      if (mod(i, 50) == 0) then
        call pending_events()
        if (run_status == FALSE) return   ! Exit if we had a delete event
      end if
    end do

    ! We only draw the image at the end of that fast computation:
    call gtk_widget_queue_draw(my_drawing_area)

    call cpu_time(t1)
    print '(A, F6.2, A)', "System time = ", t1-t0, " s"
  end subroutine mandelbrot_set

end module handlers

!***********************************************************
! We create a GtkApplication:
!***********************************************************
program cairo_tests
  use, intrinsic :: iso_c_binding
  use gtk, only: gtk_application_new, g_signal_connect, G_APPLICATION_FLAGS_NONE
  use g, only: g_application_run, g_object_unref
  use handlers, only: activate

  implicit none
  integer(c_int) :: exit_status
  type(c_ptr)    :: app

  app = gtk_application_new("gtk-fortran.examples.cairo-tests"//c_null_char, &
                          & G_APPLICATION_FLAGS_NONE)
  call g_signal_connect(app, "activate"//c_null_char, c_funloc(activate), &
                      & c_null_ptr)
  exit_status = g_application_run(app, 0_c_int, [c_null_ptr])
  call g_object_unref(app)
end program cairo_tests


================================================
FILE: examples/gio_demo.f90
================================================
! This file is part of gtk-fortran, a GTK / Fortran interface library.
! Copyright (C) 2013 The gtk-fortran team
!
! This is free software; you can redistribute it and/or modify
! it under the terms of the GNU General Public License as published by
! the Free Software Foundation; either version 3, or (at your option)
! any later version.
!
! This software is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
! GNU General Public License for more details.
!
! Under Section 7 of GPL version 3, you are granted additional
! permissions described in the GCC Runtime Library Exception, version
! 3.1, as published by the Free Software Foundation.
!
! You should have received a copy of the GNU General Public License along with
! this program; see the files LICENSE and LICENSE_EXCEPTION respectively.
! If not, see <http://www.gnu.org/licenses/>.
!
! Last modification: vmagnin 2023-03-14

program g_io_demo

  ! This is a very basic demo to get started with GIO. It uses Fortran I/O to
  ! read text from the keyboard & writes it to the file gio_demo.dat in the
  ! current directory.

  use, intrinsic :: iso_c_binding
  use gtk_sup

  !********************************
  ! Gtk modules for gio_demo.f90
  use g, only: g_file_new_for_path, g_file_replace, g_object_unref, &
       & g_output_stream_close, g_output_stream_write

  use gtk, only: FALSE, G_FILE_CREATE_NONE


  character(len=80) :: str
  integer(c_int8_t), dimension(80), target :: istr

  type(c_ptr) :: file, stream
  type(gerror), target :: errmsg
  character(len=120) :: errtxt
  integer(4) :: ios, i
  integer(c_size_t) :: ncput, nchars
  integer(c_int) :: iok

  file = g_file_new_for_path('gio_demo.dat'//c_null_char)

  ! Use g_file_replace here so that it won't crash if the file exists.
  stream = g_file_replace(file, c_null_char, FALSE, G_FILE_CREATE_NONE, &
       & c_null_ptr, c_loc(errmsg))

  if (.not. c_associated(stream)) then
     call c_f_string(errmsg%message, errtxt)
     print *, errtxt
     stop
  end if

  do
     write(*, "(a)", advance='no') "Text> "
     read(*, "(a)", iostat=ios) str
     if (ios /= 0) exit

     nchars = len_trim(str)
     do i = 1, int(nchars, kind=4)
        istr(i) = int(ichar(str(i:i)), kind=c_int8_t)
     end do
     istr(nchars+1) = ichar(c_new_line)

     ncput = g_output_stream_write(stream, c_loc(istr), &
          & nchars+1, c_null_ptr, c_loc(errmsg))
     if (ncput < 0_c_size_t) then
        call c_f_string(errmsg%message, errtxt)
        print *, errtxt
        stop
     end if
  end do

  iok = g_output_stream_close(stream, c_null_ptr, c_loc(errmsg))
  call g_object_unref(stream)
  if (.not. c_f_logical(iok)) then
     call c_f_string(errmsg%message, errtxt)
     print *, errtxt
     stop
  end if

  call g_object_unref(file)
  print *
end program g_io_demo


================================================
FILE: examples/gtkbuilder.cmb
================================================
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<!DOCTYPE cambalache-project SYSTEM "cambalache-project.dtd">
<cambalache-project version="0.10.2" target_tk="gtk-4.0">
  <ui>
	(1,None,"gtkbuilder.ui","gtkbuilder.ui",None,None,None,None,None,None)
  </ui>
  <object>
	(1,1,"GtkWindow","window",None,None,None,None,None),
	(1,2,"GtkBox","box1",1,None,None,None,-1),
	(1,3,"GtkButton","button1",2,None,None,None,None),
	(1,4,"GtkButton","button3",2,None,None,None,2),
	(1,5,"GtkButton","button2",2,None,None,None,1),
	(1,6,"GtkLabel","label1",2,None,None,None,3)
  </object>
  <object_property>
	(1,1,"GtkWindow","title","My title",None,None,None,None,None),
	(1,3,"GtkButton","label","Button1",None,None,None,None,None),
	(1,3,"GtkWidget","has-tooltip","True",None,None,None,None,None),
	(1,3,"GtkWidget","tooltip-text","I will say hello...",None,None,None,None,None),
	(1,4,"GtkButton","label","Exit",None,None,None,None,None),
	(1,4,"GtkWidget","has-tooltip","True",None,None,None,None,None),
	(1,4,"GtkWidget","tooltip-text","Not clear?",None,None,None,None,None),
	(1,5,"GtkButton","label","Button2",None,None,None,None,None),
	(1,5,"GtkWidget","has-tooltip","True",None,None,None,None,None),
	(1,5,"GtkWidget","tooltip-text","I will print 'Button 2 clicked!'",None,None,None,None,None),
	(1,6,"GtkLabel","justify","center",None,None,None,None,None),
	(1,6,"GtkLabel","label","This user interface was built with the new RAD software Cambalache (see &lt;a href=\"https://blogs.gnome.org/xjuan/\"&gt;https://blogs.gnome.org/xjuan/&lt;/a&gt;)",None,None,None,None,None),
	(1,6,"GtkLabel","lines","5",None,None,None,None,None),
	(1,6,"GtkLabel","max-width-chars","30",None,None,None,None,None),
	(1,6,"GtkLabel","selectable","True",None,None,None,None,None),
	(1,6,"GtkLabel","use-markup","True",None,None,None,None,None),
	(1,6,"GtkLabel","wrap","True",None,None,None,None,None),
	(1,6,"GtkLabel","yalign","0.4",None,None,None,None,None),
	(1,6,"GtkWidget","halign","center",None,None,None,None,None),
	(1,6,"GtkWidget","margin-end","10",None,None,None,None,None),
	(1,6,"GtkWidget","margin-start","10",None,None,None,None,None),
	(1,6,"GtkWidget","margin-top","4",None,None,None,None,None),
	(1,6,"GtkWidget","overflow","hidden",None,None,None,None,None)
  </object_property>
  <object_signal>
	(1,1,4,"GtkButton","clicked","destroy",None,None,None,None,None),
	(2,1,3,"GtkButton","clicked","hello",None,None,None,None,None),
	(3,1,5,"GtkButton","clicked","button2clicked",None,None,None,None,None),
	(4,1,1,"GtkWindow","close-request","destroy",None,None,None,None,None)
  </object_signal>
</cambalache-project>


================================================
FILE: examples/gtkbuilder.ui
================================================
<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.10.2 -->
<interface>
  <!-- interface-name gtkbuilder.ui -->
  <requires lib="gtk" version="4.6"/>
  <object class="GtkWindow" id="window">
    <property name="title">My title</property>
    <signal name="close-request" handler="destroy"/>
    <child>
      <object class="GtkBox" id="box1">
        <child>
          <object class="GtkButton" id="button1">
            <property name="has-tooltip">True</property>
            <property name="label">Button1</property>
            <property name="tooltip-text">I will say hello...</property>
            <signal name="clicked" handler="hello"/>
          </object>
        </child>
        <child>
          <object class="GtkButton" id="button2">
            <property name="has-tooltip">True</property>
            <property name="label">Button2</property>
            <property name="tooltip-text">I will print 'Button 2 clicked!'</property>
            <signal name="clicked" handler="button2clicked"/>
          </object>
        </child>
        <child>
          <object class="GtkButton" id="button3">
            <property name="has-tooltip">True</property>
            <property name="label">Exit</property>
            <property name="tooltip-text">Not clear?</property>
            <signal name="clicked" handler="destroy"/>
          </object>
        </child>
        <child>
          <object class="GtkLabel" id="label1">
            <property name="halign">center</property>
            <property name="justify">center</property>
            <property name="label">This user interface was built with the new RAD software Cambalache (see &lt;a href="https://blogs.gnome.org/xjuan/"&gt;https://blogs.gnome.org/xjuan/&lt;/a&gt;)</property>
            <property name="lines">5</property>
            <property name="margin-end">10</property>
            <property name="margin-start">10</property>
            <property name="margin-top">4</property>
            <property name="max-width-chars">30</property>
            <property name="overflow">hidden</property>
            <property name="selectable">True</property>
            <property name="use-markup">True</property>
            <property name="wrap">True</property>
            <property name="yalign">0.4</property>
          </object>
        </child>
      </object>
    </child>
  </object>
</interface>


================================================
FILE: examples/gtkbuilder2.f90
================================================
! This file is part of gtk-fortran, a GTK / Fortran interface library.
! Copyright (C) 2011 The gtk-fortran team
!
! This is free software; you can redistribute it and/or modify
! it under the terms of the GNU General Public License as published by
! the Free Software Foundation; either version 3, or (at your option)
! any later version.
!
! This software is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
! GNU General Public License for more details.
!
! Under Section 7 of GPL version 3, you are granted additional
! permissions described in the GCC Runtime Library Exception, version
! 3.1, as published by the Free Software Foundation.
! You should have received a copy of the GNU General Public License along with
! this program; see the files LICENSE and LICENSE_EXCEPTION respectively.
! If not, see <http://www.gnu.org/licenses/>.
!
! Example using GtkBuilder
! Jens Hunger, 04-01-2011
! Last modified: vmagnin 2020-06-20 (GTK 4 version), 2024-05-08

module widgets
  use, intrinsic :: iso_c_binding

  implicit none
  ! Declares the used GTK widgets:
  type(c_ptr) :: window, builder
  ! A GTK/GLib main loop:
  type(c_ptr) :: my_gmainloop
end module


module handlers
  use, intrinsic :: iso_c_binding
  use g, only: g_main_loop_quit
  use widgets, only: my_gmainloop

  implicit none

contains
  !*************************************
  ! User defined event handlers go here
  !*************************************

  ! "destroy" is a GtkObject signal
  subroutine destroy(widget, gdata) bind(c)
    !GCC$ ATTRIBUTES DLLEXPORT :: destroy
    type(c_ptr), value, intent(in) :: widget, gdata

    print *, "My destroy!"
    call g_main_loop_quit(my_gmainloop)
  end subroutine destroy

  ! "clicked" is a GtkButton signal
  subroutine hello(widget, gdata) bind(c)
    !GCC$ ATTRIBUTES DLLEXPORT :: hello
    type(c_ptr), value, intent(in) :: widget, gdata

    print *, "Hello World!"
  end subroutine hello

  subroutine button2clicked(widget, gdata) bind(c)
    !GCC$ ATTRIBUTES DLLEXPORT :: button2clicked
    type(c_ptr), value, intent(in) :: widget, gdata

    print *, "Button 2 clicked!"
  end subroutine button2clicked
end module handlers


program gtkbuilder
  use gtk, only: gtk_init, gtk_builder_new_from_file, gtk_builder_get_object, gtk_widget_show, FALSE
  use g, only: g_object_unref, g_main_loop_new, g_main_loop_run
  use widgets

  implicit none

  ! Initialize the GTK Library:
  call gtk_init()

  ! Create a new GtkBuilder object, parse the file 'gtkbuilder.ui'
  ! (generated with Cambalache) and add its content:
  builder = gtk_builder_new_from_file("gtkbuilder.ui"//c_null_char)

  ! Get a pointer to the GObject "window" from GtkBuilder:
  window = gtk_builder_get_object(builder, "window"//c_null_char)

  ! Free all memory used by XML stuff:
  call g_object_unref(builder)

  ! Show the Application Window:
  call gtk_widget_show(window)

  ! Create and enter the GTK/GLib main loop:
  my_gmainloop = g_main_loop_new(c_null_ptr, FALSE)
  call g_main_loop_run(my_gmainloop)

end program gtkbuilder


================================================
FILE: examples/gtkhello.f90
================================================
! This file is part of gtk-fortran, a GTK / Fortran interface library.
! Copyright (C) 2020 The gtk-fortran team
!
! This is free software; you can redistribute it and/or modify
! it under the terms of the GNU General Public License as published by
! the Free Software Foundation; either version 3, or (at your option)
! any later version.
!
! This software is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
! GNU General Public License for more details.
!
! Under Section 7 of GPL version 3, you are granted additional
! permissions described in the GCC Runtime Library Exception, version
! 3.1, as published by the Free Software Foundation.
! You should have received a copy of the GNU General Public License along with
! this program; see the files LICENSE and LICENSE_EXCEPTION respectively.
! If not, see <http://www.gnu.org/licenses/>.
!-------------------------------------------------------------------------------
! Vincent MAGNIN, 2020-05-12, based on gtkzero_gapp.f90
! Last modified: 2021-01-22
! A GTK application with two buttons.
! https://developer.gnome.org/gtk4/unstable/gtk-getting-started.html
! https://developer.gnome.org/gio/stable/GApplication.html
!-------------------------------------------------------------------------------

!*************************************
! User defined event handlers go here
!*************************************
! Note that events are a special type of signals, coming from
! the X Window system. Callback functions must have an event argument.
module handlers

  use, intrinsic :: iso_c_binding, only: c_ptr, c_int, c_funloc, c_null_char
  use gtk, only: FALSE, gtk_window_set_default_size,  &
               & gtk_window_set_title, gtk_window_destroy, &
               & g_signal_connect, g_signal_connect_swapped, &
               & gtk_widget_show, gtk_application_window_new, &
               & gtk_box_new, gtk_box_append, gtk_window_set_child, &
               & GTK_ORIENTATION_VERTICAL, GTK_ORIENTATION_HORIZONTAL, &
               & gtk_button_new_with_label, gtk_button_new_with_mnemonic, &
               & gtk_widget_set_margin_start, gtk_widget_set_margin_end, &
               & gtk_widget_set_margin_top, gtk_widget_set_margin_bottom
  implicit none

contains
  ! Callback function for the signal "activate" emitted by g_application_run().
  ! We use a subroutine because it should return void.
  ! The GUI is defined here.
  subroutine activate(app, gdata) bind(c)
    type(c_ptr), value, intent(in)  :: app, gdata
    ! Pointers toward our GTK widgets:
    type(c_ptr) :: window
    type(c_ptr) :: box
    type(c_ptr) :: button1, button2

    ! Create the window:
    window = gtk_application_window_new(app)
    ! Not compulsory, but can be used if you want a larger window:
    !call gtk_window_set_default_size(window, 300, 200)
    ! Don't forget that C strings must end with a null char:
    call gtk_window_set_title(window, "Hello GLib & GTK world!"//c_null_char)

    !******************************************************************
    ! Adding widgets in the window:
    !******************************************************************
    ! You need a box where to arrange your buttons, separated by 10 pixels:
    box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10_c_int)
    ! Perhaps you prefer a vertical organization:
    !box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10_c_int)
    ! Set the border width (10 pixels) around the box:
    call gtk_widget_set_margin_start (box, 10_c_int)
    call gtk_widget_set_margin_end (box, 10_c_int)
    call gtk_widget_set_margin_top (box, 10_c_int)
    call gtk_widget_set_margin_bottom (box, 10_c_int)
    ! You need a container where to put the box, it will manage layout:
    call gtk_window_set_child(window, box)

    ! It's easy to create a button:
    button1 = gtk_button_new_with_label("I say hello"//c_null_char)
    ! Let's pack the button in the box:
    call gtk_box_append(box, button1)
    ! You can associate one or several callback functions with the button,
    ! "clicked" is a GtkButton signal emitted when you click on it:
    call g_signal_connect(button1, "clicked"//c_null_char, &
                        & c_funloc(button1clicked))
    call g_signal_connect(button1, "clicked"//c_null_char, c_funloc(hello))

    ! For that second button, there is an ALT+g keyboard shortcut:
    button2 = gtk_button_new_with_mnemonic("I don't know why you say _goodbye"&
                                          &//c_null_char)
    ! Let's pack the second button in the box (from left to right):
    call gtk_box_append(box, button2)
    ! Let's associate one callback function when that button is clicked.
    ! Here the gtk_window_destroy() function will be applied
    ! to window instead of button2:
    call g_signal_connect_swapped(button2, "clicked"//c_null_char, &
                                & c_funloc(gtk_window_destroy), window)
    !******************************************************************

    ! If you don't show it, nothing will appear on screen...
    call gtk_widget_show(window)

  end subroutine activate

  ! The two callback functions for the button1, here subroutines
  ! because the C prototype returns void:
  ! void user_function (GtkButton *button, gpointer   user_data)
  ! https://developer.gnome.org/gtk4/stable/GtkButton.html#GtkButton-clicked
  subroutine hello(widget, gdata) bind(c)
    type(c_ptr), value, intent(in)  :: widget, gdata

    print *, "So I say Hello GTK World!"
  end subroutine hello

  subroutine button1clicked(widget, gdata) bind(c)
    type(c_ptr), value, intent(in)  :: widget, gdata

    print *, "Button 1 clicked!"
  end subroutine button1clicked

end module handlers

!*******************************************************************************
! In the main program, we declare the GTK application, connect it to its
! "activate" function where we will create the GUI,
! and finally call the GLib main loop.
!*******************************************************************************
program gtkhello

  use, intrinsic :: iso_c_binding, only: c_ptr, c_funloc, c_null_char, c_null_ptr
  ! We will use those GTK functions and values. The "only" statement can improve
  ! significantly the compilation time:
  use gtk, only: gtk_application_new, G_APPLICATION_FLAGS_NONE
  use g, only: g_application_run, g_object_unref
  use handlers

  implicit none
  integer(c_int)     :: status
  type(c_ptr)        :: app

  ! First, let's create a GTK application (it will initialize GTK).
  ! The application ID must contain at least one point:
  ! https://developer.gnome.org/gio/stable/GApplication.html#g-application-id-is-valid
  app = gtk_application_new("gtk-fortran.examples.gtkhello"//c_null_char, &
                            & G_APPLICATION_FLAGS_NONE)
  ! The activate signal will be sent by g_application_run().
  ! The c_funloc() function returns the C address of the callback function.
  ! The c_null_ptr means no data is transfered to the callback function.
  call g_signal_connect(app, "activate"//c_null_char, c_funloc(activate), &
                      & c_null_ptr)
  ! Now, the whole application will be managed by GLib (=> main loop).
  ! Note that commandline arguments argc, argv are not passed.
  ! https://developer.gnome.org/gio/stable/GApplication.html#g-application-run
  status = g_application_run(app, 0_c_int, [c_null_ptr])

  print *, "You have exited the GLib main loop, bye, bye..."

  ! Memory is freed:
  call g_object_unref(app)

end program gtkhello



================================================
FILE: examples/gtkzero_gapp.f90
================================================
! This file is part of gtk-fortran, a GTK / Fortran interface library.
! Copyright (C) 2020 The gtk-fortran team
!
! This is free software; you can redistribute it and/or modify
! it under the terms of the GNU General Public License as published by
! the Free Software Foundation; either version 3, or (at your option)
! any later version.
!
! This software is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
! GNU General Public License for more details.
!
! Under Section 7 of GPL version 3, you are granted additional
! permissions described in the GCC Runtime Library Exception, version
! 3.1, as published by the Free Software Foundation.
! You should have received a copy of the GNU General Public License along with
! this program; see the files LICENSE and LICENSE_EXCEPTION respectively.
! If not, see <http://www.gnu.org/licenses/>.
!-------------------------------------------------------------------------------
! Vincent MAGNIN, 2020-02-18
! Last modified: 2020-05-07
! This example just creates a GTK application with an empty window.
! https://developer.gnome.org/gtk4/unstable/gtk-getting-started.html
! https://developer.gnome.org/gio/stable/GApplication.html
!-------------------------------------------------------------------------------

!*************************************
! User defined event handlers go here
!*************************************
module handlers

  use, intrinsic :: iso_c_binding, only: c_ptr, c_null_char
  use gtk, only: gtk_window_set_default_size, gtk_window_set_title, &
               & gtk_widget_show, gtk_application_window_new
  implicit none

contains
  ! Callback function for the signal "activate" emitted by g_application_run().
  ! We use a subroutine because it should return void.
  ! The GUI is defined here.
  subroutine activate(app, gdata) bind(c)
    type(c_ptr), value, intent(in) :: app, gdata
    type(c_ptr)                    :: window

    ! Create the window:
    window = gtk_application_window_new(app)
    ! Not compulsory, but can be used if you want a larger window:
    call gtk_window_set_default_size(window, 300, 200)
    ! Don't forget that C strings must end with a null char:
    call gtk_window_set_title(window, "Hello GLib & GTK world!"//c_null_char)
    ! If you don't show it, nothing will appear on screen...
    call gtk_widget_show(window)
  end subroutine activate

end module handlers

!*********************************************************************************************
! In the main program, we declare the GTK application, connect it to its "activate" function
! where we will create the GUI, and finally call the GLib main loop.
!*********************************************************************************************
program gtkzero

  use, intrinsic :: iso_c_binding, only: c_ptr, c_int, c_null_char, c_null_ptr, c_funloc
  ! We will use those GTK functions and values. The "only" statement can improve
  ! significantly the compilation time:
  use gtk, only: gtk_application_new, g_signal_connect, G_APPLICATION_FLAGS_NONE
  use g, only: g_application_run, g_object_unref

  use handlers

  implicit none
  integer(c_int)     :: status
  type(c_ptr)        :: app

  ! First, let's create a GTK application (it will initialize GTK).
  ! The application ID must contain at least one point:
  ! https://developer.gnome.org/gio/stable/GApplication.html#g-application-id-is-valid
  app = gtk_application_new("gtk-fortran.examples.gtkzero"//c_null_char, &
                            & G_APPLICATION_FLAGS_NONE)
  ! The activate signal will be sent by g_application_run().
  ! The c_funloc() function returns the C address of the callback function.
  ! The c_null_ptr means no data is transfered to the callback function.
  call g_signal_connect(app, "activate"//c_null_char, c_funloc(activate), c_null_ptr)
  ! Now, the whole application will be managed by GLib (=> main loop).
  ! Note that commandline arguments argc, argv are not passed.
  ! https://developer.gnome.org/gio/stable/GApplication.html#g-application-run
  status = g_application_run(app, 0_c_int, [c_null_ptr])

  print *, "You have exited the GLib main loop, bye, bye..."

  ! Memory is freed:
  call g_object_unref(app)

end program gtkzero


================================================
FILE: examples/hl_assistant.f90
================================================
! This file is part of gtk-fortran, a GTK / Fortran interface library.
! Copyright (C) 2012 The gtk-fortran team
!
! This is free software; you can redistribute it and/or modify
! it under the terms of the GNU General Public License as published by
! the Free Software Foundation; either version 3, or (at your option)
! any later version.
!
! This software is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
! GNU General Public License for more details.
!
! Under Section 7 of GPL version 3, you are granted additional
! permissions described in the GCC Runtime Library Exception, version
! 3.1, as published by the Free Software Foundation.
!
! You should have received a copy of the GNU General Public License along with
! this program; see the files LICENSE and LICENSE_EXCEPTION respectively.
! If not, see <http://www.gnu.org/licenses/>.
!------------------------------------------------------------------------------
! Contributed by James Tappin.
! Last modification: vmagnin 2020-06-09 (GTK 4), 2022-05-06
!
! Based on the C example given in"
! https://www.linuxquestions.org/linux/articles/Technical/New_GTK_Widgets_GtkAssistant
!------------------------------------------------------------------------------

module as_handlers
!  use gtk_hl
  use gtk_hl_container
  use gtk_hl_button
  use gtk_hl_progress
  use gtk_hl_entry
  use gtk_hl_assistant
  use gtk_sup
  use, intrinsic :: iso_c_binding

  !********************************
  ! Gtk modules for hl_assistant.f90
  !********************************
  use g, only: g_usleep, g_main_loop_new, g_main_loop_quit, &
             & g_main_loop_run, g_main_context_iteration, &
             & g_main_context_pending
  use gtk, only: gtk_entry_get_buffer, gtk_entry_buffer_get_text, &
       & gtk_label_new, &
       & gtk_check_button_get_active, gtk_window_destroy, &
       & gtk_widget_set_sensitive, gtk_widget_show, gtk_init, TRUE, FALSE, &
       & GTK_ASSISTANT_PAGE_CONTENT, GTK_ASSISTANT_PAGE_INTRO, &
       & GTK_ASSISTANT_PAGE_CONFIRM, GTK_ASSISTANT_PAGE_PROGRESS, &
       & gtk_widget_set_halign, gtk_widget_set_valign, gtk_widget_set_hexpand,&
       & gtk_widget_set_vexpand, GTK_ALIGN_CENTER, GTK_ALIGN_FILL

  implicit none
  type(c_ptr) :: my_gmainloop
  type(c_ptr) :: asstnt

contains
  subroutine destroy_asstnt(widget, gdata) bind(c)
    type(c_ptr), value :: widget, gdata

    print *, "Exit called"
    call g_main_loop_quit(my_gmainloop)
  end subroutine destroy_asstnt

  subroutine asstnt_close(widget, gdata) bind(c)
    type(c_ptr), value :: widget, gdata

    print *, "Completed"
    call gtk_window_destroy(widget)
  end subroutine asstnt_close

  subroutine name_enter(widget, data) bind(c)
    type(c_ptr), value :: widget, data
    type(c_ptr) :: buffer
    type(c_ptr) :: page, ebox
    character(:), allocatable :: ftext

    if (c_associated(data)) then
       ebox = data
    else
       ebox = widget
    end if

     buffer = gtk_entry_get_buffer(ebox)
    call c_f_string_copy_alloc(gtk_entry_buffer_get_text(buffer), ftext)
    print *, "Entered name as: ", ftext

    page = hl_gtk_assistant_get_current_page(asstnt)
    call hl_gtk_assistant_set_page_complete(asstnt, &
         & f_c_logical(len(ftext) > 0))
  end subroutine name_enter

  subroutine check_tog(widget, data) bind(c)
    type(c_ptr), value :: widget, data

    call hl_gtk_assistant_set_page_complete(asstnt, &
         & gtk_check_button_get_active(widget))
  end subroutine check_tog

  subroutine start_pb(widget, data) bind(c)
    type(c_ptr), value :: widget, data

    integer(c_int) :: i, iev
    type(c_ptr) :: page

    call gtk_widget_set_sensitive(widget, FALSE)

    page = hl_gtk_assistant_get_current_page(asstnt)
    do i = 1, 10
       do
          if (.not. c_f_logical(g_main_context_pending(c_null_ptr))) exit
          iev = g_main_context_iteration(c_null_ptr, FALSE)
       end do

       call g_usleep(500000_c_long)
       call hl_gtk_progress_bar_set(data, i, 10_c_int, string=TRUE)
    end do
    call hl_gtk_assistant_set_page_complete(asstnt, TRUE)

  end subroutine start_pb
end module as_handlers

program hl_assistant

  use as_handlers

  implicit none
  type(c_ptr) :: junk, jb, ebox, pbar

  call gtk_init()

  asstnt = hl_gtk_assistant_new(title="GtkAssistant Example"//c_null_char, &
       & destroy=c_funloc(destroy_asstnt), wsize=[450_c_int, 300_c_int], &
       & close=c_funloc(asstnt_close))

  ! Intro page
  junk = gtk_label_new("This is an example of a GtkAssistant"//c_new_line// &
       & "by clicking the forward button,"//c_new_line// &
       & " you can continue to the next section!"//c_null_char)

  call hl_gtk_assistant_add_page(asstnt, junk, GTK_ASSISTANT_PAGE_INTRO, &
       & page_title="Introduction"//c_null_char)

  ! Name entry
  jb = hl_gtk_box_new(horizontal=TRUE, spacing=5_c_int)
  call gtk_widget_set_halign (jb, GTK_ALIGN_FILL)
  call gtk_widget_set_valign (jb, GTK_ALIGN_CENTER)
  call gtk_widget_set_hexpand (jb, TRUE)
  call gtk_widget_set_vexpand (jb, FALSE)

  junk = gtk_label_new("Your name:"//c_null_char)
  call hl_gtk_box_pack(jb, junk, expand=FALSE)

  ebox = hl_gtk_entry_new(editable=TRUE, activate=c_funloc(name_enter))
  call hl_gtk_box_pack(jb, ebox)

  junk = hl_gtk_button_new("Apply"//c_null_char, clicked=c_funloc(name_enter), &
       & data=ebox)
  call hl_gtk_box_pack(jb, junk, expand=FALSE)

  call hl_gtk_assistant_add_page(asstnt, jb, GTK_ASSISTANT_PAGE_CONTENT)

  ! Check button
  junk = hl_gtk_check_button_new("Click to continue"//c_null_char, &
       &toggled = c_funloc(check_tog))
  call hl_gtk_assistant_add_page(asstnt, junk, GTK_ASSISTANT_PAGE_CONTENT, &
       & page_title="Click the Check Button"//c_null_char)

  ! Progress
  jb = hl_gtk_box_new(horizontal=TRUE)
  call gtk_widget_set_halign (jb, GTK_ALIGN_FILL)
  call gtk_widget_set_valign (jb, GTK_ALIGN_CENTER)
  call gtk_widget_set_hexpand (jb, TRUE)
  call gtk_widget_set_vexpand (jb, FALSE)

  pbar = hl_gtk_progress_bar_new()
  call hl_gtk_box_pack(jb, pbar)

  junk = hl_gtk_button_new("Click to start"//c_null_char, &
       & clicked=c_funloc(start_pb), data=pbar)
  call hl_gtk_box_pack(jb, junk, expand=false)
  call hl_gtk_assistant_add_page(asstnt, jb, GTK_ASSISTANT_PAGE_PROGRESS, &
       & page_title="Applying"//c_null_char)

  ! Confirmation page
  junk = gtk_label_new ("Text has been entered in the label and"//c_new_line// &
       & "the combo box is clicked. If you are done, then"//c_new_line// &
       & "it is time to leave!"//c_null_char)
  call hl_gtk_assistant_add_page(asstnt, junk, GTK_ASSISTANT_PAGE_CONFIRM, &
       & page_title = "Completed?"//c_null_char)

  call gtk_widget_show(asstnt)

  ! Event loop
  my_gmainloop = g_main_loop_new(c_null_ptr, FALSE)
  call g_main_loop_run(my_gmainloop)

end program hl_assistant


================================================
FILE: examples/hl_cairo1.f90
================================================
! This file is part of gtk-fortran, a GTK / Fortran interface library.
! Copyright (C) 2011 The gtk-fortran team
!
! This is free software; you can redistribute it and/or modify
! it under the terms of the GNU General Public License as published by
! the Free Software Foundation; either version 3, or (at your option)
! any later version.
!
! This software is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
! GNU General Public License for more details.
!
! Under Section 7 of GPL version 3, you are granted additional
! permissions described in the GCC Runtime Library Exception, version
! 3.1, as published by the Free Software Foundation.
!
! You should have received a copy of the GNU General Public License along with
! this program; see the files LICENSE and LICENSE_EXCEPTION respectively.
! If not, see <http://www.gnu.org/licenses/>.
!------------------------------------------------------------------------------
! Contributed by James Tappin,
! originally derived from cairo_basics.f90 by Vincent Magnin & Jerry DeLisle
! Last modifications: vmagnin 2020-06-17 (GTK 4), 2025-05-27
!------------------------------------------------------------------------------

module handlers
  use, intrinsic :: iso_c_binding

  !********************************
  ! Gtk modules for hl_cairo1.f90
  !********************************
  use cairo, only: cairo_arc, cairo_curve_to, cairo_get_target, &
       & cairo_line_to, cairo_move_to, cairo_new_sub_path, cairo_paint, &
       & cairo_rectangle, cairo_select_font_face, cairo_set_font_size, &
       & cairo_set_line_width, cairo_set_source_rgb, cairo_show_text, &
       & cairo_stroke, cairo_surface_write_to_png
  use gdk, only: gdk_device_get_name, gdk_keyval_from_name, gdk_keyval_name
  use gtk, only: gtk_window_set_child, gtk_window_destroy, &
       & gtk_widget_queue_draw, gtk_widget_show, gtk_init, TRUE, FALSE, &
       & GDK_CONTROL_MASK, &
       & CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL, &
       & gtk_event_controller_get_current_event_device, &
       & gtk_gesture_single_get_current_button
  use gdk_events

  use gdk_pixbuf_hl
  use gtk_draw_hl
  use gtk_hl_container
  use gtk_sup

  implicit none
  type(c_ptr) :: my_window
  type(c_ptr) :: my_cairo_context
  integer(c_int) :: boolresult
  logical :: boolevent
  integer(c_int) :: width, height
  logical :: rflag = .false.
  integer(c_int) :: xp0, yp0

contains
  ! User defined event handlers go here

  ! GTK 4: Click callback function ("pressed" signal):
  subroutine button_event_h(gesture, n_press, x, y, gdata) bind(c)
    type(c_ptr), value, intent(in)    :: gesture, gdata
    integer(c_int), value, intent(in) :: n_press
    real(c_double), value, intent(in) :: x, y
    type(c_ptr) :: device, dcname
    character(len=80) :: dname

    print *, "Button ", gtk_gesture_single_get_current_button(gesture)
    print *, n_press, " click(s) at ", int(x), int(y)

    if (n_press > 1) then
      print *, "Multiple clicks"
    end if

    device = gtk_event_controller_get_current_event_device(gesture)
    dcname = gdk_device_get_name(device)
    call c_f_string(dcname, dname)
    print *, "Device: ",trim(dname)
  end subroutine button_event_h

  ! GTK 4: Click callback function ("released" signal):
  subroutine button_release_h(gesture, n_press, x, y, gdata) bind(c)
    type(c_ptr), value, intent(in)    :: gesture, gdata
    integer(c_int), value, intent(in) :: n_press
    real(c_double), value, intent(in) :: x, y

    print *, "Button released: ", gtk_gesture_single_get_current_button(gesture)
  end subroutine button_release_h

  ! GTK 4: Motion callback function ("motion" signal):
  subroutine motion_event_h(controller, x, y, gdata) bind(c)
    type(c_ptr), value, intent(in)    :: controller, gdata
    real(c_double), value, intent(in) :: x, y

    write(*, "(2I5,A)", advance='no') nint(x), nint(y), c_carriage_return
  end subroutine motion_event_h

  ! GTK 4 : Scroll callback function ("scroll" signal):
  subroutine scroll_event_h(controller, x, y, gdata) bind(c)
    type(c_ptr), value, intent(in)    :: controller, gdata
    real(c_double), value, intent(in) :: x, y

    print *, "Scroll event detected : x,y= ", x, y
  end subroutine scroll_event_h

  ! GTK 4 : motion callback function ("enter" signal):
  subroutine enter_event_h(controller, x, y, gdata) bind(c)
    type(c_ptr), value, intent(in)    :: controller, gdata
    real(c_double), value, intent(in) :: x, y

    print *, "Enter event detected : x,y= ", x, y
  end subroutine enter_event_h

  ! GTK 4 : motion callback function ("leave" signal):
  subroutine leave_event_h(controller, gdata) bind(c)
    type(c_ptr), value, intent(in)    :: controller, gdata
    print *, "Leave event detected"
  end subroutine leave_event_h

  ! GTK 4 : key callback function ("key-pressed" signal):
  ! https://developer.gnome.org/gdk4/stable/gdk4-Keyboard-Handling.html
  function key_event_h(controller, keyval, keycode, state, gdata) result(ret) bind(c)
    type(c_ptr), value, intent(in) :: controller, gdata
    integer(c_int), value, intent(in) :: keyval, keycode, state
    logical(c_bool) :: ret
    character(len=20) :: keyname
    integer(c_int) :: key_q

    call convert_c_string(gdk_keyval_name(keyval), keyname)
    print *, "Keyval: ",keyval," Name: ", trim(keyname), "      Keycode: ", &
             & keycode, " Modifier: ", state

    key_q = gdk_keyval_from_name("q"//c_null_char)
    ! CTRL+Q will close the program:
    if ((iand(state, GDK_CONTROL_MASK) /= 0).and.(keyval == key_q)) then
      call gtk_window_destroy(my_window)
    end if

    ret = .true.
  end function key_event_h


  subroutine draw_pattern(widget)
    type(c_ptr) :: widget
    real(c_double), parameter :: pi = acos(-1.0_c_double)
    integer :: cstatus
    integer :: t

    my_cairo_context = hl_gtk_drawing_area_cairo_new(widget)
    if (.not. c_associated(my_cairo_context)) then
       print *, "ERROR failed to create cairo context"
       return
    end if

    ! Background
    call cairo_set_source_rgb(my_cairo_context, 0.6_c_double, 0.6_c_double, &
         & 0.6_c_double)
    call cairo_rectangle(my_cairo_context, 0._c_double, 0._c_double,&
         & real(width, c_double), real(height, c_double))
    call cairo_paint(my_cairo_context)

    ! Bezier curve:
    call cairo_set_source_rgb(my_cairo_context, 0.9_c_double, 0.8_c_double, &
         & 0.8_c_double)
    call cairo_set_line_width(my_cairo_context, 4._c_double)
    call cairo_move_to(my_cairo_context, 0._c_double, 0._c_double)
    call cairo_curve_to(my_cairo_context, 600._c_double, 50._c_double, &
         & 115._c_double, 545._c_double, &
         & real(width, c_double), real(height, c_double))
    call cairo_stroke(my_cairo_context)

    ! Lines:
    call cairo_set_source_rgb(my_cairo_context, 0._c_double, 0.5_c_double, &
         & 0.5_c_double)
    call cairo_set_line_width(my_cairo_context, 2._c_double)
    do t = 0, int(height), +20
       call cairo_move_to(my_cairo_context, 0._c_double, real(t, c_double))
       call cairo_line_to(my_cairo_context, real(t, c_double), &
            & real(height, c_double))
       call cairo_stroke(my_cairo_context)
    end do

    ! Text:
    call cairo_set_source_rgb(my_cairo_context, 0._c_double, 0._c_double, &
         & 1._c_double)
    call cairo_select_font_face(my_cairo_context, "Times"//c_null_char, &
         & CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL)
    call cairo_set_font_size (my_cairo_context, 40._c_double)
    call cairo_move_to(my_cairo_context, 100._c_double, 30._c_double)
    call cairo_show_text (my_cairo_context, "gtk-fortran"//c_null_char)
    call cairo_move_to(my_cairo_context, 100._c_double, 75._c_double)
    call cairo_show_text (my_cairo_context, "Cairo & Fortran are good friends"//c_null_char)

    ! Circles:
    call cairo_new_sub_path(my_cairo_context)
    do t = 1, 50
       call cairo_set_source_rgb(my_cairo_context, t/50._c_double, &
            & 0._c_double, 0._c_double)
       call cairo_set_line_width(my_cairo_context, 5._c_double*t/50._c_double)
       call cairo_arc(my_cairo_context, 353._c_double+ &
            & 200._c_double*cos(t*2_c_double*pi/50), &
            & 350._c_double+200._c_double*sin(t*2._c_double*pi/50._c_double), &
            & 50._c_double, 0._c_double, 2._c_double*pi)
       call cairo_stroke(my_cairo_context)
    end do

    ! Save:
    cstatus = cairo_surface_write_to_png(cairo_get_target(my_cairo_context), &
         & "cairo.png"//c_null_char)

    call gtk_widget_queue_draw(widget)
    call hl_gtk_drawing_area_cairo_destroy(my_cairo_context)
  end subroutine draw_pattern

  subroutine activate(app, gdata) bind(c)
    use, intrinsic :: iso_c_binding, only: c_ptr, c_funloc, c_null_char
    use gtk, only: gtk_application_window_new, gtk_window_set_title
    implicit none
    type(c_ptr), value, intent(in)  :: app, gdata
    ! Pointers toward our GTK widgets:
    type(c_ptr) :: my_drawing_area
    type(c_ptr) :: my_scroll_box

    ! Properties of the main window :
    width = 700
    height = 700
    ! Create the window:
    my_window = gtk_application_window_new(app)
    call gtk_window_set_title(my_window, "Cairo events demo (CTRL+Q to quit)"//c_null_char)

    my_drawing_area = hl_gtk_drawing_area_new(&
         & scroll=my_scroll_box, &
         & size = [width, height ], &
         & ssize = [ 400_c_int, 300_c_int ], &
         & button_press_event=c_funloc(button_event_h), &
         & button_release_event=c_funloc(button_release_h), &
         & scroll_event=c_funloc(scroll_event_h), &
         & enter_event=c_funloc(enter_event_h), &
         & leave_event=c_funloc(leave_event_h), &
         & key_press_event=c_funloc(key_event_h), &
         & motion_event=c_funloc(motion_event_h))

    call gtk_window_set_child(my_window, my_scroll_box)

    call gtk_widget_show(my_window)
    call draw_pattern(my_drawing_area)
  end subroutine activate
end module handlers


program cairo_basics_click
  use, intrinsic :: iso_c_binding, only: c_ptr, c_funloc, c_null_char, c_null_ptr
  use handlers

  implicit none
  type(c_ptr)        :: app

  app = hl_gtk_application_new("gtk-fortran.examples.hl_cairo1"//c_null_char, &
                             & c_funloc(activate))
end program cairo_basics_click



================================================
FILE: examples/hl_cairo_clock.f90
================================================
! This file is part of gtk-fortran, a GTK / Fortran interface library.
! Copyright (C) 2011 The gtk-fortran team
!
! This is free software; you can redistribute it and/or modify
! it under the terms of the GNU General Public License as published by
! the Free Software Foundation; either version 3, or (at your option)
! any later version.
!
! This software is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
! GNU General Public License for more details.
!
! Under Section 7 of GPL version 3, you are granted additional
! permissions described in the GCC Runtime Library Exception, version
! 3.1, as published by the Free Software Foundation.
!
! You should have received a copy of the GNU General Public License along with
! this program; see the files LICENSE and LICENSE_EXCEPTION respectively.
! If not, see <http://www.gnu.org/licenses/>.
!------------------------------------------------------------------------------
! Contributed by: James Tappin
! Last modifications: vmagnin 2020-06-17 (GTK 4), 2025-05-27
!------------------------------------------------------------------------------

module cl_handlers
  !********************************
  ! Gtk modules for hl_cairo_clock.f90
  !********************************
  use cairo, only: cairo_arc, cairo_fill, cairo_fill_preserve, cairo_line_to, &
       & cairo_move_to, cairo_new_path, cairo_paint, cairo_rectangle, &
       & cairo_select_font_face, cairo_set_font_size, cairo_set_line_cap, &
       & cairo_set_line_width, cairo_set_source_rgb, cairo_set_source_rgba, &
       & cairo_show_text, cairo_stroke
  use g, only: g_timeout_add
  use gdk, only: gdk_keyval_from_name
  use gtk, only: gtk_window_set_child, gtk_window_destroy, &
       & gtk_widget_get_allocation, gtk_widget_queue_draw, &
       & gtk_widget_show, TRUE, FALSE, GDK_CONTROL_MASK, &
       & CAIRO_LINE_CAP_ROUND, CAIRO_FONT_SLANT_NORMAL, &
       & CAIRO_FONT_WEIGHT_BOLD
  use gdk_pixbuf_hl
  use gtk_draw_hl
  use gtk_hl_container
  use gdk_events
  use, intrinsic :: iso_c_binding

  implicit none
  integer(c_int) :: height=250_c_int, width=250_c_int
  real(c_double), parameter :: pi = acos(-1.0_c_double)
  integer, dimension(8) :: t0 = 0
  type(c_ptr) :: window
  type(c_ptr) :: app

contains

  function show_time(area) bind(c)
    integer(c_int) :: show_time
    type(c_ptr), value, intent(in) :: area

    integer, dimension(8) :: dat
    type(c_ptr) :: cr
    character(len=3) :: sdate

    character(len=4), parameter, dimension(12) :: mnames = &
         & ['JAN'//c_null_char, 'FEB'//c_null_char, 'MAR'//c_null_char, &
         &   'APR'//c_null_char, 'MAY'//c_null_char, 'JUN'//c_null_char, &
         &   'JUL'//c_null_char, 'AUG'//c_null_char, 'SEP'//c_null_char, &
         &   'OCT'//c_null_char, 'NOV'//c_null_char, 'DEC'//c_null_char ]
    integer :: i
    real(c_double) :: r0, r1, x0, x1, y0, y1, th, xc, yc, ycs
    real(c_double) :: xb, xt, yb, yt, radius, scale_factor

    show_time = TRUE

    call date_and_time(values=dat)
    if (all(dat(5:7) == t0(5:7))) return

    t0 = dat

    cr = hl_gtk_drawing_area_cairo_new(area)

    xc = real(width, c_double) / 2._c_double
    yc = real(height, c_double) / 2._c_double
    radius = min(xc, yc)
    scale_factor = radius/125._c_double

    if (height > width) then
       xb = 0._c_double
       xt = real(width, c_double)
       yt = yc - xc
       yb = yc + xc
    else if (height < width) then
       xb = xc - yc
       xt = xc + yc
       yt = 0._c_double
       yb = real(height, c_double)
    else
       xb = 0._c_double
       xt = real(width, c_double)
       yt = 0._c_double
       yb = real(height, c_double)
    end if

    ! Background
    call cairo_set_source_rgb(cr, 0.3_c_double, 0.0_c_double, &
         & 0.0_c_double)
    call cairo_rectangle(cr, 0._c_double, 0._c_double,&
         & real(width, c_double), real(height, c_double))
    call cairo_paint(cr)

    ! Face
    r0 = radius * 0.85_c_double
    call cairo_set_source_rgb(cr, 0.3_c_double, 0.3_c_double, 0._c_double)
    call cairo_new_path(cr)
    call cairo_move_to(cr, xc+r0, yc)
    call cairo_arc(cr, xc, yc, r0, 0._c_double, 2*pi)
    call cairo_fill(cr)

    ! Sub face
    r0 =  radius * 0.25_c_double
    call cairo_set_source_rgb(cr, 0.2_c_double, 0.7_c_double, 0.7_c_double)
    ycs = yc + 0.375_c_double*radius
    call cairo_new_path(cr)
    call cairo_move_to(cr, xc+r0, ycs)
    call cairo_arc(cr, xc, ycs, r0, 0._c_double, 2*pi)
    call cairo_fill(cr)

    ! Clock dials
    ! Main
    call cairo_set_source_rgb(cr, 1._c_double, 1._c_double, &
         & 1._c_double)
    call cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND)
    do i = 1, 60
       if (mod(i,15) == 0) then
          call cairo_set_line_width(cr, 5._c_double)
          r0 = radius * 0.75_c_double
          r1 = radius * 0.9_c_double
       else if (mod(i,5) == 0) then
          call cairo_set_line_width(cr, 4._c_double)
          r0 = radius * 0.8_c_double
          r1 = radius * 0.9_c_double
       else
          call cairo_set_line_width(cr, 2._c_double)
          r0 = radius * 0.8_c_double
          r1 = radius * 0.85_c_double
       end if
       th = real(i,c_double)*pi/30._c_double

       x0 = sin(th)*r0+xc
       x1 = sin(th)*r1+xc
       y0 = cos(th)*r0+yc
       y1 = cos(th)*r1+yc

       call cairo_move_to(cr, x0, y0)
       call cairo_line_to(cr, x1, y1)
       call cairo_stroke(cr)
    end do

    ! Seconds
    do i = 1, 60
       if (mod(i,15) == 0) then
          call cairo_set_line_width(cr, 2._c_double)
          r0 = radius * 0.2_c_double
          r1 = radius * 0.275_c_double
       else if (mod(i,5) == 0) then
          call cairo_set_line_width(cr, 1._c_double)
          r0 = radius * 0.225_c_double
          r1 = radius * 0.275_c_double
       else
          call cairo_set_line_width(cr, 1._c_double)
          r0 = radius * 0.225_c_double
          r1 = radius * 0.25_c_double
       end if
       th = real(i,c_double)*pi/30._c_double

       x0 = sin(th)*r0+xc
       x1 = sin(th)*r1+xc
       y0 = cos(th)*r0+ycs
       y1 = cos(th)*r1+ycs

       call cairo_move_to(cr, x0, y0)
       call cairo_line_to(cr, x1, y1)
       call cairo_stroke(cr)
    end do

    !  Date
    if (dat(5) >= 12) then
       call cairo_set_source_rgb(cr, 0._c_double, 0._c_double, 0._c_double)
    else
       call cairo_set_source_rgb(cr, 1._c_double, 1._c_double, 1._c_double)
    end if
    call cairo_select_font_face(cr, "sans-serif"//c_null_char, &
         & CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD)
    x0 = xc - 0.6_c_double*radius
    call cairo_set_line_width(cr, 1._c_double)
    call cairo_rectangle(cr, x0-2*scale_factor, yc+10*scale_factor, &
         & 42*scale_factor,-16*scale_factor)
    call cairo_fill_preserve(cr)
    if (dat(5) < 12) then
       call cairo_set_source_rgb(cr, 0._c_double, 0._c_double, 0._c_double)
    else
       call cairo_set_source_rgb(cr, 1._c_double, 1._c_double, 1._c_double)
    end if
    call cairo_stroke(cr)
    call cairo_set_font_size (cr, 12._c_double*scale_factor)
    write(sdate,"(I2.2,a1)") dat(3), char(0)
    call cairo_move_to(cr, x0,yc+6*scale_factor)
    call cairo_show_text(cr, sdate)
    call cairo_set_font_size (cr, 9*scale_factor)
    call cairo_show_text(cr, ' '//mnames(dat(2)))

    ! Second hand
    ! Trail
    th = real(dat(7),c_double) * pi / 30._c_double - pi/2._c_double
    r0 = radius * 0.24_c_double
    do i = 1, 15
       call cairo_set_source_rgba(cr, 1._c_double, 0.1_c_double, &
            & 1._c_double, 1._c_double-real(i,c_double)/15._c_double)
       call cairo_new_path(cr)
       call cairo_move_to(cr, xc, ycs)
       call cairo_arc(cr, xc, ycs, r0, th-pi/30._c_double, th)
       call cairo_fill(cr)
       th = th-pi/30._c_double
    end do

    ! Hand
    call cairo_set_source_rgb(cr, .6_c_double, 0.1_c_double, &
         & .6_c_double)
    call cairo_set_line_width(cr, 2._c_double)

    th = real(dat(7),c_double) * pi / 30._c_double
    x1 = r0*sin(th) + xc
    x0 = xc
    y1 = -r0*cos(th) + ycs
    y0 = ycs

    call cairo_move_to(cr, x0, y0)
    call cairo_line_to(cr, x1, y1)
    call cairo_stroke(cr)

    ! Hour hand
    call cairo_set_source_rgb(cr, 0.1_c_double, 0.8_c_double, &
         & 1._c_double)
    call cairo_set_line_width(cr, 8._c_double)
    r0 = radius * 0.6_c_double
    th = (real(mod(dat(5),12),c_double) + &
         & real(dat(6),c_double)/60._c_double + &
         & real(dat(7), c_double)/3600._c_double) * pi / 6._c_double
    x1 = r0*sin(th) + xc
    x0 = -r0*sin(th)/10._c_double + xc
    y1 = -r0*cos(th) + yc
    y0 = r0*cos(th)/10._c_double + yc

    call cairo_move_to(cr, x0, y0)
    call cairo_line_to(cr, x1, y1)
    call cairo_stroke(cr)

    ! Minute hand
    call cairo_set_source_rgba(cr, 1.0_c_double, 1._c_double, &
         & 0.1_c_double, 0.9_c_double)
    call cairo_set_line_width(cr, 3._c_double)
    r0 = min(xc,yc) * 0.85_c_double

    th = (real(dat(6),c_double) + &
         & real(dat(7),c_double)/60._c_double) * pi / 30._c_double
    x1 = r0*sin(th) + xc
    x0 = -r0*sin(th)/10._c_double + xc
    y1 = -r0*cos(th) + yc
    y0 = r0*cos(th)/10._c_double + yc

    call cairo_move_to(cr, x0, y0)
    call cairo_line_to(cr, x1, y1)
    call cairo_stroke(cr)

    call hl_gtk_drawing_area_cairo_destroy(cr)
    call gtk_widget_queue_draw(area)
  end function show_time


  subroutine clock_resize(area, data) bind(c)
    type(c_ptr), value :: area, data

    type(gtkallocation), target:: alloc
    integer(c_int) :: irv

    call gtk_widget_get_allocation(area,c_loc(alloc))
    width = alloc%width
    height = alloc%height

    call hl_gtk_drawing_area_resize(area)

    t0(:) = 0
    irv = show_time(area)
  end subroutine clock_resize


  ! GTK 4 : key callback function ("key-pressed" signal):
  ! https://developer.gnome.org/gdk4/stable/gdk4-Keyboard-Handling.html
  function clock_key(controller, keyval, keycode, state, gdata) result(ret) bind(c)
    type(c_ptr), value, intent(in) :: controller, gdata
    integer(c_int), value, intent(in) :: keyval, keycode, state
    logical(c_bool) :: ret
    integer(c_int) :: key_q

    key_q = gdk_keyval_from_name("q"//c_null_char)
    ! CTRL+Q will close the program:
    if ((iand(state, GDK_CONTROL_MASK) /= 0).and.(keyval == key_q)) then
      call gtk_window_destroy(window)
    end if

    ret = .true.
  end function clock_key

  subroutine activate(app, gdata) bind(c)
    use, intrinsic :: iso_c_binding, only: c_ptr, c_funloc, c_null_char
    use gtk, only: gtk_application_window_new, gtk_window_set_title
    implicit none
    type(c_ptr), value, intent(in)  :: app, gdata
 
Download .txt
gitextract__o02a7ce/

├── .github/
│   └── ISSUE_TEMPLATE/
│       └── bug_report.md
├── .gitignore
├── CHANGELOG.md
├── CITATION.cff
├── CMakeLists.txt
├── INSTALL.md
├── LICENSE
├── LICENSE_EXCEPTION
├── README-high-level.md
├── README.md
├── VERSIONS
├── cmake/
│   ├── DefaultFlags.cmake
│   ├── README.md
│   └── cmake_uninstall.cmake.in
├── codemeta.json
├── examples/
│   ├── CMakeLists.txt
│   ├── README.md
│   ├── bazaar.f90
│   ├── cairo-basics-click.f90
│   ├── cairo-basics.f90
│   ├── cairo-tests.f90
│   ├── demo_sound.ogg
│   ├── gio_demo.f90
│   ├── gtkbuilder.cmb
│   ├── gtkbuilder.ui
│   ├── gtkbuilder2.f90
│   ├── gtkhello.f90
│   ├── gtkzero_gapp.f90
│   ├── hl_assistant.f90
│   ├── hl_cairo1.f90
│   ├── hl_cairo_clock.f90
│   ├── hl_cairo_viewer.f90
│   ├── hl_choosers.f90
│   ├── hl_combo.f90
│   ├── hl_containers.f90
│   ├── hl_dialog.f90
│   ├── hl_infobar.f90
│   ├── hl_list1.f90
│   ├── hl_list_n.f90
│   ├── hl_list_renderers.f90
│   ├── hl_pbar.f90
│   ├── hl_sliders.f90
│   ├── hl_sliders2.f90
│   ├── hl_textview.f90
│   ├── hl_tree.f90
│   ├── julia_pixbuf.f90
│   ├── list_demo.f90
│   ├── mandelbrot_pixbuf.f90
│   ├── mandelbrot_pixbuf_zoom.f90
│   ├── menubar.f90
│   ├── notebooks.f90
│   ├── pixbuf_without_gui.f90
│   ├── regex.f90
│   ├── tests.f90
│   └── tests_gtk_sup.f90
├── fpm.toml
├── logo/
│   └── README.md
├── plplot/
│   ├── CMakeLists.txt
│   ├── README.md
│   ├── hl_plplot17e.f90
│   ├── hl_plplot17e_gto.f90
│   ├── hl_plplot1e.f90
│   ├── hl_plplot30e.f90
│   ├── hl_plplot4e.f90
│   └── hl_plplot8e.f90
├── screenshots/
│   ├── README.md
│   ├── bazaar_about_box.tiff
│   ├── cairo-basics_MacOSX.tiff
│   └── julia_pixbuf.tiff
├── sketcher/
│   ├── CMakeLists.txt
│   ├── README.md
│   ├── data/
│   │   ├── apache2.0.lic
│   │   ├── bsd.lic
│   │   ├── freeware.lic
│   │   ├── gnu-gpl-v2.lic
│   │   ├── gnu-gpl-v3.lic
│   │   ├── gnu-lgpl-v2.1.lic
│   │   ├── gnu-lgpl-v2.lic
│   │   └── zlib.lic
│   ├── default.options
│   ├── example.glade
│   ├── gtkf-sketcher.f90
│   └── gtkf-sketcher.glade
├── src/
│   ├── CMakeLists.txt
│   ├── README.md
│   ├── alt_build_test.sh
│   ├── api_compatibility.f90
│   ├── build.sh
│   ├── cairo-auto.f90
│   ├── cfwrapper/
│   │   ├── README.md
│   │   ├── analyze.py
│   │   ├── cfwrapper.py
│   │   ├── cleaning.py
│   │   ├── enums.py
│   │   ├── errors.py
│   │   ├── fortran.py
│   │   ├── globals_const.py
│   │   ├── gtk-fortran-hash.pkl
│   │   ├── lib_versions.py
│   │   ├── run_tests.py
│   │   ├── scan_types_and_enums.py
│   │   └── stats.py
│   ├── extract_enums.pl
│   ├── extract_events.pl
│   ├── extract_hl_doc.py
│   ├── gdk-auto.f90
│   ├── gdk-pixbuf-auto.f90
│   ├── gdk-pixbuf-hl.f90
│   ├── gdkevents-auto.f90
│   ├── glib-auto.f90
│   ├── graphene-auto.f90
│   ├── gsk-auto.f90
│   ├── gtk-auto.in
│   ├── gtk-draw-hl.f90
│   ├── gtk-enumerators.lis
│   ├── gtk-fortran-index.csv
│   ├── gtk-fortran-modscan.man
│   ├── gtk-fortran.f90
│   ├── gtk-fortran.pc.in
│   ├── gtk-fortran_funptr.csv
│   ├── gtk-fortran_types.csv
│   ├── gtk-hl-assistant.f90
│   ├── gtk-hl-button.f90
│   ├── gtk-hl-chooser.f90
│   ├── gtk-hl-combobox.f90
│   ├── gtk-hl-container.f90
│   ├── gtk-hl-dialog.f90
│   ├── gtk-hl-entry.f90
│   ├── gtk-hl-infobar.f90
│   ├── gtk-hl-misc.f90
│   ├── gtk-hl-progress.f90
│   ├── gtk-hl-spin-slider.f90
│   ├── gtk-hl-tree.f90
│   ├── gtk-hl.f90
│   ├── gtk-sup.f90
│   ├── gtk.f90
│   ├── gtkenums-auto.in
│   ├── pango-auto.f90
│   ├── plplot_extra.f90
│   ├── screenshots.sh
│   ├── show_versions.sh
│   ├── test_extra.sh
│   ├── tools.py
│   ├── unix-print-auto.f90
│   ├── usemodules.pl
│   └── usemodules.py
└── tutorials/
    ├── README.md
    ├── my_first_gtk_app1.f90
    ├── my_first_gtk_app2.f90
    ├── my_first_gtk_app3.f90
    ├── my_first_gtk_app4.f90
    ├── my_first_gtk_app5.f90
    ├── my_first_gtk_app6.f90
    └── my_first_gtk_app7.f90
Download .txt
SYMBOL INDEX (42 symbols across 11 files)

FILE: src/cfwrapper/analyze.py
  function split_prototype (line 66) | def split_prototype(prototype):
  function analyze_prototypes (line 95) | def analyze_prototypes(index, module_name, f_file_name, f_file, preproce...
  function analyze_arguments (line 182) | def analyze_arguments(args, f_use, proto, c_dir, c_file_name, my_stats, ...
  function write_fortran_interface (line 251) | def write_fortran_interface(index, module_name, f_file_name, f_file,

FILE: src/cfwrapper/cleaning.py
  function clean_header_file (line 37) | def clean_header_file(c_file_name, whole_file, enums_file):
  function preprocess_prototypes (line 97) | def preprocess_prototypes(preprocessed_list, lines_list):

FILE: src/cfwrapper/enums.py
  function set_bit_field (line 39) | def set_bit_field(match):
  function translate_enums (line 45) | def translate_enums(c_file_name, enum_list):

FILE: src/cfwrapper/errors.py
  class Errors (line 31) | class Errors():
    method __init__ (line 36) | def __init__(self):
    method inc_nb_errors (line 41) | def inc_nb_errors(self):
    method inc_nb_type_errors (line 44) | def inc_nb_type_errors(self):
    method append_error (line 47) | def append_error(self, error):
    method new_error (line 50) | def new_error(self, direc, filename, message, proto, type_error):
    method sort (line 60) | def sort(self):

FILE: src/cfwrapper/fortran.py
  function iso_c_binding (line 42) | def iso_c_binding(declaration, isReturned):

FILE: src/cfwrapper/lib_versions.py
  class Version (line 38) | class Version():
    method __init__ (line 43) | def __init__(self, GTK_VERSION, GTK_FORTRAN_VERSION):
    method find_library (line 70) | def find_library(self, lib_name, psys):
    method library (line 104) | def library(self, tuple_packages):
    method string (line 117) | def string(self):
    method create_file (line 126) | def create_file(self):
    method update_json_file (line 141) | def update_json_file(self):
    method update_fpm_file (line 152) | def update_fpm_file(self):

FILE: src/cfwrapper/scan_types_and_enums.py
  class types_enums (line 36) | class types_enums():
    method __init__ (line 150) | def __init__(self, PATH_DICT):

FILE: src/cfwrapper/stats.py
  function hash_gtk_fortran (line 43) | def hash_gtk_fortran(PATH_DICT, GTKENUMS_FILE):
  class Statistics (line 75) | class Statistics():
    method __init__ (line 78) | def __init__(self):
    method inc_nb_lines (line 89) | def inc_nb_lines(self, n):
    method inc_nb_generated_interfaces (line 92) | def inc_nb_generated_interfaces(self, n):
    method inc_nb_deprecated_functions (line 95) | def inc_nb_deprecated_functions(self):
    method inc_nb_variadic (line 98) | def inc_nb_variadic(self):
    method inc_nb_files (line 101) | def inc_nb_files(self):
    method inc_nb_enumerators (line 104) | def inc_nb_enumerators(self, n):
    method inc_nb_win32_utf8 (line 107) | def inc_nb_win32_utf8(self):
    method append_type (line 110) | def append_type(self, iso_c):
    method inc_nb_funptr_types (line 113) | def inc_nb_funptr_types(self, n):
    method print (line 116) | def print(self, T0, versions, PATH_DICT, GTKENUMS_FILE, my_errors):

FILE: src/extract_hl_doc.py
  function write_in_adequate_file (line 38) | def write_in_adequate_file(source_file_name, string):

FILE: src/tools.py
  function multiline (line 36) | def multiline(line, max_length):

FILE: src/usemodules.py
  function multiline (line 37) | def multiline(line, max_length):
Condensed preview — 154 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (7,952K chars).
[
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "chars": 654,
    "preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: Bug\nassignees: vmagnin\n\n---\n\n**Describe"
  },
  {
    "path": ".gitignore",
    "chars": 109,
    "preview": "*.out\n*.mod\n*.o\n*~\n*.bak\n*.backup\n*.old\n*.directory\n*__pycache__*\ncfwrapper-errors.csv\nusemodules.txt\nbuild/\n"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 25581,
    "preview": "# Changelog\nAll notable changes to the gtk-fortran project are documented in this file. The format is based on [Keep a C"
  },
  {
    "path": "CITATION.cff",
    "chars": 2719,
    "preview": "# This CITATION.cff file was generated with cffinit.\n# Visit https://bit.ly/cffinit to generate yours today!\n\ncff-versio"
  },
  {
    "path": "CMakeLists.txt",
    "chars": 11236,
    "preview": "# This file is part of gtk-fortran, a GTK / Fortran interface library.\n# Copyright (C) 2011 The gtk-fortran team\n#\n# Thi"
  },
  {
    "path": "INSTALL.md",
    "chars": 4328,
    "preview": "Last update: 2025-03-07\n\nDependencies\n================================\n\nIf you want to use gtk-fortran as a fpm dependen"
  },
  {
    "path": "LICENSE",
    "chars": 35147,
    "preview": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free "
  },
  {
    "path": "LICENSE_EXCEPTION",
    "chars": 3324,
    "preview": "GCC RUNTIME LIBRARY EXCEPTION\n\nVersion 3.1, 31 March 2009\n\nCopyright (C) 2009 Free Software Foundation, Inc. <http://fsf"
  },
  {
    "path": "README-high-level.md",
    "chars": 2183,
    "preview": "# gtk-fortran -- High level interfaces\n\nThe high level interface for gtk-fortran is in the source file\ngtk-hl.f90. This "
  },
  {
    "path": "README.md",
    "chars": 1912,
    "preview": "# gtk-fortran\n\n**This branch is for GTK 4**\n\nThe gtk-fortran project aims to offer scientists programming in Fortran a c"
  },
  {
    "path": "VERSIONS",
    "chars": 55,
    "preview": "gtk-fortran;4.9.0\r\nGTK;4.20.2\r\nGLib;2.86.1\r\nFedora;43\r\n"
  },
  {
    "path": "cmake/DefaultFlags.cmake",
    "chars": 3288,
    "preview": "# Copyright (C) 2011\n# Free Software Foundation, Inc.\n#\n# This file is part of the gtk-fortran GTK Fortran Interface lib"
  },
  {
    "path": "cmake/README.md",
    "chars": 373,
    "preview": "# CMake additional modules\n\nThis directory contains the modules to be loaded by `include()` or `find_package()` before c"
  },
  {
    "path": "cmake/cmake_uninstall.cmake.in",
    "chars": 1003,
    "preview": "# Source:\n# https://gitlab.kitware.com/cmake/community/-/wikis/FAQ#can-i-do-make-uninstall-with-cmake\n\nif(NOT EXISTS \"@C"
  },
  {
    "path": "codemeta.json",
    "chars": 2175,
    "preview": "{\n  \"@context\": \"https://raw.githubusercontent.com/codemeta/codemeta/master/codemeta.jsonld\",\n  \"@type\": \"Code\",\n  \"appl"
  },
  {
    "path": "examples/CMakeLists.txt",
    "chars": 3554,
    "preview": "# This file is part of gtk-fortran, a GTK / Fortran interface library.\n# Copyright (C) 2011 The gtk-fortran team\n#\n# Thi"
  },
  {
    "path": "examples/README.md",
    "chars": 1918,
    "preview": "# Gtk-fortran Example Programs\n\nThis directory contains example programs for the GTK 4 version of gtk-fortran. They are "
  },
  {
    "path": "examples/bazaar.f90",
    "chars": 17948,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2011 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "examples/cairo-basics-click.f90",
    "chars": 8011,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2011 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "examples/cairo-basics.f90",
    "chars": 7390,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2011 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "examples/cairo-tests.f90",
    "chars": 12121,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2011 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "examples/gio_demo.f90",
    "chars": 2930,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2013 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "examples/gtkbuilder.cmb",
    "chars": 2620,
    "preview": "<?xml version='1.0' encoding='UTF-8' standalone='no'?>\n<!DOCTYPE cambalache-project SYSTEM \"cambalache-project.dtd\">\n<ca"
  },
  {
    "path": "examples/gtkbuilder.ui",
    "chars": 2404,
    "preview": "<?xml version='1.0' encoding='UTF-8'?>\n<!-- Created with Cambalache 0.10.2 -->\n<interface>\n  <!-- interface-name gtkbuil"
  },
  {
    "path": "examples/gtkbuilder2.f90",
    "chars": 3168,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2011 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "examples/gtkhello.f90",
    "chars": 7638,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2020 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "examples/gtkzero_gapp.f90",
    "chars": 4354,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2020 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "examples/hl_assistant.f90",
    "chars": 6927,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2012 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "examples/hl_cairo1.f90",
    "chars": 10401,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2011 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "examples/hl_cairo_clock.f90",
    "chars": 11678,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2011 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "examples/hl_cairo_viewer.f90",
    "chars": 10682,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2013 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "examples/hl_choosers.f90",
    "chars": 8054,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2011 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "examples/hl_combo.f90",
    "chars": 3953,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2011 The gtk-fortran team\n\n! This"
  },
  {
    "path": "examples/hl_containers.f90",
    "chars": 4138,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2011 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "examples/hl_dialog.f90",
    "chars": 4249,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2011 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "examples/hl_infobar.f90",
    "chars": 6345,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2012 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "examples/hl_list1.f90",
    "chars": 8929,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2011 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "examples/hl_list_n.f90",
    "chars": 9762,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2011 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "examples/hl_list_renderers.f90",
    "chars": 14675,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2011 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "examples/hl_pbar.f90",
    "chars": 3831,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2011 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "examples/hl_sliders.f90",
    "chars": 5507,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2011 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "examples/hl_sliders2.f90",
    "chars": 5681,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2011 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "examples/hl_textview.f90",
    "chars": 8576,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2011 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "examples/hl_tree.f90",
    "chars": 8489,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2011 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "examples/julia_pixbuf.f90",
    "chars": 23031,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2011 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "examples/list_demo.f90",
    "chars": 6958,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2011 The gtk-fortran team\n!\n! A t"
  },
  {
    "path": "examples/mandelbrot_pixbuf.f90",
    "chars": 9291,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2011 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "examples/mandelbrot_pixbuf_zoom.f90",
    "chars": 16594,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2011 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "examples/menubar.f90",
    "chars": 9430,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2021 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "examples/notebooks.f90",
    "chars": 14290,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2011 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "examples/pixbuf_without_gui.f90",
    "chars": 4428,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2020 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "examples/regex.f90",
    "chars": 3784,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2021 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "examples/tests.f90",
    "chars": 19377,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2011 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "examples/tests_gtk_sup.f90",
    "chars": 6359,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2022 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "fpm.toml",
    "chars": 1091,
    "preview": "name = \"gtk-fortran\"\ndescription = \"With this file gtk-fortran can be used as a fpm dependency. But if you want a full b"
  },
  {
    "path": "logo/README.md",
    "chars": 763,
    "preview": "# gtk-fortran logo\n\n## Contains\nIn this directory, you will find:\n\n- `gtk-fortran-logo.svg`: the logo created with Inksc"
  },
  {
    "path": "plplot/CMakeLists.txt",
    "chars": 4054,
    "preview": "# This file is part of gtk-fortran, a GTK / Fortran interface library.\n# Copyright (C) 2012 The gtk-fortran team\n#\n# Thi"
  },
  {
    "path": "plplot/README.md",
    "chars": 4682,
    "preview": "# gtk-fortran & PLplot\n\nIn this directory there are a few examples of using the [PLplot library](http://plplot.sourcefor"
  },
  {
    "path": "plplot/hl_plplot17e.f90",
    "chars": 8292,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2012 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "plplot/hl_plplot17e_gto.f90",
    "chars": 8105,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2012 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "plplot/hl_plplot1e.f90",
    "chars": 10188,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2012 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "plplot/hl_plplot30e.f90",
    "chars": 8349,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2012 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "plplot/hl_plplot4e.f90",
    "chars": 10501,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2012 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "plplot/hl_plplot8e.f90",
    "chars": 15166,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2012 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "screenshots/README.md",
    "chars": 139,
    "preview": "# Examples screenshots\n\nIn this directory, you will find screenshots of the gtk-fortran examples, obtained with various "
  },
  {
    "path": "sketcher/CMakeLists.txt",
    "chars": 2554,
    "preview": "# This file is part of gtk-fortran, a GTK / Fortran interface library.\n# Copyright (C) 2011 The gtk-fortran team\n#\n# Thi"
  },
  {
    "path": "sketcher/README.md",
    "chars": 493,
    "preview": "# gtkf-sketcher\n\nA gtk-fortran Code Sketcher using UI XML definitions. It will automatically generate gtk-fortran code t"
  },
  {
    "path": "sketcher/data/apache2.0.lic",
    "chars": 542,
    "preview": "Apache License v2.0\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in "
  },
  {
    "path": "sketcher/data/bsd.lic",
    "chars": 1436,
    "preview": "BSD License\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that"
  },
  {
    "path": "sketcher/data/freeware.lic",
    "chars": 363,
    "preview": "Freeware\nThis program is FREEWARE. The author takes no responsibility for any\r\ndamage or loss of data that may occur by "
  },
  {
    "path": "sketcher/data/gnu-gpl-v2.lic",
    "chars": 722,
    "preview": "GNU General Public License v2\nThis program is free software; you can redistribute it and/or modify\r\nit under the terms o"
  },
  {
    "path": "sketcher/data/gnu-gpl-v3.lic",
    "chars": 653,
    "preview": "GNU General Public License v3\nThis program is free software: you can redistribute it and/or modify it under\r\nthe terms o"
  },
  {
    "path": "sketcher/data/gnu-lgpl-v2.1.lic",
    "chars": 739,
    "preview": "GNU Lesser General Public License v2.1\nThis program is free software; you can redistribute it and/or\nmodify it under the"
  },
  {
    "path": "sketcher/data/gnu-lgpl-v2.lic",
    "chars": 740,
    "preview": "GNU Library General Public License v2\nThis library is free software; you can redistribute it and/or\nmodify it under the "
  },
  {
    "path": "sketcher/data/zlib.lic",
    "chars": 832,
    "preview": "Zlib License\nThis software is provided 'as-is', without any express or implied\nwarranty.  In no event will the authors b"
  },
  {
    "path": "sketcher/default.options",
    "chars": 12,
    "preview": "TTFTTTTF\n 4\n"
  },
  {
    "path": "sketcher/example.glade",
    "chars": 1448,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<interface>\n  <requires lib=\"gtk\" version=\"4.0\"/>\n  <object class=\"GtkWindow\" id="
  },
  {
    "path": "sketcher/gtkf-sketcher.f90",
    "chars": 36587,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2011 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "sketcher/gtkf-sketcher.glade",
    "chars": 13300,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<interface>\n  <requires lib=\"gtk\" version=\"4.0\"/>\n  <object class=\"GtkTextBuffer\""
  },
  {
    "path": "src/CMakeLists.txt",
    "chars": 7777,
    "preview": "# This file is part of gtk-fortran, a GTK / Fortran interface library.\n# Copyright (C) 2011 The gtk-fortran team\n#\n# Thi"
  },
  {
    "path": "src/README.md",
    "chars": 3845,
    "preview": "# gtk-fortran source files\n\nIn the following filenames, the ? character is the GTK major version.\n\n## gtk-fortran core\n\n"
  },
  {
    "path": "src/alt_build_test.sh",
    "chars": 3999,
    "preview": "#! /bin/sh\n# This file is part of gtk-fortran, a GTK / Fortran interface library.\n# Copyright (C) 2011 The gtk-fortran t"
  },
  {
    "path": "src/api_compatibility.f90",
    "chars": 580,
    "preview": "! This gtk_os_dependent module is present only for API compatibility,\n! as the mswindowsonly-auto.f90 and unixonly-auto."
  },
  {
    "path": "src/build.sh",
    "chars": 2133,
    "preview": "#!/bin/sh\n# This file is part of gtk-fortran, a GTK / Fortran interface library.\n# Copyright (C) 2016 The gtk-fortran te"
  },
  {
    "path": "src/cairo-auto.f90",
    "chars": 142132,
    "preview": "! Do not modify this file automatically generated by cfwrapper.py using:\n! gtk-fortran 4.9.0, GTK 4.20.2, GLib 2.86.1, F"
  },
  {
    "path": "src/cfwrapper/README.md",
    "chars": 1222,
    "preview": "# cfwrapper source files\n\n- `cfwrapper/cfwrapper.py`: this is the precious heart of gtk-fortran. Developers use it to au"
  },
  {
    "path": "src/cfwrapper/analyze.py",
    "chars": 12619,
    "preview": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\n# This file is part of gtk-fortran, a GTK / Fortran interface library.\n#"
  },
  {
    "path": "src/cfwrapper/cfwrapper.py",
    "chars": 12758,
    "preview": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\n# This file is part of gtk-fortran, a GTK / Fortran interface library.\n#"
  },
  {
    "path": "src/cfwrapper/cleaning.py",
    "chars": 5152,
    "preview": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\n# This file is part of gtk-fortran, a GTK / Fortran interface library.\n#"
  },
  {
    "path": "src/cfwrapper/enums.py",
    "chars": 4985,
    "preview": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\n# This file is part of gtk-fortran, a GTK / Fortran interface library.\n#"
  },
  {
    "path": "src/cfwrapper/errors.py",
    "chars": 1986,
    "preview": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\n# This file is part of gtk-fortran, a GTK / Fortran interface library.\n#"
  },
  {
    "path": "src/cfwrapper/fortran.py",
    "chars": 4610,
    "preview": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\n# This file is part of gtk-fortran, a GTK / Fortran interface library.\n#"
  },
  {
    "path": "src/cfwrapper/globals_const.py",
    "chars": 1382,
    "preview": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\n# This file is part of gtk-fortran, a GTK / Fortran interface library.\n#"
  },
  {
    "path": "src/cfwrapper/lib_versions.py",
    "chars": 6818,
    "preview": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\n# This file is part of gtk-fortran, a GTK / Fortran interface library.\n#"
  },
  {
    "path": "src/cfwrapper/run_tests.py",
    "chars": 2548,
    "preview": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\n# This file is part of gtk-fortran, a GTK / Fortran interface library.\n#"
  },
  {
    "path": "src/cfwrapper/scan_types_and_enums.py",
    "chars": 9478,
    "preview": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\n# This file is part of gtk-fortran, a GTK / Fortran interface library.\n#"
  },
  {
    "path": "src/cfwrapper/stats.py",
    "chars": 5219,
    "preview": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\n# This file is part of gtk-fortran, a GTK / Fortran interface library.\n#"
  },
  {
    "path": "src/extract_enums.pl",
    "chars": 1703,
    "preview": "#!/usr/bin/env perl\n\n# This file is part of gtk-fortran, a GTK / Fortran interface library.\n# Copyright (C) 2012 The gtk"
  },
  {
    "path": "src/extract_events.pl",
    "chars": 5205,
    "preview": "#!/usr/bin/env perl\n\n# This file is part of gtk-fortran, a GTK / Fortran interface library.\n# Copyright (C) 2011 The gtk"
  },
  {
    "path": "src/extract_hl_doc.py",
    "chars": 7490,
    "preview": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\n# This file is part of gtk-fortran, a GTK / Fortran interface library.\n#"
  },
  {
    "path": "src/gdk-auto.f90",
    "chars": 234194,
    "preview": "! Do not modify this file automatically generated by cfwrapper.py using:\n! gtk-fortran 4.9.0, GTK 4.20.2, GLib 2.86.1, F"
  },
  {
    "path": "src/gdk-pixbuf-auto.f90",
    "chars": 51404,
    "preview": "! Do not modify this file automatically generated by cfwrapper.py using:\n! gtk-fortran 4.9.0, GTK 4.20.2, GLib 2.86.1, F"
  },
  {
    "path": "src/gdk-pixbuf-hl.f90",
    "chars": 36774,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2012 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "src/gdkevents-auto.f90",
    "chars": 796,
    "preview": "! Automatically generated by extract_events.pl on Thu Nov 20 09:30:58 2025 Z\n! Please do not modify (unless you really k"
  },
  {
    "path": "src/glib-auto.f90",
    "chars": 1514231,
    "preview": "! Do not modify this file automatically generated by cfwrapper.py using:\n! gtk-fortran 4.9.0, GTK 4.20.2, GLib 2.86.1, F"
  },
  {
    "path": "src/graphene-auto.f90",
    "chars": 125927,
    "preview": "! Do not modify this file automatically generated by cfwrapper.py using:\n! gtk-fortran 4.9.0, GTK 4.20.2, GLib 2.86.1, F"
  },
  {
    "path": "src/gsk-auto.f90",
    "chars": 111397,
    "preview": "! Do not modify this file automatically generated by cfwrapper.py using:\n! gtk-fortran 4.9.0, GTK 4.20.2, GLib 2.86.1, F"
  },
  {
    "path": "src/gtk-auto.in",
    "chars": 1213977,
    "preview": "!--------------------------------------------------\n! /usr/include/gtk-4.0/gtk/gtk.h\n!----------------------------------"
  },
  {
    "path": "src/gtk-draw-hl.f90",
    "chars": 29013,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2011 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "src/gtk-enumerators.lis",
    "chars": 66406,
    "preview": "cairo_ft_synthesize_bold\ncairo_ft_synthesize_oblique\ncairo_ps_level_2\ncairo_ps_level_3\ncairo_status_success\ncairo_status"
  },
  {
    "path": "src/gtk-fortran-index.csv",
    "chars": 2785593,
    "preview": "cairo;cairo_append_path;;cairo-auto.f90;/usr/include/cairo/cairo.h;\"void cairo_append_path (cairo_t *cr, const cairo_pat"
  },
  {
    "path": "src/gtk-fortran-modscan.man",
    "chars": 1684,
    "preview": ".TH \"GTK-FORTRAN-MODSCAN\" \"1\" \"16 August 2012\" \"Function scanner for gtk-fortran\"\n.SH NAME\ngtk-@GTK@-fortran-modscan \\- "
  },
  {
    "path": "src/gtk-fortran.f90",
    "chars": 3903,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2021 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "src/gtk-fortran.pc.in",
    "chars": 570,
    "preview": "# The .pc file is generated by the build system which uses the .pc.in file\n# in gtk-fortran/src and replaces the @.*@ st"
  },
  {
    "path": "src/gtk-fortran_funptr.csv",
    "chars": 5121,
    "preview": "C type\r\nGAsyncReadyCallback\r\nGBaseFinalizeFunc\r\nGBaseInitFunc\r\nGBindingTransformFunc\r\nGBoxedCopyFunc\r\nGBoxedFreeFunc\r\nGB"
  },
  {
    "path": "src/gtk-fortran_types.csv",
    "chars": 2801,
    "preview": "C type;Fortran type;Fortran KIND\r\nint;integer(c_int);c_int\r\ngint;integer(c_int);c_int\r\nguint;integer(c_int);c_int\r\nBool;"
  },
  {
    "path": "src/gtk-hl-assistant.f90",
    "chars": 12216,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2012 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "src/gtk-hl-button.f90",
    "chars": 8085,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2011 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "src/gtk-hl-chooser.f90",
    "chars": 20270,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2011 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "src/gtk-hl-combobox.f90",
    "chars": 8610,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2011 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "src/gtk-hl-container.f90",
    "chars": 26256,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2011 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "src/gtk-hl-dialog.f90",
    "chars": 18070,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2011 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "src/gtk-hl-entry.f90",
    "chars": 32628,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2012 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "src/gtk-hl-infobar.f90",
    "chars": 7497,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2012 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "src/gtk-hl-misc.f90",
    "chars": 2965,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2011 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "src/gtk-hl-progress.f90",
    "chars": 6188,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2011 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "src/gtk-hl-spin-slider.f90",
    "chars": 25608,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2011 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "src/gtk-hl-tree.f90",
    "chars": 129775,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2011 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "src/gtk-hl.f90",
    "chars": 1665,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2011 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "src/gtk-sup.f90",
    "chars": 26087,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2011 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "src/gtk.f90",
    "chars": 6583,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2011 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "src/gtkenums-auto.in",
    "chars": 169535,
    "preview": "! Do not modify this file automatically generated by cfwrapper.py using:\n! gtk-fortran 4.9.0, GTK 4.20.2, GLib 2.86.1, F"
  },
  {
    "path": "src/pango-auto.f90",
    "chars": 202920,
    "preview": "! Do not modify this file automatically generated by cfwrapper.py using:\n! gtk-fortran 4.9.0, GTK 4.20.2, GLib 2.86.1, F"
  },
  {
    "path": "src/plplot_extra.f90",
    "chars": 1879,
    "preview": "! This file is part of gtk-fortran, a GTK / Fortran interface library.\n! Copyright (C) 2012 The gtk-fortran team\n!\n! Thi"
  },
  {
    "path": "src/screenshots.sh",
    "chars": 1512,
    "preview": "#! /bin/sh\n# This file is part of gtk-fortran, a GTK / Fortran interface library.\n# Copyright (C) 2011 The gtk-fortran t"
  },
  {
    "path": "src/show_versions.sh",
    "chars": 2776,
    "preview": "#! /bin/sh\n# This file is part of gtk-fortran, a GTK / Fortran interface library.\n# Copyright (C) 2019 The gtk-fortran t"
  },
  {
    "path": "src/test_extra.sh",
    "chars": 1963,
    "preview": "#!/bin/sh\n# This file is part of gtk-fortran, a GTK / Fortran interface library.\n# Copyright (C) 2016 The gtk-fortran te"
  },
  {
    "path": "src/tools.py",
    "chars": 2210,
    "preview": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\n# This file is part of gtk-fortran, a GTK / Fortran interface library.\n#"
  },
  {
    "path": "src/unix-print-auto.f90",
    "chars": 25880,
    "preview": "! Do not modify this file automatically generated by cfwrapper.py using:\n! gtk-fortran 4.9.0, GTK 4.20.2, GLib 2.86.1, F"
  },
  {
    "path": "src/usemodules.pl",
    "chars": 10336,
    "preview": "#!/usr/bin/env perl\n\n# This file is part of gtk-fortran, a GTK / Fortran interface library.\n# Copyright (C) 2012 The gtk"
  },
  {
    "path": "src/usemodules.py",
    "chars": 6448,
    "preview": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\n# This file is part of gtk-fortran, a GTK / Fortran interface library.\n#"
  },
  {
    "path": "tutorials/README.md",
    "chars": 206,
    "preview": "# Tutorials programs\n\nThis directory contains the different stages of the program described in the wiki tutorial [My fir"
  },
  {
    "path": "tutorials/my_first_gtk_app1.f90",
    "chars": 321,
    "preview": "! $ gfortran -Wall -Wextra -std=f2008 -pedantic -g my_first_gtk_app1.f90 $(pkg-config --cflags --libs gtk-4-fortran)\n\nmo"
  },
  {
    "path": "tutorials/my_first_gtk_app2.f90",
    "chars": 665,
    "preview": "! $ gfortran -Wall -Wextra -std=f2008 -pedantic -g my_first_gtk_app2.f90 $(pkg-config --cflags --libs gtk-4-fortran)\n\nmo"
  },
  {
    "path": "tutorials/my_first_gtk_app3.f90",
    "chars": 1163,
    "preview": "! $ gfortran -Wall -Wextra -std=f2008 -pedantic -g my_first_gtk_app3.f90 $(pkg-config --cflags --libs gtk-4-fortran)\n\nmo"
  },
  {
    "path": "tutorials/my_first_gtk_app4.f90",
    "chars": 1820,
    "preview": "! $ gfortran -Wall -Wextra -std=f2008 -pedantic -g my_first_gtk_app4.f90 $(pkg-config --cflags --libs gtk-4-fortran)\n\nmo"
  },
  {
    "path": "tutorials/my_first_gtk_app5.f90",
    "chars": 2722,
    "preview": "! $ gfortran -Wall -Wextra -std=f2008 -pedantic -g my_first_gtk_app5.f90 $(pkg-config --cflags --libs gtk-4-fortran)\n\nmo"
  },
  {
    "path": "tutorials/my_first_gtk_app6.f90",
    "chars": 4304,
    "preview": "! $ gfortran -Wall -Wextra -std=f2008 -pedantic -g my_first_gtk_app6.f90 $(pkg-config --cflags --libs gtk-4-fortran)\n\nmo"
  },
  {
    "path": "tutorials/my_first_gtk_app7.f90",
    "chars": 4812,
    "preview": "! $ gfortran -Wall -Wextra -std=f2008 -pedantic -g my_first_gtk_app7.f90 $(pkg-config --cflags --libs gtk-4-fortran)\n\nmo"
  }
]

// ... and 5 more files (download for full content)

About this extraction

This page contains the full source code of the vmagnin/gtk-fortran GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 154 files (7.4 MB), approximately 1.9M tokens, and a symbol index with 42 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!